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