• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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