| 1 | //! Internal interface for communicating between a `proc_macro` client |
| 2 | //! (a proc macro crate) and a `proc_macro` server (a compiler front-end). |
| 3 | //! |
| 4 | //! Serialization (with C ABI buffers) and unique integer handles are employed |
| 5 | //! to allow safely interfacing between two copies of `proc_macro` built |
| 6 | //! (from the same source) by different compilers with potentially mismatching |
| 7 | //! Rust ABIs (e.g., stage0/bin/rustc vs stage1/bin/rustc during bootstrap). |
| 8 | |
| 9 | #![deny (unsafe_code)] |
| 10 | // proc_macros anyway don't work on wasm hosts so while both sides of this bridge can |
| 11 | // be built with different versions of rustc, the wasm ABI changes don't really matter. |
| 12 | #![allow (wasm_c_abi)] |
| 13 | |
| 14 | use std::hash::Hash; |
| 15 | use std::ops::{Bound, Range}; |
| 16 | use std::sync::Once; |
| 17 | use std::{fmt, marker, mem, panic, thread}; |
| 18 | |
| 19 | use crate::{Delimiter, Level, Spacing}; |
| 20 | |
| 21 | /// Higher-order macro describing the server RPC API, allowing automatic |
| 22 | /// generation of type-safe Rust APIs, both client-side and server-side. |
| 23 | /// |
| 24 | /// `with_api!(MySelf, my_self, my_macro)` expands to: |
| 25 | /// ```rust,ignore (pseudo-code) |
| 26 | /// my_macro! { |
| 27 | /// // ... |
| 28 | /// Literal { |
| 29 | /// // ... |
| 30 | /// fn character(ch: char) -> MySelf::Literal; |
| 31 | /// // ... |
| 32 | /// fn span(my_self: &MySelf::Literal) -> MySelf::Span; |
| 33 | /// fn set_span(my_self: &mut MySelf::Literal, span: MySelf::Span); |
| 34 | /// }, |
| 35 | /// // ... |
| 36 | /// } |
| 37 | /// ``` |
| 38 | /// |
| 39 | /// The first two arguments serve to customize the arguments names |
| 40 | /// and argument/return types, to enable several different usecases: |
| 41 | /// |
| 42 | /// If `my_self` is just `self`, then each `fn` signature can be used |
| 43 | /// as-is for a method. If it's anything else (`self_` in practice), |
| 44 | /// then the signatures don't have a special `self` argument, and |
| 45 | /// can, therefore, have a different one introduced. |
| 46 | /// |
| 47 | /// If `MySelf` is just `Self`, then the types are only valid inside |
| 48 | /// a trait or a trait impl, where the trait has associated types |
| 49 | /// for each of the API types. If non-associated types are desired, |
| 50 | /// a module name (`self` in practice) can be used instead of `Self`. |
| 51 | macro_rules! with_api { |
| 52 | ($S:ident, $self:ident, $m:ident) => { |
| 53 | $m! { |
| 54 | FreeFunctions { |
| 55 | fn drop($self: $S::FreeFunctions); |
| 56 | fn injected_env_var(var: &str) -> Option<String>; |
| 57 | fn track_env_var(var: &str, value: Option<&str>); |
| 58 | fn track_path(path: &str); |
| 59 | fn literal_from_str(s: &str) -> Result<Literal<$S::Span, $S::Symbol>, ()>; |
| 60 | fn emit_diagnostic(diagnostic: Diagnostic<$S::Span>); |
| 61 | }, |
| 62 | TokenStream { |
| 63 | fn drop($self: $S::TokenStream); |
| 64 | fn clone($self: &$S::TokenStream) -> $S::TokenStream; |
| 65 | fn is_empty($self: &$S::TokenStream) -> bool; |
| 66 | fn expand_expr($self: &$S::TokenStream) -> Result<$S::TokenStream, ()>; |
| 67 | fn from_str(src: &str) -> $S::TokenStream; |
| 68 | fn to_string($self: &$S::TokenStream) -> String; |
| 69 | fn from_token_tree( |
| 70 | tree: TokenTree<$S::TokenStream, $S::Span, $S::Symbol>, |
| 71 | ) -> $S::TokenStream; |
| 72 | fn concat_trees( |
| 73 | base: Option<$S::TokenStream>, |
| 74 | trees: Vec<TokenTree<$S::TokenStream, $S::Span, $S::Symbol>>, |
| 75 | ) -> $S::TokenStream; |
| 76 | fn concat_streams( |
| 77 | base: Option<$S::TokenStream>, |
| 78 | streams: Vec<$S::TokenStream>, |
| 79 | ) -> $S::TokenStream; |
| 80 | fn into_trees( |
| 81 | $self: $S::TokenStream |
| 82 | ) -> Vec<TokenTree<$S::TokenStream, $S::Span, $S::Symbol>>; |
| 83 | }, |
| 84 | Span { |
| 85 | fn debug($self: $S::Span) -> String; |
| 86 | fn parent($self: $S::Span) -> Option<$S::Span>; |
| 87 | fn source($self: $S::Span) -> $S::Span; |
| 88 | fn byte_range($self: $S::Span) -> Range<usize>; |
| 89 | fn start($self: $S::Span) -> $S::Span; |
| 90 | fn end($self: $S::Span) -> $S::Span; |
| 91 | fn line($self: $S::Span) -> usize; |
| 92 | fn column($self: $S::Span) -> usize; |
| 93 | fn file($self: $S::Span) -> String; |
| 94 | fn local_file($self: $S::Span) -> Option<String>; |
| 95 | fn join($self: $S::Span, other: $S::Span) -> Option<$S::Span>; |
| 96 | fn subspan($self: $S::Span, start: Bound<usize>, end: Bound<usize>) -> Option<$S::Span>; |
| 97 | fn resolved_at($self: $S::Span, at: $S::Span) -> $S::Span; |
| 98 | fn source_text($self: $S::Span) -> Option<String>; |
| 99 | fn save_span($self: $S::Span) -> usize; |
| 100 | fn recover_proc_macro_span(id: usize) -> $S::Span; |
| 101 | }, |
| 102 | Symbol { |
| 103 | fn normalize_and_validate_ident(string: &str) -> Result<$S::Symbol, ()>; |
| 104 | }, |
| 105 | } |
| 106 | }; |
| 107 | } |
| 108 | |
| 109 | // Similar to `with_api`, but only lists the types requiring handles, and they |
| 110 | // are divided into the two storage categories. |
| 111 | macro_rules! with_api_handle_types { |
| 112 | ($m:ident) => { |
| 113 | $m! { |
| 114 | 'owned: |
| 115 | FreeFunctions, |
| 116 | TokenStream, |
| 117 | |
| 118 | 'interned: |
| 119 | Span, |
| 120 | // Symbol is handled manually |
| 121 | } |
| 122 | }; |
| 123 | } |
| 124 | |
| 125 | // FIXME(eddyb) this calls `encode` for each argument, but in reverse, |
| 126 | // to match the ordering in `reverse_decode`. |
| 127 | macro_rules! reverse_encode { |
| 128 | ($writer:ident;) => {}; |
| 129 | ($writer:ident; $first:ident $(, $rest:ident)*) => { |
| 130 | reverse_encode!($writer; $($rest),*); |
| 131 | $first.encode(&mut $writer, &mut ()); |
| 132 | } |
| 133 | } |
| 134 | |
| 135 | // FIXME(eddyb) this calls `decode` for each argument, but in reverse, |
| 136 | // to avoid borrow conflicts from borrows started by `&mut` arguments. |
| 137 | macro_rules! reverse_decode { |
| 138 | ($reader:ident, $s:ident;) => {}; |
| 139 | ($reader:ident, $s:ident; $first:ident: $first_ty:ty $(, $rest:ident: $rest_ty:ty)*) => { |
| 140 | reverse_decode!($reader, $s; $($rest: $rest_ty),*); |
| 141 | let $first = <$first_ty>::decode(&mut $reader, $s); |
| 142 | } |
| 143 | } |
| 144 | |
| 145 | #[allow (unsafe_code)] |
| 146 | mod arena; |
| 147 | #[allow (unsafe_code)] |
| 148 | mod buffer; |
| 149 | #[deny (unsafe_code)] |
| 150 | pub mod client; |
| 151 | #[allow (unsafe_code)] |
| 152 | mod closure; |
| 153 | #[forbid (unsafe_code)] |
| 154 | mod fxhash; |
| 155 | #[forbid (unsafe_code)] |
| 156 | mod handle; |
| 157 | #[macro_use ] |
| 158 | #[forbid (unsafe_code)] |
| 159 | mod rpc; |
| 160 | #[allow (unsafe_code)] |
| 161 | mod selfless_reify; |
| 162 | #[forbid (unsafe_code)] |
| 163 | pub mod server; |
| 164 | #[allow (unsafe_code)] |
| 165 | mod symbol; |
| 166 | |
| 167 | use buffer::Buffer; |
| 168 | pub use rpc::PanicMessage; |
| 169 | use rpc::{Decode, DecodeMut, Encode, Reader, Writer}; |
| 170 | |
| 171 | /// Configuration for establishing an active connection between a server and a |
| 172 | /// client. The server creates the bridge config (`run_server` in `server.rs`), |
| 173 | /// then passes it to the client through the function pointer in the `run` field |
| 174 | /// of `client::Client`. The client constructs a local `Bridge` from the config |
| 175 | /// in TLS during its execution (`Bridge::{enter, with}` in `client.rs`). |
| 176 | #[repr (C)] |
| 177 | pub struct BridgeConfig<'a> { |
| 178 | /// Buffer used to pass initial input to the client. |
| 179 | input: Buffer, |
| 180 | |
| 181 | /// Server-side function that the client uses to make requests. |
| 182 | dispatch: closure::Closure<'a, Buffer, Buffer>, |
| 183 | |
| 184 | /// If 'true', always invoke the default panic hook |
| 185 | force_show_panics: bool, |
| 186 | |
| 187 | // Prevent Send and Sync impls. `!Send`/`!Sync` is the usual way of doing |
| 188 | // this, but that requires unstable features. rust-analyzer uses this code |
| 189 | // and avoids unstable features. |
| 190 | _marker: marker::PhantomData<*mut ()>, |
| 191 | } |
| 192 | |
| 193 | #[forbid (unsafe_code)] |
| 194 | #[allow (non_camel_case_types)] |
| 195 | mod api_tags { |
| 196 | use super::rpc::{DecodeMut, Encode, Reader, Writer}; |
| 197 | |
| 198 | macro_rules! declare_tags { |
| 199 | ($($name:ident { |
| 200 | $(fn $method:ident($($arg:ident: $arg_ty:ty),* $(,)?) $(-> $ret_ty:ty)*;)* |
| 201 | }),* $(,)?) => { |
| 202 | $( |
| 203 | pub(super) enum $name { |
| 204 | $($method),* |
| 205 | } |
| 206 | rpc_encode_decode!(enum $name { $($method),* }); |
| 207 | )* |
| 208 | |
| 209 | pub(super) enum Method { |
| 210 | $($name($name)),* |
| 211 | } |
| 212 | rpc_encode_decode!(enum Method { $($name(m)),* }); |
| 213 | } |
| 214 | } |
| 215 | with_api!(self, self, declare_tags); |
| 216 | } |
| 217 | |
| 218 | /// Helper to wrap associated types to allow trait impl dispatch. |
| 219 | /// That is, normally a pair of impls for `T::Foo` and `T::Bar` |
| 220 | /// can overlap, but if the impls are, instead, on types like |
| 221 | /// `Marked<T::Foo, Foo>` and `Marked<T::Bar, Bar>`, they can't. |
| 222 | trait Mark { |
| 223 | type Unmarked; |
| 224 | fn mark(unmarked: Self::Unmarked) -> Self; |
| 225 | } |
| 226 | |
| 227 | /// Unwrap types wrapped by `Mark::mark` (see `Mark` for details). |
| 228 | trait Unmark { |
| 229 | type Unmarked; |
| 230 | fn unmark(self) -> Self::Unmarked; |
| 231 | } |
| 232 | |
| 233 | #[derive (Copy, Clone, PartialEq, Eq, Hash)] |
| 234 | struct Marked<T, M> { |
| 235 | value: T, |
| 236 | _marker: marker::PhantomData<M>, |
| 237 | } |
| 238 | |
| 239 | impl<T, M> Mark for Marked<T, M> { |
| 240 | type Unmarked = T; |
| 241 | fn mark(unmarked: Self::Unmarked) -> Self { |
| 242 | Marked { value: unmarked, _marker: marker::PhantomData } |
| 243 | } |
| 244 | } |
| 245 | impl<T, M> Unmark for Marked<T, M> { |
| 246 | type Unmarked = T; |
| 247 | fn unmark(self) -> Self::Unmarked { |
| 248 | self.value |
| 249 | } |
| 250 | } |
| 251 | impl<'a, T, M> Unmark for &'a Marked<T, M> { |
| 252 | type Unmarked = &'a T; |
| 253 | fn unmark(self) -> Self::Unmarked { |
| 254 | &self.value |
| 255 | } |
| 256 | } |
| 257 | impl<'a, T, M> Unmark for &'a mut Marked<T, M> { |
| 258 | type Unmarked = &'a mut T; |
| 259 | fn unmark(self) -> Self::Unmarked { |
| 260 | &mut self.value |
| 261 | } |
| 262 | } |
| 263 | |
| 264 | impl<T: Mark> Mark for Vec<T> { |
| 265 | type Unmarked = Vec<T::Unmarked>; |
| 266 | fn mark(unmarked: Self::Unmarked) -> Self { |
| 267 | // Should be a no-op due to std's in-place collect optimizations. |
| 268 | unmarked.into_iter().map(T::mark).collect() |
| 269 | } |
| 270 | } |
| 271 | impl<T: Unmark> Unmark for Vec<T> { |
| 272 | type Unmarked = Vec<T::Unmarked>; |
| 273 | fn unmark(self) -> Self::Unmarked { |
| 274 | // Should be a no-op due to std's in-place collect optimizations. |
| 275 | self.into_iter().map(T::unmark).collect() |
| 276 | } |
| 277 | } |
| 278 | |
| 279 | macro_rules! mark_noop { |
| 280 | ($($ty:ty),* $(,)?) => { |
| 281 | $( |
| 282 | impl Mark for $ty { |
| 283 | type Unmarked = Self; |
| 284 | fn mark(unmarked: Self::Unmarked) -> Self { |
| 285 | unmarked |
| 286 | } |
| 287 | } |
| 288 | impl Unmark for $ty { |
| 289 | type Unmarked = Self; |
| 290 | fn unmark(self) -> Self::Unmarked { |
| 291 | self |
| 292 | } |
| 293 | } |
| 294 | )* |
| 295 | } |
| 296 | } |
| 297 | mark_noop! { |
| 298 | (), |
| 299 | bool, |
| 300 | char, |
| 301 | &'_ [u8], |
| 302 | &'_ str, |
| 303 | String, |
| 304 | u8, |
| 305 | usize, |
| 306 | Delimiter, |
| 307 | LitKind, |
| 308 | Level, |
| 309 | Spacing, |
| 310 | } |
| 311 | |
| 312 | rpc_encode_decode!( |
| 313 | enum Delimiter { |
| 314 | Parenthesis, |
| 315 | Brace, |
| 316 | Bracket, |
| 317 | None, |
| 318 | } |
| 319 | ); |
| 320 | rpc_encode_decode!( |
| 321 | enum Level { |
| 322 | Error, |
| 323 | Warning, |
| 324 | Note, |
| 325 | Help, |
| 326 | } |
| 327 | ); |
| 328 | rpc_encode_decode!( |
| 329 | enum Spacing { |
| 330 | Alone, |
| 331 | Joint, |
| 332 | } |
| 333 | ); |
| 334 | |
| 335 | #[derive (Copy, Clone, Eq, PartialEq, Debug)] |
| 336 | pub enum LitKind { |
| 337 | Byte, |
| 338 | Char, |
| 339 | Integer, |
| 340 | Float, |
| 341 | Str, |
| 342 | StrRaw(u8), |
| 343 | ByteStr, |
| 344 | ByteStrRaw(u8), |
| 345 | CStr, |
| 346 | CStrRaw(u8), |
| 347 | // This should have an `ErrorGuaranteed`, except that type isn't available |
| 348 | // in this crate. (Imagine it is there.) Hence the `WithGuar` suffix. Must |
| 349 | // only be constructed in `LitKind::from_internal`, where an |
| 350 | // `ErrorGuaranteed` is available. |
| 351 | ErrWithGuar, |
| 352 | } |
| 353 | |
| 354 | rpc_encode_decode!( |
| 355 | enum LitKind { |
| 356 | Byte, |
| 357 | Char, |
| 358 | Integer, |
| 359 | Float, |
| 360 | Str, |
| 361 | StrRaw(n), |
| 362 | ByteStr, |
| 363 | ByteStrRaw(n), |
| 364 | CStr, |
| 365 | CStrRaw(n), |
| 366 | ErrWithGuar, |
| 367 | } |
| 368 | ); |
| 369 | |
| 370 | macro_rules! mark_compound { |
| 371 | (struct $name:ident <$($T:ident),+> { $($field:ident),* $(,)? }) => { |
| 372 | impl<$($T: Mark),+> Mark for $name <$($T),+> { |
| 373 | type Unmarked = $name <$($T::Unmarked),+>; |
| 374 | fn mark(unmarked: Self::Unmarked) -> Self { |
| 375 | $name { |
| 376 | $($field: Mark::mark(unmarked.$field)),* |
| 377 | } |
| 378 | } |
| 379 | } |
| 380 | |
| 381 | impl<$($T: Unmark),+> Unmark for $name <$($T),+> { |
| 382 | type Unmarked = $name <$($T::Unmarked),+>; |
| 383 | fn unmark(self) -> Self::Unmarked { |
| 384 | $name { |
| 385 | $($field: Unmark::unmark(self.$field)),* |
| 386 | } |
| 387 | } |
| 388 | } |
| 389 | }; |
| 390 | (enum $name:ident <$($T:ident),+> { $($variant:ident $(($field:ident))?),* $(,)? }) => { |
| 391 | impl<$($T: Mark),+> Mark for $name <$($T),+> { |
| 392 | type Unmarked = $name <$($T::Unmarked),+>; |
| 393 | fn mark(unmarked: Self::Unmarked) -> Self { |
| 394 | match unmarked { |
| 395 | $($name::$variant $(($field))? => { |
| 396 | $name::$variant $((Mark::mark($field)))? |
| 397 | })* |
| 398 | } |
| 399 | } |
| 400 | } |
| 401 | |
| 402 | impl<$($T: Unmark),+> Unmark for $name <$($T),+> { |
| 403 | type Unmarked = $name <$($T::Unmarked),+>; |
| 404 | fn unmark(self) -> Self::Unmarked { |
| 405 | match self { |
| 406 | $($name::$variant $(($field))? => { |
| 407 | $name::$variant $((Unmark::unmark($field)))? |
| 408 | })* |
| 409 | } |
| 410 | } |
| 411 | } |
| 412 | } |
| 413 | } |
| 414 | |
| 415 | macro_rules! compound_traits { |
| 416 | ($($t:tt)*) => { |
| 417 | rpc_encode_decode!($($t)*); |
| 418 | mark_compound!($($t)*); |
| 419 | }; |
| 420 | } |
| 421 | |
| 422 | compound_traits!( |
| 423 | enum Bound<T> { |
| 424 | Included(x), |
| 425 | Excluded(x), |
| 426 | Unbounded, |
| 427 | } |
| 428 | ); |
| 429 | |
| 430 | compound_traits!( |
| 431 | enum Option<T> { |
| 432 | Some(t), |
| 433 | None, |
| 434 | } |
| 435 | ); |
| 436 | |
| 437 | compound_traits!( |
| 438 | enum Result<T, E> { |
| 439 | Ok(t), |
| 440 | Err(e), |
| 441 | } |
| 442 | ); |
| 443 | |
| 444 | #[derive (Copy, Clone)] |
| 445 | pub struct DelimSpan<Span> { |
| 446 | pub open: Span, |
| 447 | pub close: Span, |
| 448 | pub entire: Span, |
| 449 | } |
| 450 | |
| 451 | impl<Span: Copy> DelimSpan<Span> { |
| 452 | pub fn from_single(span: Span) -> Self { |
| 453 | DelimSpan { open: span, close: span, entire: span } |
| 454 | } |
| 455 | } |
| 456 | |
| 457 | compound_traits!(struct DelimSpan<Span> { open, close, entire }); |
| 458 | |
| 459 | #[derive (Clone)] |
| 460 | pub struct Group<TokenStream, Span> { |
| 461 | pub delimiter: Delimiter, |
| 462 | pub stream: Option<TokenStream>, |
| 463 | pub span: DelimSpan<Span>, |
| 464 | } |
| 465 | |
| 466 | compound_traits!(struct Group<TokenStream, Span> { delimiter, stream, span }); |
| 467 | |
| 468 | #[derive (Clone)] |
| 469 | pub struct Punct<Span> { |
| 470 | pub ch: u8, |
| 471 | pub joint: bool, |
| 472 | pub span: Span, |
| 473 | } |
| 474 | |
| 475 | compound_traits!(struct Punct<Span> { ch, joint, span }); |
| 476 | |
| 477 | #[derive (Copy, Clone, Eq, PartialEq)] |
| 478 | pub struct Ident<Span, Symbol> { |
| 479 | pub sym: Symbol, |
| 480 | pub is_raw: bool, |
| 481 | pub span: Span, |
| 482 | } |
| 483 | |
| 484 | compound_traits!(struct Ident<Span, Symbol> { sym, is_raw, span }); |
| 485 | |
| 486 | #[derive (Clone, Eq, PartialEq)] |
| 487 | pub struct Literal<Span, Symbol> { |
| 488 | pub kind: LitKind, |
| 489 | pub symbol: Symbol, |
| 490 | pub suffix: Option<Symbol>, |
| 491 | pub span: Span, |
| 492 | } |
| 493 | |
| 494 | compound_traits!(struct Literal<Sp, Sy> { kind, symbol, suffix, span }); |
| 495 | |
| 496 | #[derive (Clone)] |
| 497 | pub enum TokenTree<TokenStream, Span, Symbol> { |
| 498 | Group(Group<TokenStream, Span>), |
| 499 | Punct(Punct<Span>), |
| 500 | Ident(Ident<Span, Symbol>), |
| 501 | Literal(Literal<Span, Symbol>), |
| 502 | } |
| 503 | |
| 504 | compound_traits!( |
| 505 | enum TokenTree<TokenStream, Span, Symbol> { |
| 506 | Group(tt), |
| 507 | Punct(tt), |
| 508 | Ident(tt), |
| 509 | Literal(tt), |
| 510 | } |
| 511 | ); |
| 512 | |
| 513 | #[derive (Clone, Debug)] |
| 514 | pub struct Diagnostic<Span> { |
| 515 | pub level: Level, |
| 516 | pub message: String, |
| 517 | pub spans: Vec<Span>, |
| 518 | pub children: Vec<Diagnostic<Span>>, |
| 519 | } |
| 520 | |
| 521 | compound_traits!( |
| 522 | struct Diagnostic<Span> { level, message, spans, children } |
| 523 | ); |
| 524 | |
| 525 | /// Globals provided alongside the initial inputs for a macro expansion. |
| 526 | /// Provides values such as spans which are used frequently to avoid RPC. |
| 527 | #[derive (Clone)] |
| 528 | pub struct ExpnGlobals<Span> { |
| 529 | pub def_site: Span, |
| 530 | pub call_site: Span, |
| 531 | pub mixed_site: Span, |
| 532 | } |
| 533 | |
| 534 | compound_traits!( |
| 535 | struct ExpnGlobals<Span> { def_site, call_site, mixed_site } |
| 536 | ); |
| 537 | |
| 538 | compound_traits!( |
| 539 | struct Range<T> { start, end } |
| 540 | ); |
| 541 | |