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