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