1 //! Internal interface for communicating between a `proc_macro` client
2 //! (a proc macro crate) and a `proc_macro` server (a compiler front-end).
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).
11 use crate::{Delimiter, Level, LineColumn, Spacing}
;
18 use std
::sync
::atomic
::AtomicUsize
;
22 /// Higher-order macro describing the server RPC API, allowing automatic
23 /// generation of type-safe Rust APIs, both client-side and server-side.
25 /// `with_api!(MySelf, my_self, my_macro)` expands to:
26 /// ```rust,ignore (pseudo-code)
31 /// fn character(ch: char) -> MySelf::Literal;
33 /// fn span(my_self: &MySelf::Literal) -> MySelf::Span;
34 /// fn set_span(my_self: &mut MySelf::Literal, span: MySelf::Span);
40 /// The first two arguments serve to customize the arguments names
41 /// and argument/return types, to enable several different usecases:
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.
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
) => {
56 fn drop($
self: $S
::FreeFunctions
);
57 fn track_env_var(var
: &str, value
: Option
<&str>);
60 fn drop($
self: $S
::TokenStream
);
61 fn clone($
self: &$S
::TokenStream
) -> $S
::TokenStream
;
62 fn new() -> $S
::TokenStream
;
63 fn is_empty($
self: &$S
::TokenStream
) -> bool
;
64 fn from_str(src
: &str) -> $S
::TokenStream
;
65 fn to_string($
self: &$S
::TokenStream
) -> String
;
67 tree
: TokenTree
<$S
::Group
, $S
::Punct
, $S
::Ident
, $S
::Literal
>,
69 fn into_iter($
self: $S
::TokenStream
) -> $S
::TokenStreamIter
;
72 fn drop($
self: $S
::TokenStreamBuilder
);
73 fn new() -> $S
::TokenStreamBuilder
;
74 fn push($
self: &mut $S
::TokenStreamBuilder
, stream
: $S
::TokenStream
);
75 fn build($
self: $S
::TokenStreamBuilder
) -> $S
::TokenStream
;
78 fn drop($
self: $S
::TokenStreamIter
);
79 fn clone($
self: &$S
::TokenStreamIter
) -> $S
::TokenStreamIter
;
81 $
self: &mut $S
::TokenStreamIter
,
82 ) -> Option
<TokenTree
<$S
::Group
, $S
::Punct
, $S
::Ident
, $S
::Literal
>>;
85 fn drop($
self: $S
::Group
);
86 fn clone($
self: &$S
::Group
) -> $S
::Group
;
87 fn new(delimiter
: Delimiter
, stream
: $S
::TokenStream
) -> $S
::Group
;
88 fn delimiter($
self: &$S
::Group
) -> Delimiter
;
89 fn stream($
self: &$S
::Group
) -> $S
::TokenStream
;
90 fn span($
self: &$S
::Group
) -> $S
::Span
;
91 fn span_open($
self: &$S
::Group
) -> $S
::Span
;
92 fn span_close($
self: &$S
::Group
) -> $S
::Span
;
93 fn set_span($
self: &mut $S
::Group
, span
: $S
::Span
);
96 fn new(ch
: char, spacing
: Spacing
) -> $S
::Punct
;
97 fn as_char($
self: $S
::Punct
) -> char;
98 fn spacing($
self: $S
::Punct
) -> Spacing
;
99 fn span($
self: $S
::Punct
) -> $S
::Span
;
100 fn with_span($
self: $S
::Punct
, span
: $S
::Span
) -> $S
::Punct
;
103 fn new(string
: &str, span
: $S
::Span
, is_raw
: bool
) -> $S
::Ident
;
104 fn span($
self: $S
::Ident
) -> $S
::Span
;
105 fn with_span($
self: $S
::Ident
, span
: $S
::Span
) -> $S
::Ident
;
108 fn drop($
self: $S
::Literal
);
109 fn clone($
self: &$S
::Literal
) -> $S
::Literal
;
110 fn debug_kind($
self: &$S
::Literal
) -> String
;
111 fn symbol($
self: &$S
::Literal
) -> String
;
112 fn suffix($
self: &$S
::Literal
) -> Option
<String
>;
113 fn integer(n
: &str) -> $S
::Literal
;
114 fn typed_integer(n
: &str, kind
: &str) -> $S
::Literal
;
115 fn float(n
: &str) -> $S
::Literal
;
116 fn f32(n
: &str) -> $S
::Literal
;
117 fn f64(n
: &str) -> $S
::Literal
;
118 fn string(string
: &str) -> $S
::Literal
;
119 fn character(ch
: char) -> $S
::Literal
;
120 fn byte_string(bytes
: &[u8]) -> $S
::Literal
;
121 fn span($
self: &$S
::Literal
) -> $S
::Span
;
122 fn set_span($
self: &mut $S
::Literal
, span
: $S
::Span
);
127 ) -> Option
<$S
::Span
>;
130 fn drop($
self: $S
::SourceFile
);
131 fn clone($
self: &$S
::SourceFile
) -> $S
::SourceFile
;
132 fn eq($
self: &$S
::SourceFile
, other
: &$S
::SourceFile
) -> bool
;
133 fn path($
self: &$S
::SourceFile
) -> String
;
134 fn is_real($
self: &$S
::SourceFile
) -> bool
;
137 fn drop($
self: $S
::MultiSpan
);
138 fn new() -> $S
::MultiSpan
;
139 fn push($
self: &mut $S
::MultiSpan
, span
: $S
::Span
);
142 fn drop($
self: $S
::Diagnostic
);
143 fn new(level
: Level
, msg
: &str, span
: $S
::MultiSpan
) -> $S
::Diagnostic
;
145 $
self: &mut $S
::Diagnostic
,
150 fn emit($
self: $S
::Diagnostic
);
153 fn debug($
self: $S
::Span
) -> String
;
154 fn def_site() -> $S
::Span
;
155 fn call_site() -> $S
::Span
;
156 fn mixed_site() -> $S
::Span
;
157 fn source_file($
self: $S
::Span
) -> $S
::SourceFile
;
158 fn parent($
self: $S
::Span
) -> Option
<$S
::Span
>;
159 fn source($
self: $S
::Span
) -> $S
::Span
;
160 fn start($
self: $S
::Span
) -> LineColumn
;
161 fn end($
self: $S
::Span
) -> LineColumn
;
162 fn join($
self: $S
::Span
, other
: $S
::Span
) -> Option
<$S
::Span
>;
163 fn resolved_at($
self: $S
::Span
, at
: $S
::Span
) -> $S
::Span
;
164 fn source_text($
self: $S
::Span
) -> Option
<String
>;
170 // FIXME(eddyb) this calls `encode` for each argument, but in reverse,
171 // to avoid borrow conflicts from borrows started by `&mut` arguments.
172 macro_rules
! reverse_encode
{
173 ($writer
:ident
;) => {}
;
174 ($writer
:ident
; $first
:ident $
(, $rest
:ident
)*) => {
175 reverse_encode
!($writer
; $
($rest
),*);
176 $first
.encode(&mut $writer
, &mut ());
180 // FIXME(eddyb) this calls `decode` for each argument, but in reverse,
181 // to avoid borrow conflicts from borrows started by `&mut` arguments.
182 macro_rules
! reverse_decode
{
183 ($reader
:ident
, $s
:ident
;) => {}
;
184 ($reader
:ident
, $s
:ident
; $first
:ident
: $first_ty
:ty $
(, $rest
:ident
: $rest_ty
:ty
)*) => {
185 reverse_decode
!($reader
, $s
; $
($rest
: $rest_ty
),*);
186 let $first
= <$first_ty
>::decode(&mut $reader
, $s
);
190 #[allow(unsafe_code)]
192 #[forbid(unsafe_code)]
194 #[allow(unsafe_code)]
196 #[forbid(unsafe_code)]
199 #[forbid(unsafe_code)]
201 #[allow(unsafe_code)]
203 #[forbid(unsafe_code)]
207 pub use rpc
::PanicMessage
;
208 use rpc
::{Decode, DecodeMut, Encode, Reader, Writer}
;
210 /// An active connection between a server and a client.
211 /// The server creates the bridge (`Bridge::run_server` in `server.rs`),
212 /// then passes it to the client through the function pointer in the `run`
213 /// field of `client::Client`. The client holds its copy of the `Bridge`
214 /// in TLS during its execution (`Bridge::{enter, with}` in `client.rs`).
216 pub struct Bridge
<'a
> {
217 /// Reusable buffer (only `clear`-ed, never shrunk), primarily
218 /// used for making requests, but also for passing input to client.
219 cached_buffer
: Buffer
<u8>,
221 /// Server-side function that the client uses to make requests.
222 dispatch
: closure
::Closure
<'a
, Buffer
<u8>, Buffer
<u8>>,
224 /// If 'true', always invoke the default panic hook
225 force_show_panics
: bool
,
228 impl<'a
> !Sync
for Bridge
<'a
> {}
229 impl<'a
> !Send
for Bridge
<'a
> {}
231 #[forbid(unsafe_code)]
232 #[allow(non_camel_case_types)]
234 use super::rpc
::{DecodeMut, Encode, Reader, Writer}
;
236 macro_rules
! declare_tags
{
238 $
(fn $method
:ident($
($arg
:ident
: $arg_ty
:ty
),* $
(,)?
) $
(-> $ret_ty
:ty
)*;)*
241 pub(super) enum $name
{
244 rpc_encode_decode
!(enum $name { $($method),* }
);
248 pub(super) enum Method
{
251 rpc_encode_decode
!(enum Method { $($name(m)),* }
);
254 with_api
!(self, self, declare_tags
);
257 /// Helper to wrap associated types to allow trait impl dispatch.
258 /// That is, normally a pair of impls for `T::Foo` and `T::Bar`
259 /// can overlap, but if the impls are, instead, on types like
260 /// `Marked<T::Foo, Foo>` and `Marked<T::Bar, Bar>`, they can't.
263 fn mark(unmarked
: Self::Unmarked
) -> Self;
266 /// Unwrap types wrapped by `Mark::mark` (see `Mark` for details).
269 fn unmark(self) -> Self::Unmarked
;
272 #[derive(Copy, Clone, PartialEq, Eq, Hash)]
273 struct Marked
<T
, M
> {
275 _marker
: marker
::PhantomData
<M
>,
278 impl<T
, M
> Mark
for Marked
<T
, M
> {
280 fn mark(unmarked
: Self::Unmarked
) -> Self {
281 Marked { value: unmarked, _marker: marker::PhantomData }
284 impl<T
, M
> Unmark
for Marked
<T
, M
> {
286 fn unmark(self) -> Self::Unmarked
{
290 impl<T
, M
> Unmark
for &'a Marked
<T
, M
> {
291 type Unmarked
= &'a T
;
292 fn unmark(self) -> Self::Unmarked
{
296 impl<T
, M
> Unmark
for &'a
mut Marked
<T
, M
> {
297 type Unmarked
= &'a
mut T
;
298 fn unmark(self) -> Self::Unmarked
{
303 impl<T
: Mark
> Mark
for Option
<T
> {
304 type Unmarked
= Option
<T
::Unmarked
>;
305 fn mark(unmarked
: Self::Unmarked
) -> Self {
306 unmarked
.map(T
::mark
)
309 impl<T
: Unmark
> Unmark
for Option
<T
> {
310 type Unmarked
= Option
<T
::Unmarked
>;
311 fn unmark(self) -> Self::Unmarked
{
316 macro_rules
! mark_noop
{
317 ($
($ty
:ty
),* $
(,)?
) => {
320 type Unmarked
= Self;
321 fn mark(unmarked
: Self::Unmarked
) -> Self {
325 impl Unmark
for $ty
{
326 type Unmarked
= Self;
327 fn unmark(self) -> Self::Unmarked
{
364 rpc_encode_decode
!(struct LineColumn { line, column }
);
373 pub enum TokenTree
<G
, P
, I
, L
> {
380 impl<G
: Mark
, P
: Mark
, I
: Mark
, L
: Mark
> Mark
for TokenTree
<G
, P
, I
, L
> {
381 type Unmarked
= TokenTree
<G
::Unmarked
, P
::Unmarked
, I
::Unmarked
, L
::Unmarked
>;
382 fn mark(unmarked
: Self::Unmarked
) -> Self {
384 TokenTree
::Group(tt
) => TokenTree
::Group(G
::mark(tt
)),
385 TokenTree
::Punct(tt
) => TokenTree
::Punct(P
::mark(tt
)),
386 TokenTree
::Ident(tt
) => TokenTree
::Ident(I
::mark(tt
)),
387 TokenTree
::Literal(tt
) => TokenTree
::Literal(L
::mark(tt
)),
391 impl<G
: Unmark
, P
: Unmark
, I
: Unmark
, L
: Unmark
> Unmark
for TokenTree
<G
, P
, I
, L
> {
392 type Unmarked
= TokenTree
<G
::Unmarked
, P
::Unmarked
, I
::Unmarked
, L
::Unmarked
>;
393 fn unmark(self) -> Self::Unmarked
{
395 TokenTree
::Group(tt
) => TokenTree
::Group(tt
.unmark()),
396 TokenTree
::Punct(tt
) => TokenTree
::Punct(tt
.unmark()),
397 TokenTree
::Ident(tt
) => TokenTree
::Ident(tt
.unmark()),
398 TokenTree
::Literal(tt
) => TokenTree
::Literal(tt
.unmark()),
404 enum TokenTree
<G
, P
, I
, L
> {