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 Span {
82 fn debug($self: $S::Span) -> String;
83 fn parent($self: $S::Span) -> Option<$S::Span>;
84 fn source($self: $S::Span) -> $S::Span;
85 fn byte_range($self: $S::Span) -> Range<usize>;
86 fn start($self: $S::Span) -> $S::Span;
87 fn end($self: $S::Span) -> $S::Span;
88 fn line($self: $S::Span) -> usize;
89 fn column($self: $S::Span) -> usize;
90 fn file($self: $S::Span) -> String;
91 fn local_file($self: $S::Span) -> Option<String>;
92 fn join($self: $S::Span, other: $S::Span) -> Option<$S::Span>;
93 fn subspan($self: $S::Span, start: Bound<usize>, end: Bound<usize>) -> Option<$S::Span>;
94 fn resolved_at($self: $S::Span, at: $S::Span) -> $S::Span;
95 fn source_text($self: $S::Span) -> Option<String>;
96 fn save_span($self: $S::Span) -> usize;
97 fn recover_proc_macro_span(id: usize) -> $S::Span;
98 },
99 Symbol {
100 fn normalize_and_validate_ident(string: &str) -> Result<$S::Symbol, ()>;
101 },
102 }
103 };
104}
105
106macro_rules! with_api_handle_types {
109 ($m:ident) => {
110 $m! {
111 'owned:
112 FreeFunctions,
113 TokenStream,
114
115 'interned:
116 Span,
117 }
119 };
120}
121
122#[allow(unsafe_code)]
123mod arena;
124#[allow(unsafe_code)]
125mod buffer;
126#[deny(unsafe_code)]
127pub mod client;
128#[allow(unsafe_code)]
129mod closure;
130#[forbid(unsafe_code)]
131mod fxhash;
132#[forbid(unsafe_code)]
133mod handle;
134#[macro_use]
135#[forbid(unsafe_code)]
136mod rpc;
137#[allow(unsafe_code)]
138mod selfless_reify;
139#[forbid(unsafe_code)]
140pub mod server;
141#[allow(unsafe_code)]
142mod symbol;
143
144use buffer::Buffer;
145pub use rpc::PanicMessage;
146use rpc::{Decode, DecodeMut, Encode, Reader, Writer};
147
148#[repr(C)]
154pub struct BridgeConfig<'a> {
155 input: Buffer,
157
158 dispatch: closure::Closure<'a, Buffer, Buffer>,
160
161 force_show_panics: bool,
163}
164
165impl !Send for BridgeConfig<'_> {}
166impl !Sync for BridgeConfig<'_> {}
167
168#[forbid(unsafe_code)]
169#[allow(non_camel_case_types)]
170mod api_tags {
171 use super::rpc::{DecodeMut, Encode, Reader, Writer};
172
173 macro_rules! declare_tags {
174 ($($name:ident {
175 $(fn $method:ident($($arg:ident: $arg_ty:ty),* $(,)?) $(-> $ret_ty:ty)*;)*
176 }),* $(,)?) => {
177 $(
178 pub(super) enum $name {
179 $($method),*
180 }
181 rpc_encode_decode!(enum $name { $($method),* });
182 )*
183
184 pub(super) enum Method {
185 $($name($name)),*
186 }
187 rpc_encode_decode!(enum Method { $($name(m)),* });
188 }
189 }
190 with_api!(self, self, declare_tags);
191}
192
193trait Mark {
198 type Unmarked;
199 fn mark(unmarked: Self::Unmarked) -> Self;
200}
201
202trait Unmark {
204 type Unmarked;
205 fn unmark(self) -> Self::Unmarked;
206}
207
208#[derive(Copy, Clone, PartialEq, Eq, Hash)]
209struct Marked<T, M> {
210 value: T,
211 _marker: marker::PhantomData<M>,
212}
213
214impl<T, M> Mark for Marked<T, M> {
215 type Unmarked = T;
216 fn mark(unmarked: Self::Unmarked) -> Self {
217 Marked { value: unmarked, _marker: marker::PhantomData }
218 }
219}
220impl<T, M> Unmark for Marked<T, M> {
221 type Unmarked = T;
222 fn unmark(self) -> Self::Unmarked {
223 self.value
224 }
225}
226impl<'a, T, M> Unmark for &'a Marked<T, M> {
227 type Unmarked = &'a T;
228 fn unmark(self) -> Self::Unmarked {
229 &self.value
230 }
231}
232impl<'a, T, M> Unmark for &'a mut Marked<T, M> {
233 type Unmarked = &'a mut T;
234 fn unmark(self) -> Self::Unmarked {
235 &mut self.value
236 }
237}
238
239impl<T: Mark> Mark for Vec<T> {
240 type Unmarked = Vec<T::Unmarked>;
241 fn mark(unmarked: Self::Unmarked) -> Self {
242 unmarked.into_iter().map(T::mark).collect()
244 }
245}
246impl<T: Unmark> Unmark for Vec<T> {
247 type Unmarked = Vec<T::Unmarked>;
248 fn unmark(self) -> Self::Unmarked {
249 self.into_iter().map(T::unmark).collect()
251 }
252}
253
254macro_rules! mark_noop {
255 ($($ty:ty),* $(,)?) => {
256 $(
257 impl Mark for $ty {
258 type Unmarked = Self;
259 fn mark(unmarked: Self::Unmarked) -> Self {
260 unmarked
261 }
262 }
263 impl Unmark for $ty {
264 type Unmarked = Self;
265 fn unmark(self) -> Self::Unmarked {
266 self
267 }
268 }
269 )*
270 }
271}
272mark_noop! {
273 (),
274 bool,
275 char,
276 &'_ [u8],
277 &'_ str,
278 String,
279 u8,
280 usize,
281 Delimiter,
282 LitKind,
283 Level,
284 Spacing,
285}
286
287rpc_encode_decode!(
288 enum Delimiter {
289 Parenthesis,
290 Brace,
291 Bracket,
292 None,
293 }
294);
295rpc_encode_decode!(
296 enum Level {
297 Error,
298 Warning,
299 Note,
300 Help,
301 }
302);
303rpc_encode_decode!(
304 enum Spacing {
305 Alone,
306 Joint,
307 }
308);
309
310#[derive(Copy, Clone, Eq, PartialEq, Debug)]
311pub enum LitKind {
312 Byte,
313 Char,
314 Integer,
315 Float,
316 Str,
317 StrRaw(u8),
318 ByteStr,
319 ByteStrRaw(u8),
320 CStr,
321 CStrRaw(u8),
322 ErrWithGuar,
327}
328
329rpc_encode_decode!(
330 enum LitKind {
331 Byte,
332 Char,
333 Integer,
334 Float,
335 Str,
336 StrRaw(n),
337 ByteStr,
338 ByteStrRaw(n),
339 CStr,
340 CStrRaw(n),
341 ErrWithGuar,
342 }
343);
344
345macro_rules! mark_compound {
346 (struct $name:ident <$($T:ident),+> { $($field:ident),* $(,)? }) => {
347 impl<$($T: Mark),+> Mark for $name <$($T),+> {
348 type Unmarked = $name <$($T::Unmarked),+>;
349 fn mark(unmarked: Self::Unmarked) -> Self {
350 $name {
351 $($field: Mark::mark(unmarked.$field)),*
352 }
353 }
354 }
355
356 impl<$($T: Unmark),+> Unmark for $name <$($T),+> {
357 type Unmarked = $name <$($T::Unmarked),+>;
358 fn unmark(self) -> Self::Unmarked {
359 $name {
360 $($field: Unmark::unmark(self.$field)),*
361 }
362 }
363 }
364 };
365 (enum $name:ident <$($T:ident),+> { $($variant:ident $(($field:ident))?),* $(,)? }) => {
366 impl<$($T: Mark),+> Mark for $name <$($T),+> {
367 type Unmarked = $name <$($T::Unmarked),+>;
368 fn mark(unmarked: Self::Unmarked) -> Self {
369 match unmarked {
370 $($name::$variant $(($field))? => {
371 $name::$variant $((Mark::mark($field)))?
372 })*
373 }
374 }
375 }
376
377 impl<$($T: Unmark),+> Unmark for $name <$($T),+> {
378 type Unmarked = $name <$($T::Unmarked),+>;
379 fn unmark(self) -> Self::Unmarked {
380 match self {
381 $($name::$variant $(($field))? => {
382 $name::$variant $((Unmark::unmark($field)))?
383 })*
384 }
385 }
386 }
387 }
388}
389
390macro_rules! compound_traits {
391 ($($t:tt)*) => {
392 rpc_encode_decode!($($t)*);
393 mark_compound!($($t)*);
394 };
395}
396
397compound_traits!(
398 enum Bound<T> {
399 Included(x),
400 Excluded(x),
401 Unbounded,
402 }
403);
404
405compound_traits!(
406 enum Option<T> {
407 Some(t),
408 None,
409 }
410);
411
412compound_traits!(
413 enum Result<T, E> {
414 Ok(t),
415 Err(e),
416 }
417);
418
419#[derive(Copy, Clone)]
420pub struct DelimSpan<Span> {
421 pub open: Span,
422 pub close: Span,
423 pub entire: Span,
424}
425
426impl<Span: Copy> DelimSpan<Span> {
427 pub fn from_single(span: Span) -> Self {
428 DelimSpan { open: span, close: span, entire: span }
429 }
430}
431
432compound_traits!(struct DelimSpan<Span> { open, close, entire });
433
434#[derive(Clone)]
435pub struct Group<TokenStream, Span> {
436 pub delimiter: Delimiter,
437 pub stream: Option<TokenStream>,
438 pub span: DelimSpan<Span>,
439}
440
441compound_traits!(struct Group<TokenStream, Span> { delimiter, stream, span });
442
443#[derive(Clone)]
444pub struct Punct<Span> {
445 pub ch: u8,
446 pub joint: bool,
447 pub span: Span,
448}
449
450compound_traits!(struct Punct<Span> { ch, joint, span });
451
452#[derive(Copy, Clone, Eq, PartialEq)]
453pub struct Ident<Span, Symbol> {
454 pub sym: Symbol,
455 pub is_raw: bool,
456 pub span: Span,
457}
458
459compound_traits!(struct Ident<Span, Symbol> { sym, is_raw, span });
460
461#[derive(Clone, Eq, PartialEq)]
462pub struct Literal<Span, Symbol> {
463 pub kind: LitKind,
464 pub symbol: Symbol,
465 pub suffix: Option<Symbol>,
466 pub span: Span,
467}
468
469compound_traits!(struct Literal<Sp, Sy> { kind, symbol, suffix, span });
470
471#[derive(Clone)]
472pub enum TokenTree<TokenStream, Span, Symbol> {
473 Group(Group<TokenStream, Span>),
474 Punct(Punct<Span>),
475 Ident(Ident<Span, Symbol>),
476 Literal(Literal<Span, Symbol>),
477}
478
479compound_traits!(
480 enum TokenTree<TokenStream, Span, Symbol> {
481 Group(tt),
482 Punct(tt),
483 Ident(tt),
484 Literal(tt),
485 }
486);
487
488#[derive(Clone, Debug)]
489pub struct Diagnostic<Span> {
490 pub level: Level,
491 pub message: String,
492 pub spans: Vec<Span>,
493 pub children: Vec<Diagnostic<Span>>,
494}
495
496compound_traits!(
497 struct Diagnostic<Span> { level, message, spans, children }
498);
499
500#[derive(Clone)]
503pub struct ExpnGlobals<Span> {
504 pub def_site: Span,
505 pub call_site: Span,
506 pub mixed_site: Span,
507}
508
509compound_traits!(
510 struct ExpnGlobals<Span> { def_site, call_site, mixed_site }
511);
512
513compound_traits!(
514 struct Range<T> { start, end }
515);