proc_macro/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// 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
14use std::hash::Hash;
15use std::ops::{Bound, Range};
16use std::sync::Once;
17use std::{fmt, marker, mem, panic, thread};
18
19use 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`.
51macro_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.
111macro_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`.
127macro_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.
137macro_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)]
146mod arena;
147#[allow(unsafe_code)]
148mod buffer;
149#[deny(unsafe_code)]
150pub mod client;
151#[allow(unsafe_code)]
152mod closure;
153#[forbid(unsafe_code)]
154mod fxhash;
155#[forbid(unsafe_code)]
156mod handle;
157#[macro_use]
158#[forbid(unsafe_code)]
159mod rpc;
160#[allow(unsafe_code)]
161mod selfless_reify;
162#[forbid(unsafe_code)]
163pub mod server;
164#[allow(unsafe_code)]
165mod symbol;
166
167use buffer::Buffer;
168pub use rpc::PanicMessage;
169use 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)]
177pub 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)]
195mod 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.
222trait Mark {
223    type Unmarked;
224    fn mark(unmarked: Self::Unmarked) -> Self;
225}
226
227/// Unwrap types wrapped by `Mark::mark` (see `Mark` for details).
228trait Unmark {
229    type Unmarked;
230    fn unmark(self) -> Self::Unmarked;
231}
232
233#[derive(Copy, Clone, PartialEq, Eq, Hash)]
234struct Marked<T, M> {
235    value: T,
236    _marker: marker::PhantomData<M>,
237}
238
239impl<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}
245impl<T, M> Unmark for Marked<T, M> {
246    type Unmarked = T;
247    fn unmark(self) -> Self::Unmarked {
248        self.value
249    }
250}
251impl<'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}
257impl<'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
264impl<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}
271impl<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
279macro_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}
297mark_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
312rpc_encode_decode!(
313    enum Delimiter {
314        Parenthesis,
315        Brace,
316        Bracket,
317        None,
318    }
319);
320rpc_encode_decode!(
321    enum Level {
322        Error,
323        Warning,
324        Note,
325        Help,
326    }
327);
328rpc_encode_decode!(
329    enum Spacing {
330        Alone,
331        Joint,
332    }
333);
334
335#[derive(Copy, Clone, Eq, PartialEq, Debug)]
336pub 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
354rpc_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
370macro_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
415macro_rules! compound_traits {
416    ($($t:tt)*) => {
417        rpc_encode_decode!($($t)*);
418        mark_compound!($($t)*);
419    };
420}
421
422compound_traits!(
423    enum Bound<T> {
424        Included(x),
425        Excluded(x),
426        Unbounded,
427    }
428);
429
430compound_traits!(
431    enum Option<T> {
432        Some(t),
433        None,
434    }
435);
436
437compound_traits!(
438    enum Result<T, E> {
439        Ok(t),
440        Err(e),
441    }
442);
443
444#[derive(Copy, Clone)]
445pub struct DelimSpan<Span> {
446    pub open: Span,
447    pub close: Span,
448    pub entire: Span,
449}
450
451impl<Span: Copy> DelimSpan<Span> {
452    pub fn from_single(span: Span) -> Self {
453        DelimSpan { open: span, close: span, entire: span }
454    }
455}
456
457compound_traits!(struct DelimSpan<Span> { open, close, entire });
458
459#[derive(Clone)]
460pub struct Group<TokenStream, Span> {
461    pub delimiter: Delimiter,
462    pub stream: Option<TokenStream>,
463    pub span: DelimSpan<Span>,
464}
465
466compound_traits!(struct Group<TokenStream, Span> { delimiter, stream, span });
467
468#[derive(Clone)]
469pub struct Punct<Span> {
470    pub ch: u8,
471    pub joint: bool,
472    pub span: Span,
473}
474
475compound_traits!(struct Punct<Span> { ch, joint, span });
476
477#[derive(Copy, Clone, Eq, PartialEq)]
478pub struct Ident<Span, Symbol> {
479    pub sym: Symbol,
480    pub is_raw: bool,
481    pub span: Span,
482}
483
484compound_traits!(struct Ident<Span, Symbol> { sym, is_raw, span });
485
486#[derive(Clone, Eq, PartialEq)]
487pub struct Literal<Span, Symbol> {
488    pub kind: LitKind,
489    pub symbol: Symbol,
490    pub suffix: Option<Symbol>,
491    pub span: Span,
492}
493
494compound_traits!(struct Literal<Sp, Sy> { kind, symbol, suffix, span });
495
496#[derive(Clone)]
497pub 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
504compound_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)]
514pub struct Diagnostic<Span> {
515    pub level: Level,
516    pub message: String,
517    pub spans: Vec<Span>,
518    pub children: Vec<Diagnostic<Span>>,
519}
520
521compound_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)]
528pub struct ExpnGlobals<Span> {
529    pub def_site: Span,
530    pub call_site: Span,
531    pub mixed_site: Span,
532}
533
534compound_traits!(
535    struct ExpnGlobals<Span> { def_site, call_site, mixed_site }
536);
537
538compound_traits!(
539    struct Range<T> { start, end }
540);