1#![deny(unsafe_code)]
10
11use std::hash::Hash;
12use std::ops::{Bound, Range};
13use std::sync::Once;
14use std::{fmt, marker, mem, panic, thread};
15
16use crate::{Delimiter, Level};
17
18macro_rules! with_api {
35 ($m:ident, $TokenStream: path, $Span: path, $Symbol: path) => {
36 $m! {
37 fn injected_env_var(var: &str) -> Option<String>;
38 fn track_env_var(var: &str, value: Option<&str>);
39 fn track_path(path: &str);
40 fn literal_from_str(s: &str) -> Result<Literal<$Span, $Symbol>, String>;
41 fn emit_diagnostic(diagnostic: Diagnostic<$Span>);
42
43 fn ts_drop(stream: $TokenStream);
44 fn ts_clone(stream: &$TokenStream) -> $TokenStream;
45 fn ts_is_empty(stream: &$TokenStream) -> bool;
46 fn ts_expand_expr(stream: &$TokenStream) -> Result<$TokenStream, ()>;
47 fn ts_from_str(src: &str) -> Result<$TokenStream, String>;
48 fn ts_to_string(stream: &$TokenStream) -> String;
49 fn ts_from_token_tree(
50 tree: TokenTree<$TokenStream, $Span, $Symbol>,
51 ) -> $TokenStream;
52 fn ts_concat_trees(
53 base: Option<$TokenStream>,
54 trees: Vec<TokenTree<$TokenStream, $Span, $Symbol>>,
55 ) -> $TokenStream;
56 fn ts_concat_streams(
57 base: Option<$TokenStream>,
58 streams: Vec<$TokenStream>,
59 ) -> $TokenStream;
60 fn ts_into_trees(
61 stream: $TokenStream
62 ) -> Vec<TokenTree<$TokenStream, $Span, $Symbol>>;
63
64 fn span_debug(span: $Span) -> String;
65 fn span_parent(span: $Span) -> Option<$Span>;
66 fn span_source(span: $Span) -> $Span;
67 fn span_byte_range(span: $Span) -> Range<usize>;
68 fn span_start(span: $Span) -> $Span;
69 fn span_end(span: $Span) -> $Span;
70 fn span_line(span: $Span) -> usize;
71 fn span_column(span: $Span) -> usize;
72 fn span_file(span: $Span) -> String;
73 fn span_local_file(span: $Span) -> Option<String>;
74 fn span_join(span: $Span, other: $Span) -> Option<$Span>;
75 fn span_subspan(span: $Span, start: Bound<usize>, end: Bound<usize>) -> Option<$Span>;
76 fn span_resolved_at(span: $Span, at: $Span) -> $Span;
77 fn span_source_text(span: $Span) -> Option<String>;
78 fn span_save_span(span: $Span) -> usize;
79 fn span_recover_proc_macro_span(id: usize) -> $Span;
80
81 fn symbol_normalize_and_validate_ident(string: &str) -> Result<$Symbol, ()>;
82 }
83 };
84}
85
86pub(crate) struct Methods;
87
88#[allow(unsafe_code)]
89mod arena;
90#[allow(unsafe_code)]
91mod buffer;
92#[deny(unsafe_code)]
93pub mod client;
94#[allow(unsafe_code)]
95mod closure;
96#[forbid(unsafe_code)]
97mod fxhash;
98#[forbid(unsafe_code)]
99mod handle;
100#[macro_use]
101#[forbid(unsafe_code)]
102mod rpc;
103#[allow(unsafe_code)]
104mod selfless_reify;
105#[forbid(unsafe_code)]
106pub mod server;
107#[allow(unsafe_code)]
108mod symbol;
109
110use buffer::Buffer;
111pub use rpc::PanicMessage;
112use rpc::{Decode, Encode};
113
114#[repr(C)]
120pub struct BridgeConfig<'a> {
121 input: Buffer,
123
124 dispatch: closure::Closure<'a>,
126
127 force_show_panics: bool,
129}
130
131impl !Send for BridgeConfig<'_> {}
132impl !Sync for BridgeConfig<'_> {}
133
134macro_rules! declare_tags {
135 (
136 $(fn $method:ident($($arg:ident: $arg_ty:ty),* $(,)?) $(-> $ret_ty:ty)?;)*
137 ) => {
138 #[allow(non_camel_case_types)]
139 pub(super) enum ApiTags {
140 $($method),*
141 }
142 rpc_encode_decode!(enum ApiTags { $($method),* });
143 }
144}
145with_api!(declare_tags, __, __, __);
146
147trait Mark {
152 type Unmarked;
153 fn mark(unmarked: Self::Unmarked) -> Self;
154 fn unmark(self) -> Self::Unmarked;
155}
156
157#[derive(Copy, Clone, PartialEq, Eq, Hash)]
158struct Marked<T, M> {
159 value: T,
160 _marker: marker::PhantomData<M>,
161}
162
163impl<T, M> Mark for Marked<T, M> {
164 type Unmarked = T;
165 #[inline]
166 fn mark(unmarked: Self::Unmarked) -> Self {
167 Marked { value: unmarked, _marker: marker::PhantomData }
168 }
169 #[inline]
170 fn unmark(self) -> Self::Unmarked {
171 self.value
172 }
173}
174impl<'a, T> Mark for &'a Marked<T, client::TokenStream> {
175 type Unmarked = &'a T;
176 fn mark(_: Self::Unmarked) -> Self {
177 unreachable!()
178 }
179 #[inline]
180 fn unmark(self) -> Self::Unmarked {
181 &self.value
182 }
183}
184
185impl<T: Mark> Mark for Vec<T> {
186 type Unmarked = Vec<T::Unmarked>;
187 #[inline]
188 fn mark(unmarked: Self::Unmarked) -> Self {
189 unmarked.into_iter().map(T::mark).collect()
191 }
192 #[inline]
193 fn unmark(self) -> Self::Unmarked {
194 self.into_iter().map(T::unmark).collect()
196 }
197}
198
199macro_rules! mark_noop {
200 ($($ty:ty),* $(,)?) => {
201 $(
202 impl Mark for $ty {
203 type Unmarked = Self;
204 #[inline]
205 fn mark(unmarked: Self::Unmarked) -> Self {
206 unmarked
207 }
208 #[inline]
209 fn unmark(self) -> Self::Unmarked {
210 self
211 }
212 }
213 )*
214 }
215}
216mark_noop! {
217 (),
218 bool,
219 &'_ str,
220 String,
221 u8,
222 usize,
223 Delimiter,
224 LitKind,
225 Level,
226 Bound<usize>,
227 Range<usize>,
228}
229
230rpc_encode_decode!(
231 enum Delimiter {
232 Parenthesis,
233 Brace,
234 Bracket,
235 None,
236 }
237);
238rpc_encode_decode!(
239 enum Level {
240 Error,
241 Warning,
242 Note,
243 Help,
244 }
245);
246
247#[derive(Copy, Clone, Eq, PartialEq, Debug)]
248pub enum LitKind {
249 Byte,
250 Char,
251 Integer,
252 Float,
253 Str,
254 StrRaw(u8),
255 ByteStr,
256 ByteStrRaw(u8),
257 CStr,
258 CStrRaw(u8),
259 ErrWithGuar,
264}
265
266rpc_encode_decode!(
267 enum LitKind {
268 Byte,
269 Char,
270 Integer,
271 Float,
272 Str,
273 StrRaw(n),
274 ByteStr,
275 ByteStrRaw(n),
276 CStr,
277 CStrRaw(n),
278 ErrWithGuar,
279 }
280);
281
282macro_rules! mark_compound {
283 (struct $name:ident <$($T:ident),+> { $($field:ident),* $(,)? }) => {
284 impl<$($T: Mark),+> Mark for $name <$($T),+> {
285 type Unmarked = $name <$($T::Unmarked),+>;
286 #[inline]
287 fn mark(unmarked: Self::Unmarked) -> Self {
288 $name {
289 $($field: Mark::mark(unmarked.$field)),*
290 }
291 }
292 #[inline]
293 fn unmark(self) -> Self::Unmarked {
294 $name {
295 $($field: Mark::unmark(self.$field)),*
296 }
297 }
298 }
299 };
300 (enum $name:ident <$($T:ident),+> { $($variant:ident $(($field:ident))?),* $(,)? }) => {
301 impl<$($T: Mark),+> Mark for $name <$($T),+> {
302 type Unmarked = $name <$($T::Unmarked),+>;
303 #[inline]
304 fn mark(unmarked: Self::Unmarked) -> Self {
305 match unmarked {
306 $($name::$variant $(($field))? => {
307 $name::$variant $((Mark::mark($field)))?
308 })*
309 }
310 }
311 #[inline]
312 fn unmark(self) -> Self::Unmarked {
313 match self {
314 $($name::$variant $(($field))? => {
315 $name::$variant $((Mark::unmark($field)))?
316 })*
317 }
318 }
319 }
320 }
321}
322
323macro_rules! compound_traits {
324 ($($t:tt)*) => {
325 rpc_encode_decode!($($t)*);
326 mark_compound!($($t)*);
327 };
328}
329
330rpc_encode_decode!(
331 enum Bound<T> {
332 Included(x),
333 Excluded(x),
334 Unbounded,
335 }
336);
337
338compound_traits!(
339 enum Option<T> {
340 Some(t),
341 None,
342 }
343);
344
345compound_traits!(
346 enum Result<T, E> {
347 Ok(t),
348 Err(e),
349 }
350);
351
352#[derive(Copy, Clone)]
353pub struct DelimSpan<Span> {
354 pub open: Span,
355 pub close: Span,
356 pub entire: Span,
357}
358
359impl<Span: Copy> DelimSpan<Span> {
360 pub fn from_single(span: Span) -> Self {
361 DelimSpan { open: span, close: span, entire: span }
362 }
363}
364
365compound_traits!(struct DelimSpan<Span> { open, close, entire });
366
367#[derive(Clone)]
368pub struct Group<TokenStream, Span> {
369 pub delimiter: Delimiter,
370 pub stream: Option<TokenStream>,
371 pub span: DelimSpan<Span>,
372}
373
374compound_traits!(struct Group<TokenStream, Span> { delimiter, stream, span });
375
376#[derive(Clone)]
377pub struct Punct<Span> {
378 pub ch: u8,
379 pub joint: bool,
380 pub span: Span,
381}
382
383compound_traits!(struct Punct<Span> { ch, joint, span });
384
385#[derive(Copy, Clone, Eq, PartialEq)]
386pub struct Ident<Span, Symbol> {
387 pub sym: Symbol,
388 pub is_raw: bool,
389 pub span: Span,
390}
391
392compound_traits!(struct Ident<Span, Symbol> { sym, is_raw, span });
393
394#[derive(Clone, Eq, PartialEq)]
395pub struct Literal<Span, Symbol> {
396 pub kind: LitKind,
397 pub symbol: Symbol,
398 pub suffix: Option<Symbol>,
399 pub span: Span,
400}
401
402compound_traits!(struct Literal<Span, Symbol> { kind, symbol, suffix, span });
403
404#[derive(Clone)]
405pub enum TokenTree<TokenStream, Span, Symbol> {
406 Group(Group<TokenStream, Span>),
407 Punct(Punct<Span>),
408 Ident(Ident<Span, Symbol>),
409 Literal(Literal<Span, Symbol>),
410}
411
412compound_traits!(
413 enum TokenTree<TokenStream, Span, Symbol> {
414 Group(tt),
415 Punct(tt),
416 Ident(tt),
417 Literal(tt),
418 }
419);
420
421#[derive(Clone, Debug)]
422pub struct Diagnostic<Span> {
423 pub level: Level,
424 pub message: String,
425 pub spans: Vec<Span>,
426 pub children: Vec<Diagnostic<Span>>,
427}
428
429compound_traits!(
430 struct Diagnostic<Span> { level, message, spans, children }
431);
432
433#[derive(Clone)]
436pub struct ExpnGlobals<Span> {
437 pub def_site: Span,
438 pub call_site: Span,
439 pub mixed_site: Span,
440}
441
442compound_traits!(
443 struct ExpnGlobals<Span> { def_site, call_site, mixed_site }
444);
445
446rpc_encode_decode!(
447 struct Range<T> { start, end }
448);