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, Spacing};
17
18macro_rules! with_api {
49 ($S:ident, $self:ident, $m:ident) => {
50 $m! {
51 FreeFunctions {
52 fn drop($self: $S::FreeFunctions);
53 fn injected_env_var(var: &str) -> Option<String>;
54 fn track_env_var(var: &str, value: Option<&str>);
55 fn track_path(path: &str);
56 fn literal_from_str(s: &str) -> Result<Literal<$S::Span, $S::Symbol>, ()>;
57 fn emit_diagnostic(diagnostic: Diagnostic<$S::Span>);
58 },
59 TokenStream {
60 fn drop($self: $S::TokenStream);
61 fn clone($self: &$S::TokenStream) -> $S::TokenStream;
62 fn is_empty($self: &$S::TokenStream) -> bool;
63 fn expand_expr($self: &$S::TokenStream) -> Result<$S::TokenStream, ()>;
64 fn from_str(src: &str) -> $S::TokenStream;
65 fn to_string($self: &$S::TokenStream) -> String;
66 fn from_token_tree(
67 tree: TokenTree<$S::TokenStream, $S::Span, $S::Symbol>,
68 ) -> $S::TokenStream;
69 fn concat_trees(
70 base: Option<$S::TokenStream>,
71 trees: Vec<TokenTree<$S::TokenStream, $S::Span, $S::Symbol>>,
72 ) -> $S::TokenStream;
73 fn concat_streams(
74 base: Option<$S::TokenStream>,
75 streams: Vec<$S::TokenStream>,
76 ) -> $S::TokenStream;
77 fn into_trees(
78 $self: $S::TokenStream
79 ) -> Vec<TokenTree<$S::TokenStream, $S::Span, $S::Symbol>>;
80 },
81 SourceFile {
82 fn drop($self: $S::SourceFile);
83 fn clone($self: &$S::SourceFile) -> $S::SourceFile;
84 fn eq($self: &$S::SourceFile, other: &$S::SourceFile) -> bool;
85 fn path($self: &$S::SourceFile) -> String;
86 fn is_real($self: &$S::SourceFile) -> bool;
87 },
88 Span {
89 fn debug($self: $S::Span) -> String;
90 fn source_file($self: $S::Span) -> $S::SourceFile;
91 fn parent($self: $S::Span) -> Option<$S::Span>;
92 fn source($self: $S::Span) -> $S::Span;
93 fn byte_range($self: $S::Span) -> Range<usize>;
94 fn start($self: $S::Span) -> $S::Span;
95 fn end($self: $S::Span) -> $S::Span;
96 fn line($self: $S::Span) -> usize;
97 fn column($self: $S::Span) -> usize;
98 fn join($self: $S::Span, other: $S::Span) -> Option<$S::Span>;
99 fn subspan($self: $S::Span, start: Bound<usize>, end: Bound<usize>) -> Option<$S::Span>;
100 fn resolved_at($self: $S::Span, at: $S::Span) -> $S::Span;
101 fn source_text($self: $S::Span) -> Option<String>;
102 fn save_span($self: $S::Span) -> usize;
103 fn recover_proc_macro_span(id: usize) -> $S::Span;
104 },
105 Symbol {
106 fn normalize_and_validate_ident(string: &str) -> Result<$S::Symbol, ()>;
107 },
108 }
109 };
110}
111
112macro_rules! with_api_handle_types {
115 ($m:ident) => {
116 $m! {
117 'owned:
118 FreeFunctions,
119 TokenStream,
120 SourceFile,
121
122 'interned:
123 Span,
124 }
126 };
127}
128
129macro_rules! reverse_encode {
132 ($writer:ident;) => {};
133 ($writer:ident; $first:ident $(, $rest:ident)*) => {
134 reverse_encode!($writer; $($rest),*);
135 $first.encode(&mut $writer, &mut ());
136 }
137}
138
139macro_rules! reverse_decode {
142 ($reader:ident, $s:ident;) => {};
143 ($reader:ident, $s:ident; $first:ident: $first_ty:ty $(, $rest:ident: $rest_ty:ty)*) => {
144 reverse_decode!($reader, $s; $($rest: $rest_ty),*);
145 let $first = <$first_ty>::decode(&mut $reader, $s);
146 }
147}
148
149#[allow(unsafe_code)]
150mod arena;
151#[allow(unsafe_code)]
152mod buffer;
153#[deny(unsafe_code)]
154pub mod client;
155#[allow(unsafe_code)]
156mod closure;
157#[forbid(unsafe_code)]
158mod fxhash;
159#[forbid(unsafe_code)]
160mod handle;
161#[macro_use]
162#[forbid(unsafe_code)]
163mod rpc;
164#[allow(unsafe_code)]
165mod selfless_reify;
166#[forbid(unsafe_code)]
167pub mod server;
168#[allow(unsafe_code)]
169mod symbol;
170
171use buffer::Buffer;
172pub use rpc::PanicMessage;
173use rpc::{Decode, DecodeMut, Encode, Reader, Writer};
174
175#[repr(C)]
181pub struct BridgeConfig<'a> {
182 input: Buffer,
184
185 dispatch: closure::Closure<'a, Buffer, Buffer>,
187
188 force_show_panics: bool,
190
191 _marker: marker::PhantomData<*mut ()>,
195}
196
197#[forbid(unsafe_code)]
198#[allow(non_camel_case_types)]
199mod api_tags {
200 use super::rpc::{DecodeMut, Encode, Reader, Writer};
201
202 macro_rules! declare_tags {
203 ($($name:ident {
204 $(fn $method:ident($($arg:ident: $arg_ty:ty),* $(,)?) $(-> $ret_ty:ty)*;)*
205 }),* $(,)?) => {
206 $(
207 pub(super) enum $name {
208 $($method),*
209 }
210 rpc_encode_decode!(enum $name { $($method),* });
211 )*
212
213 pub(super) enum Method {
214 $($name($name)),*
215 }
216 rpc_encode_decode!(enum Method { $($name(m)),* });
217 }
218 }
219 with_api!(self, self, declare_tags);
220}
221
222trait Mark {
227 type Unmarked;
228 fn mark(unmarked: Self::Unmarked) -> Self;
229}
230
231trait Unmark {
233 type Unmarked;
234 fn unmark(self) -> Self::Unmarked;
235}
236
237#[derive(Copy, Clone, PartialEq, Eq, Hash)]
238struct Marked<T, M> {
239 value: T,
240 _marker: marker::PhantomData<M>,
241}
242
243impl<T, M> Mark for Marked<T, M> {
244 type Unmarked = T;
245 fn mark(unmarked: Self::Unmarked) -> Self {
246 Marked { value: unmarked, _marker: marker::PhantomData }
247 }
248}
249impl<T, M> Unmark for Marked<T, M> {
250 type Unmarked = T;
251 fn unmark(self) -> Self::Unmarked {
252 self.value
253 }
254}
255impl<'a, T, M> Unmark for &'a Marked<T, M> {
256 type Unmarked = &'a T;
257 fn unmark(self) -> Self::Unmarked {
258 &self.value
259 }
260}
261impl<'a, T, M> Unmark for &'a mut Marked<T, M> {
262 type Unmarked = &'a mut T;
263 fn unmark(self) -> Self::Unmarked {
264 &mut self.value
265 }
266}
267
268impl<T: Mark> Mark for Vec<T> {
269 type Unmarked = Vec<T::Unmarked>;
270 fn mark(unmarked: Self::Unmarked) -> Self {
271 unmarked.into_iter().map(T::mark).collect()
273 }
274}
275impl<T: Unmark> Unmark for Vec<T> {
276 type Unmarked = Vec<T::Unmarked>;
277 fn unmark(self) -> Self::Unmarked {
278 self.into_iter().map(T::unmark).collect()
280 }
281}
282
283macro_rules! mark_noop {
284 ($($ty:ty),* $(,)?) => {
285 $(
286 impl Mark for $ty {
287 type Unmarked = Self;
288 fn mark(unmarked: Self::Unmarked) -> Self {
289 unmarked
290 }
291 }
292 impl Unmark for $ty {
293 type Unmarked = Self;
294 fn unmark(self) -> Self::Unmarked {
295 self
296 }
297 }
298 )*
299 }
300}
301mark_noop! {
302 (),
303 bool,
304 char,
305 &'_ [u8],
306 &'_ str,
307 String,
308 u8,
309 usize,
310 Delimiter,
311 LitKind,
312 Level,
313 Spacing,
314}
315
316rpc_encode_decode!(
317 enum Delimiter {
318 Parenthesis,
319 Brace,
320 Bracket,
321 None,
322 }
323);
324rpc_encode_decode!(
325 enum Level {
326 Error,
327 Warning,
328 Note,
329 Help,
330 }
331);
332rpc_encode_decode!(
333 enum Spacing {
334 Alone,
335 Joint,
336 }
337);
338
339#[derive(Copy, Clone, Eq, PartialEq, Debug)]
340pub enum LitKind {
341 Byte,
342 Char,
343 Integer,
344 Float,
345 Str,
346 StrRaw(u8),
347 ByteStr,
348 ByteStrRaw(u8),
349 CStr,
350 CStrRaw(u8),
351 ErrWithGuar,
356}
357
358rpc_encode_decode!(
359 enum LitKind {
360 Byte,
361 Char,
362 Integer,
363 Float,
364 Str,
365 StrRaw(n),
366 ByteStr,
367 ByteStrRaw(n),
368 CStr,
369 CStrRaw(n),
370 ErrWithGuar,
371 }
372);
373
374macro_rules! mark_compound {
375 (struct $name:ident <$($T:ident),+> { $($field:ident),* $(,)? }) => {
376 impl<$($T: Mark),+> Mark for $name <$($T),+> {
377 type Unmarked = $name <$($T::Unmarked),+>;
378 fn mark(unmarked: Self::Unmarked) -> Self {
379 $name {
380 $($field: Mark::mark(unmarked.$field)),*
381 }
382 }
383 }
384
385 impl<$($T: Unmark),+> Unmark for $name <$($T),+> {
386 type Unmarked = $name <$($T::Unmarked),+>;
387 fn unmark(self) -> Self::Unmarked {
388 $name {
389 $($field: Unmark::unmark(self.$field)),*
390 }
391 }
392 }
393 };
394 (enum $name:ident <$($T:ident),+> { $($variant:ident $(($field:ident))?),* $(,)? }) => {
395 impl<$($T: Mark),+> Mark for $name <$($T),+> {
396 type Unmarked = $name <$($T::Unmarked),+>;
397 fn mark(unmarked: Self::Unmarked) -> Self {
398 match unmarked {
399 $($name::$variant $(($field))? => {
400 $name::$variant $((Mark::mark($field)))?
401 })*
402 }
403 }
404 }
405
406 impl<$($T: Unmark),+> Unmark for $name <$($T),+> {
407 type Unmarked = $name <$($T::Unmarked),+>;
408 fn unmark(self) -> Self::Unmarked {
409 match self {
410 $($name::$variant $(($field))? => {
411 $name::$variant $((Unmark::unmark($field)))?
412 })*
413 }
414 }
415 }
416 }
417}
418
419macro_rules! compound_traits {
420 ($($t:tt)*) => {
421 rpc_encode_decode!($($t)*);
422 mark_compound!($($t)*);
423 };
424}
425
426compound_traits!(
427 enum Bound<T> {
428 Included(x),
429 Excluded(x),
430 Unbounded,
431 }
432);
433
434compound_traits!(
435 enum Option<T> {
436 Some(t),
437 None,
438 }
439);
440
441compound_traits!(
442 enum Result<T, E> {
443 Ok(t),
444 Err(e),
445 }
446);
447
448#[derive(Copy, Clone)]
449pub struct DelimSpan<Span> {
450 pub open: Span,
451 pub close: Span,
452 pub entire: Span,
453}
454
455impl<Span: Copy> DelimSpan<Span> {
456 pub fn from_single(span: Span) -> Self {
457 DelimSpan { open: span, close: span, entire: span }
458 }
459}
460
461compound_traits!(struct DelimSpan<Span> { open, close, entire });
462
463#[derive(Clone)]
464pub struct Group<TokenStream, Span> {
465 pub delimiter: Delimiter,
466 pub stream: Option<TokenStream>,
467 pub span: DelimSpan<Span>,
468}
469
470compound_traits!(struct Group<TokenStream, Span> { delimiter, stream, span });
471
472#[derive(Clone)]
473pub struct Punct<Span> {
474 pub ch: u8,
475 pub joint: bool,
476 pub span: Span,
477}
478
479compound_traits!(struct Punct<Span> { ch, joint, span });
480
481#[derive(Copy, Clone, Eq, PartialEq)]
482pub struct Ident<Span, Symbol> {
483 pub sym: Symbol,
484 pub is_raw: bool,
485 pub span: Span,
486}
487
488compound_traits!(struct Ident<Span, Symbol> { sym, is_raw, span });
489
490#[derive(Clone, Eq, PartialEq)]
491pub struct Literal<Span, Symbol> {
492 pub kind: LitKind,
493 pub symbol: Symbol,
494 pub suffix: Option<Symbol>,
495 pub span: Span,
496}
497
498compound_traits!(struct Literal<Sp, Sy> { kind, symbol, suffix, span });
499
500#[derive(Clone)]
501pub enum TokenTree<TokenStream, Span, Symbol> {
502 Group(Group<TokenStream, Span>),
503 Punct(Punct<Span>),
504 Ident(Ident<Span, Symbol>),
505 Literal(Literal<Span, Symbol>),
506}
507
508compound_traits!(
509 enum TokenTree<TokenStream, Span, Symbol> {
510 Group(tt),
511 Punct(tt),
512 Ident(tt),
513 Literal(tt),
514 }
515);
516
517#[derive(Clone, Debug)]
518pub struct Diagnostic<Span> {
519 pub level: Level,
520 pub message: String,
521 pub spans: Vec<Span>,
522 pub children: Vec<Diagnostic<Span>>,
523}
524
525compound_traits!(
526 struct Diagnostic<Span> { level, message, spans, children }
527);
528
529#[derive(Clone)]
532pub struct ExpnGlobals<Span> {
533 pub def_site: Span,
534 pub call_site: Span,
535 pub mixed_site: Span,
536}
537
538compound_traits!(
539 struct ExpnGlobals<Span> { def_site, call_site, mixed_site }
540);
541
542compound_traits!(
543 struct Range<T> { start, end }
544);