1#![deny(unsafe_code)]
10
11use std::hash::Hash;
12use std::marker;
13use std::ops::{Bound, Range};
14
15use crate::{Delimiter, Level};
16
17macro_rules! with_api {
34 ($m:ident, $TokenStream: path, $Span: path, $Symbol: path) => {
35 $m! {
36 fn track_env_var(var: &str, value: Option<&str>);
37 fn track_path(path: &str);
38 fn literal_from_str(s: &str) -> Result<Literal<$Span, $Symbol>, String>;
39 fn emit_diagnostic(diagnostic: Diagnostic<$Span>);
40
41 fn ts_drop(stream: $TokenStream);
42 fn ts_clone(stream: &$TokenStream) -> $TokenStream;
43 fn ts_is_empty(stream: &$TokenStream) -> bool;
44 fn ts_expand_expr(stream: &$TokenStream) -> Result<$TokenStream, ()>;
45 fn ts_from_str(src: &str) -> Result<$TokenStream, String>;
46 fn ts_to_string(stream: &$TokenStream) -> String;
47 fn ts_from_token_tree(
48 tree: TokenTree<$TokenStream, $Span, $Symbol>,
49 ) -> $TokenStream;
50 fn ts_concat_trees(
51 base: Option<$TokenStream>,
52 trees: Vec<TokenTree<$TokenStream, $Span, $Symbol>>,
53 ) -> $TokenStream;
54 fn ts_concat_streams(
55 base: Option<$TokenStream>,
56 streams: Vec<$TokenStream>,
57 ) -> $TokenStream;
58 fn ts_into_trees(
59 stream: $TokenStream
60 ) -> Vec<TokenTree<$TokenStream, $Span, $Symbol>>;
61
62 fn span_debug(span: $Span) -> String;
63 fn span_parent(span: $Span) -> Option<$Span>;
64 fn span_source(span: $Span) -> $Span;
65 fn span_byte_range(span: $Span) -> Range<usize>;
66 fn span_start(span: $Span) -> $Span;
67 fn span_end(span: $Span) -> $Span;
68 fn span_line(span: $Span) -> usize;
69 fn span_column(span: $Span) -> usize;
70 fn span_file(span: $Span) -> String;
71 fn span_local_file(span: $Span) -> Option<String>;
72 fn span_join(span: $Span, other: $Span) -> Option<$Span>;
73 fn span_subspan(span: $Span, start: Bound<usize>, end: Bound<usize>) -> Option<$Span>;
74 fn span_resolved_at(span: $Span, at: $Span) -> $Span;
75 fn span_source_text(span: $Span) -> Option<String>;
76 fn span_save_span(span: $Span) -> usize;
77 fn span_recover_proc_macro_span(id: usize) -> $Span;
78
79 fn symbol_normalize_and_validate_ident(string: &str) -> Result<$Symbol, ()>;
80 }
81 };
82}
83
84pub(crate) struct Methods;
85
86#[allow(unsafe_code)]
87mod arena;
88#[allow(unsafe_code)]
89mod buffer;
90#[deny(unsafe_code)]
91pub mod client;
92#[allow(unsafe_code)]
93mod closure;
94#[forbid(unsafe_code)]
95mod fxhash;
96#[forbid(unsafe_code)]
97mod handle;
98#[macro_use]
99#[forbid(unsafe_code)]
100mod rpc;
101#[forbid(unsafe_code)]
102mod panic_message;
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 panic_message::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 IdentKind,
226 Level,
227 Bound<usize>,
228 Range<usize>,
229}
230
231rpc_encode_decode!(
232 enum Delimiter {
233 Parenthesis,
234 Brace,
235 Bracket,
236 None,
237 }
238);
239rpc_encode_decode!(
240 enum Level {
241 Error,
242 Warning,
243 Note,
244 Help,
245 }
246);
247
248#[derive(Copy, Clone, Eq, PartialEq, Debug)]
249pub enum LitKind {
250 Byte,
251 Char,
252 Integer,
253 Float,
254 Str,
255 StrRaw(u8),
256 ByteStr,
257 ByteStrRaw(u8),
258 CStr,
259 CStrRaw(u8),
260 ErrWithGuar,
265}
266
267rpc_encode_decode!(
268 enum LitKind {
269 Byte,
270 Char,
271 Integer,
272 Float,
273 Str,
274 StrRaw(n),
275 ByteStr,
276 ByteStrRaw(n),
277 CStr,
278 CStrRaw(n),
279 ErrWithGuar,
280 }
281);
282
283macro_rules! mark_compound {
284 (struct $name:ident <$($T:ident),+> { $($field:ident),* $(,)? }) => {
285 impl<$($T: Mark),+> Mark for $name <$($T),+> {
286 type Unmarked = $name <$($T::Unmarked),+>;
287 #[inline]
288 fn mark(unmarked: Self::Unmarked) -> Self {
289 $name {
290 $($field: Mark::mark(unmarked.$field)),*
291 }
292 }
293 #[inline]
294 fn unmark(self) -> Self::Unmarked {
295 $name {
296 $($field: Mark::unmark(self.$field)),*
297 }
298 }
299 }
300 };
301 (enum $name:ident <$($T:ident),+> { $($variant:ident $(($field:ident))?),* $(,)? }) => {
302 impl<$($T: Mark),+> Mark for $name <$($T),+> {
303 type Unmarked = $name <$($T::Unmarked),+>;
304 #[inline]
305 fn mark(unmarked: Self::Unmarked) -> Self {
306 match unmarked {
307 $($name::$variant $(($field))? => {
308 $name::$variant $((Mark::mark($field)))?
309 })*
310 }
311 }
312 #[inline]
313 fn unmark(self) -> Self::Unmarked {
314 match self {
315 $($name::$variant $(($field))? => {
316 $name::$variant $((Mark::unmark($field)))?
317 })*
318 }
319 }
320 }
321 }
322}
323
324macro_rules! compound_traits {
325 ($($t:tt)*) => {
326 rpc_encode_decode!($($t)*);
327 mark_compound!($($t)*);
328 };
329}
330
331rpc_encode_decode!(
332 enum Bound<T> {
333 Included(x),
334 Excluded(x),
335 Unbounded,
336 }
337);
338
339compound_traits!(
340 enum Option<T> {
341 Some(t),
342 None,
343 }
344);
345
346compound_traits!(
347 enum Result<T, E> {
348 Ok(t),
349 Err(e),
350 }
351);
352
353#[derive(Copy, Clone)]
354pub struct DelimSpan<Span> {
355 pub open: Span,
356 pub close: Span,
357 pub entire: Span,
358}
359
360impl<Span: Copy> DelimSpan<Span> {
361 pub fn from_single(span: Span) -> Self {
362 DelimSpan { open: span, close: span, entire: span }
363 }
364}
365
366compound_traits!(struct DelimSpan<Span> { open, close, entire });
367
368#[derive(Clone)]
369pub struct Group<TokenStream, Span> {
370 pub delimiter: Delimiter,
371 pub stream: Option<TokenStream>,
372 pub span: DelimSpan<Span>,
373}
374
375compound_traits!(struct Group<TokenStream, Span> { delimiter, stream, span });
376
377#[derive(Clone)]
378pub struct Punct<Span> {
379 pub ch: u8,
380 pub joint: bool,
381 pub span: Span,
382}
383
384compound_traits!(struct Punct<Span> { ch, joint, span });
385
386#[derive(Copy, Clone, Eq, PartialEq)]
387pub struct Ident<Span, Symbol> {
388 pub sym: Symbol,
389 pub kind: IdentKind,
390 pub span: Span,
391}
392
393compound_traits!(struct Ident<Span, Symbol> { sym, kind, span });
394
395#[derive(Copy, Clone, Eq, PartialEq)]
396pub enum IdentKind {
397 Normal,
398 Raw,
399 ForcedKeyword,
400}
401
402impl IdentKind {
403 pub fn prefix(self) -> Option<&'static str> {
404 match self {
405 Self::Normal => None,
406 Self::Raw => Some("r#"),
407 Self::ForcedKeyword => Some("k#"),
408 }
409 }
410}
411
412rpc_encode_decode!(
413 enum IdentKind {
414 Normal,
415 Raw,
416 ForcedKeyword,
417 }
418);
419
420#[derive(Clone, Eq, PartialEq)]
421pub struct Literal<Span, Symbol> {
422 pub kind: LitKind,
423 pub symbol: Symbol,
424 pub suffix: Option<Symbol>,
425 pub span: Span,
426}
427
428compound_traits!(struct Literal<Span, Symbol> { kind, symbol, suffix, span });
429
430#[derive(Clone)]
431pub enum TokenTree<TokenStream, Span, Symbol> {
432 Group(Group<TokenStream, Span>),
433 Punct(Punct<Span>),
434 Ident(Ident<Span, Symbol>),
435 Literal(Literal<Span, Symbol>),
436}
437
438compound_traits!(
439 enum TokenTree<TokenStream, Span, Symbol> {
440 Group(tt),
441 Punct(tt),
442 Ident(tt),
443 Literal(tt),
444 }
445);
446
447#[derive(Clone, Debug)]
448pub struct Diagnostic<Span> {
449 pub level: Level,
450 pub message: String,
451 pub spans: Vec<Span>,
452 pub children: Vec<Diagnostic<Span>>,
453}
454
455compound_traits!(
456 struct Diagnostic<Span> { level, message, spans, children }
457);
458
459#[derive(Clone)]
462pub struct ExpnGlobals<Span> {
463 pub def_site: Span,
464 pub call_site: Span,
465 pub mixed_site: Span,
466}
467
468compound_traits!(
469 struct ExpnGlobals<Span> { def_site, call_site, mixed_site }
470);
471
472rpc_encode_decode!(
473 struct Range<T> { start, end }
474);