mirror of
https://github.com/rust-lang/rust.git
synced 2026-04-27 18:57:42 +03:00
Rollup merge of #151505 - bjorn3:proc_macro_refactors, r=petrochenkov,Kobzol
Various refactors to the proc_macro bridge This reduces the amount of types, traits and other abstractions that are involved with the bridge, which should make it easier to understand and modify. This should also help a bit with getting rid of the type marking hack, which is complicating the code a fair bit. Fixes: rust-lang/rust#139810
This commit is contained in:
@@ -431,8 +431,6 @@ fn to_internal(self) -> rustc_errors::Level {
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) struct FreeFunctions;
|
||||
|
||||
pub(crate) struct Rustc<'a, 'b> {
|
||||
ecx: &'a mut ExtCtxt<'b>,
|
||||
def_site: Span,
|
||||
@@ -461,13 +459,28 @@ fn psess(&self) -> &ParseSess {
|
||||
}
|
||||
|
||||
impl server::Types for Rustc<'_, '_> {
|
||||
type FreeFunctions = FreeFunctions;
|
||||
type TokenStream = TokenStream;
|
||||
type Span = Span;
|
||||
type Symbol = Symbol;
|
||||
}
|
||||
|
||||
impl server::FreeFunctions for Rustc<'_, '_> {
|
||||
impl server::Server for Rustc<'_, '_> {
|
||||
fn globals(&mut self) -> ExpnGlobals<Self::Span> {
|
||||
ExpnGlobals {
|
||||
def_site: self.def_site,
|
||||
call_site: self.call_site,
|
||||
mixed_site: self.mixed_site,
|
||||
}
|
||||
}
|
||||
|
||||
fn intern_symbol(string: &str) -> Self::Symbol {
|
||||
Symbol::intern(string)
|
||||
}
|
||||
|
||||
fn with_symbol_string(symbol: &Self::Symbol, f: impl FnOnce(&str)) {
|
||||
f(symbol.as_str())
|
||||
}
|
||||
|
||||
fn injected_env_var(&mut self, var: &str) -> Option<String> {
|
||||
self.ecx.sess.opts.logical_env.get(var).cloned()
|
||||
}
|
||||
@@ -552,14 +565,20 @@ fn emit_diagnostic(&mut self, diagnostic: Diagnostic<Self::Span>) {
|
||||
}
|
||||
diag.emit();
|
||||
}
|
||||
}
|
||||
|
||||
impl server::TokenStream for Rustc<'_, '_> {
|
||||
fn is_empty(&mut self, stream: &Self::TokenStream) -> bool {
|
||||
fn ts_drop(&mut self, stream: Self::TokenStream) {
|
||||
drop(stream);
|
||||
}
|
||||
|
||||
fn ts_clone(&mut self, stream: &Self::TokenStream) -> Self::TokenStream {
|
||||
stream.clone()
|
||||
}
|
||||
|
||||
fn ts_is_empty(&mut self, stream: &Self::TokenStream) -> bool {
|
||||
stream.is_empty()
|
||||
}
|
||||
|
||||
fn from_str(&mut self, src: &str) -> Self::TokenStream {
|
||||
fn ts_from_str(&mut self, src: &str) -> Self::TokenStream {
|
||||
unwrap_or_emit_fatal(source_str_to_stream(
|
||||
self.psess(),
|
||||
FileName::proc_macro_source_code(src),
|
||||
@@ -568,11 +587,11 @@ fn from_str(&mut self, src: &str) -> Self::TokenStream {
|
||||
))
|
||||
}
|
||||
|
||||
fn to_string(&mut self, stream: &Self::TokenStream) -> String {
|
||||
fn ts_to_string(&mut self, stream: &Self::TokenStream) -> String {
|
||||
pprust::tts_to_string(stream)
|
||||
}
|
||||
|
||||
fn expand_expr(&mut self, stream: &Self::TokenStream) -> Result<Self::TokenStream, ()> {
|
||||
fn ts_expand_expr(&mut self, stream: &Self::TokenStream) -> Result<Self::TokenStream, ()> {
|
||||
// Parse the expression from our tokenstream.
|
||||
let expr: PResult<'_, _> = try {
|
||||
let mut p = Parser::new(self.psess(), stream.clone(), Some("proc_macro expand expr"));
|
||||
@@ -633,14 +652,14 @@ fn expand_expr(&mut self, stream: &Self::TokenStream) -> Result<Self::TokenStrea
|
||||
}
|
||||
}
|
||||
|
||||
fn from_token_tree(
|
||||
fn ts_from_token_tree(
|
||||
&mut self,
|
||||
tree: TokenTree<Self::TokenStream, Self::Span, Self::Symbol>,
|
||||
) -> Self::TokenStream {
|
||||
Self::TokenStream::new((tree, &mut *self).to_internal().into_iter().collect::<Vec<_>>())
|
||||
}
|
||||
|
||||
fn concat_trees(
|
||||
fn ts_concat_trees(
|
||||
&mut self,
|
||||
base: Option<Self::TokenStream>,
|
||||
trees: Vec<TokenTree<Self::TokenStream, Self::Span, Self::Symbol>>,
|
||||
@@ -654,7 +673,7 @@ fn concat_trees(
|
||||
stream
|
||||
}
|
||||
|
||||
fn concat_streams(
|
||||
fn ts_concat_streams(
|
||||
&mut self,
|
||||
base: Option<Self::TokenStream>,
|
||||
streams: Vec<Self::TokenStream>,
|
||||
@@ -666,16 +685,14 @@ fn concat_streams(
|
||||
stream
|
||||
}
|
||||
|
||||
fn into_trees(
|
||||
fn ts_into_trees(
|
||||
&mut self,
|
||||
stream: Self::TokenStream,
|
||||
) -> Vec<TokenTree<Self::TokenStream, Self::Span, Self::Symbol>> {
|
||||
FromInternal::from_internal((stream, self))
|
||||
}
|
||||
}
|
||||
|
||||
impl server::Span for Rustc<'_, '_> {
|
||||
fn debug(&mut self, span: Self::Span) -> String {
|
||||
fn span_debug(&mut self, span: Self::Span) -> String {
|
||||
if self.ecx.ecfg.span_debug {
|
||||
format!("{span:?}")
|
||||
} else {
|
||||
@@ -683,7 +700,7 @@ fn debug(&mut self, span: Self::Span) -> String {
|
||||
}
|
||||
}
|
||||
|
||||
fn file(&mut self, span: Self::Span) -> String {
|
||||
fn span_file(&mut self, span: Self::Span) -> String {
|
||||
self.psess()
|
||||
.source_map()
|
||||
.lookup_char_pos(span.lo())
|
||||
@@ -693,7 +710,7 @@ fn file(&mut self, span: Self::Span) -> String {
|
||||
.to_string()
|
||||
}
|
||||
|
||||
fn local_file(&mut self, span: Self::Span) -> Option<String> {
|
||||
fn span_local_file(&mut self, span: Self::Span) -> Option<String> {
|
||||
self.psess()
|
||||
.source_map()
|
||||
.lookup_char_pos(span.lo())
|
||||
@@ -708,15 +725,15 @@ fn local_file(&mut self, span: Self::Span) -> Option<String> {
|
||||
})
|
||||
}
|
||||
|
||||
fn parent(&mut self, span: Self::Span) -> Option<Self::Span> {
|
||||
fn span_parent(&mut self, span: Self::Span) -> Option<Self::Span> {
|
||||
span.parent_callsite()
|
||||
}
|
||||
|
||||
fn source(&mut self, span: Self::Span) -> Self::Span {
|
||||
fn span_source(&mut self, span: Self::Span) -> Self::Span {
|
||||
span.source_callsite()
|
||||
}
|
||||
|
||||
fn byte_range(&mut self, span: Self::Span) -> Range<usize> {
|
||||
fn span_byte_range(&mut self, span: Self::Span) -> Range<usize> {
|
||||
let source_map = self.psess().source_map();
|
||||
|
||||
let relative_start_pos = source_map.lookup_byte_offset(span.lo()).pos;
|
||||
@@ -724,25 +741,25 @@ fn byte_range(&mut self, span: Self::Span) -> Range<usize> {
|
||||
|
||||
Range { start: relative_start_pos.0 as usize, end: relative_end_pos.0 as usize }
|
||||
}
|
||||
fn start(&mut self, span: Self::Span) -> Self::Span {
|
||||
fn span_start(&mut self, span: Self::Span) -> Self::Span {
|
||||
span.shrink_to_lo()
|
||||
}
|
||||
|
||||
fn end(&mut self, span: Self::Span) -> Self::Span {
|
||||
fn span_end(&mut self, span: Self::Span) -> Self::Span {
|
||||
span.shrink_to_hi()
|
||||
}
|
||||
|
||||
fn line(&mut self, span: Self::Span) -> usize {
|
||||
fn span_line(&mut self, span: Self::Span) -> usize {
|
||||
let loc = self.psess().source_map().lookup_char_pos(span.lo());
|
||||
loc.line
|
||||
}
|
||||
|
||||
fn column(&mut self, span: Self::Span) -> usize {
|
||||
fn span_column(&mut self, span: Self::Span) -> usize {
|
||||
let loc = self.psess().source_map().lookup_char_pos(span.lo());
|
||||
loc.col.to_usize() + 1
|
||||
}
|
||||
|
||||
fn join(&mut self, first: Self::Span, second: Self::Span) -> Option<Self::Span> {
|
||||
fn span_join(&mut self, first: Self::Span, second: Self::Span) -> Option<Self::Span> {
|
||||
let self_loc = self.psess().source_map().lookup_char_pos(first.lo());
|
||||
let other_loc = self.psess().source_map().lookup_char_pos(second.lo());
|
||||
|
||||
@@ -753,7 +770,7 @@ fn join(&mut self, first: Self::Span, second: Self::Span) -> Option<Self::Span>
|
||||
Some(first.to(second))
|
||||
}
|
||||
|
||||
fn subspan(
|
||||
fn span_subspan(
|
||||
&mut self,
|
||||
span: Self::Span,
|
||||
start: Bound<usize>,
|
||||
@@ -789,11 +806,11 @@ fn subspan(
|
||||
Some(span.with_lo(new_lo).with_hi(new_hi))
|
||||
}
|
||||
|
||||
fn resolved_at(&mut self, span: Self::Span, at: Self::Span) -> Self::Span {
|
||||
fn span_resolved_at(&mut self, span: Self::Span, at: Self::Span) -> Self::Span {
|
||||
span.with_ctxt(at.ctxt())
|
||||
}
|
||||
|
||||
fn source_text(&mut self, span: Self::Span) -> Option<String> {
|
||||
fn span_source_text(&mut self, span: Self::Span) -> Option<String> {
|
||||
self.psess().source_map().span_to_snippet(span).ok()
|
||||
}
|
||||
|
||||
@@ -821,11 +838,11 @@ fn source_text(&mut self, span: Self::Span) -> Option<String> {
|
||||
/// span from the metadata of `my_proc_macro` (which we have access to,
|
||||
/// since we've loaded `my_proc_macro` from disk in order to execute it).
|
||||
/// In this way, we have obtained a span pointing into `my_proc_macro`
|
||||
fn save_span(&mut self, span: Self::Span) -> usize {
|
||||
fn span_save_span(&mut self, span: Self::Span) -> usize {
|
||||
self.psess().save_proc_macro_span(span)
|
||||
}
|
||||
|
||||
fn recover_proc_macro_span(&mut self, id: usize) -> Self::Span {
|
||||
fn span_recover_proc_macro_span(&mut self, id: usize) -> Self::Span {
|
||||
let (resolver, krate, def_site) = (&*self.ecx.resolver, self.krate, self.def_site);
|
||||
*self.rebased_spans.entry(id).or_insert_with(|| {
|
||||
// FIXME: `SyntaxContext` for spans from proc macro crates is lost during encoding,
|
||||
@@ -833,29 +850,9 @@ fn recover_proc_macro_span(&mut self, id: usize) -> Self::Span {
|
||||
resolver.get_proc_macro_quoted_span(krate, id).with_ctxt(def_site.ctxt())
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
impl server::Symbol for Rustc<'_, '_> {
|
||||
fn normalize_and_validate_ident(&mut self, string: &str) -> Result<Self::Symbol, ()> {
|
||||
fn symbol_normalize_and_validate_ident(&mut self, string: &str) -> Result<Self::Symbol, ()> {
|
||||
let sym = nfc_normalize(string);
|
||||
if rustc_lexer::is_ident(sym.as_str()) { Ok(sym) } else { Err(()) }
|
||||
}
|
||||
}
|
||||
|
||||
impl server::Server for Rustc<'_, '_> {
|
||||
fn globals(&mut self) -> ExpnGlobals<Self::Span> {
|
||||
ExpnGlobals {
|
||||
def_site: self.def_site,
|
||||
call_site: self.call_site,
|
||||
mixed_site: self.mixed_site,
|
||||
}
|
||||
}
|
||||
|
||||
fn intern_symbol(string: &str) -> Self::Symbol {
|
||||
Symbol::intern(string)
|
||||
}
|
||||
|
||||
fn with_symbol_string(symbol: &Self::Symbol, f: impl FnOnce(&str)) {
|
||||
f(symbol.as_str())
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,93 +6,66 @@
|
||||
|
||||
use super::*;
|
||||
|
||||
macro_rules! define_client_handles {
|
||||
(
|
||||
'owned: $($oty:ident,)*
|
||||
'interned: $($ity:ident,)*
|
||||
) => {
|
||||
#[repr(C)]
|
||||
#[allow(non_snake_case)]
|
||||
pub(super) struct HandleCounters {
|
||||
$(pub(super) $oty: AtomicU32,)*
|
||||
$(pub(super) $ity: AtomicU32,)*
|
||||
}
|
||||
#[repr(C)]
|
||||
pub(super) struct HandleCounters {
|
||||
pub(super) token_stream: AtomicU32,
|
||||
pub(super) span: AtomicU32,
|
||||
}
|
||||
|
||||
static COUNTERS: HandleCounters = HandleCounters {
|
||||
$($oty: AtomicU32::new(1),)*
|
||||
$($ity: AtomicU32::new(1),)*
|
||||
};
|
||||
static COUNTERS: HandleCounters =
|
||||
HandleCounters { token_stream: AtomicU32::new(1), span: AtomicU32::new(1) };
|
||||
|
||||
$(
|
||||
pub(crate) struct $oty {
|
||||
handle: handle::Handle,
|
||||
}
|
||||
pub(crate) struct TokenStream {
|
||||
handle: handle::Handle,
|
||||
}
|
||||
|
||||
impl !Send for $oty {}
|
||||
impl !Sync for $oty {}
|
||||
impl !Send for TokenStream {}
|
||||
impl !Sync for TokenStream {}
|
||||
|
||||
// Forward `Drop::drop` to the inherent `drop` method.
|
||||
impl Drop for $oty {
|
||||
fn drop(&mut self) {
|
||||
$oty {
|
||||
handle: self.handle,
|
||||
}.drop();
|
||||
}
|
||||
}
|
||||
|
||||
impl<S> Encode<S> for $oty {
|
||||
fn encode(self, w: &mut Writer, s: &mut S) {
|
||||
mem::ManuallyDrop::new(self).handle.encode(w, s);
|
||||
}
|
||||
}
|
||||
|
||||
impl<S> Encode<S> for &$oty {
|
||||
fn encode(self, w: &mut Writer, s: &mut S) {
|
||||
self.handle.encode(w, s);
|
||||
}
|
||||
}
|
||||
|
||||
impl<S> Encode<S> for &mut $oty {
|
||||
fn encode(self, w: &mut Writer, s: &mut S) {
|
||||
self.handle.encode(w, s);
|
||||
}
|
||||
}
|
||||
|
||||
impl<S> Decode<'_, '_, S> for $oty {
|
||||
fn decode(r: &mut Reader<'_>, s: &mut S) -> Self {
|
||||
$oty {
|
||||
handle: handle::Handle::decode(r, s),
|
||||
}
|
||||
}
|
||||
}
|
||||
)*
|
||||
|
||||
$(
|
||||
#[derive(Copy, Clone, PartialEq, Eq, Hash)]
|
||||
pub(crate) struct $ity {
|
||||
handle: handle::Handle,
|
||||
}
|
||||
|
||||
impl !Send for $ity {}
|
||||
impl !Sync for $ity {}
|
||||
|
||||
impl<S> Encode<S> for $ity {
|
||||
fn encode(self, w: &mut Writer, s: &mut S) {
|
||||
self.handle.encode(w, s);
|
||||
}
|
||||
}
|
||||
|
||||
impl<S> Decode<'_, '_, S> for $ity {
|
||||
fn decode(r: &mut Reader<'_>, s: &mut S) -> Self {
|
||||
$ity {
|
||||
handle: handle::Handle::decode(r, s),
|
||||
}
|
||||
}
|
||||
}
|
||||
)*
|
||||
// Forward `Drop::drop` to the inherent `drop` method.
|
||||
impl Drop for TokenStream {
|
||||
fn drop(&mut self) {
|
||||
Methods::ts_drop(TokenStream { handle: self.handle });
|
||||
}
|
||||
}
|
||||
|
||||
impl<S> Encode<S> for TokenStream {
|
||||
fn encode(self, w: &mut Writer, s: &mut S) {
|
||||
mem::ManuallyDrop::new(self).handle.encode(w, s);
|
||||
}
|
||||
}
|
||||
|
||||
impl<S> Encode<S> for &TokenStream {
|
||||
fn encode(self, w: &mut Writer, s: &mut S) {
|
||||
self.handle.encode(w, s);
|
||||
}
|
||||
}
|
||||
|
||||
impl<S> Decode<'_, '_, S> for TokenStream {
|
||||
fn decode(r: &mut Reader<'_>, s: &mut S) -> Self {
|
||||
TokenStream { handle: handle::Handle::decode(r, s) }
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, PartialEq, Eq, Hash)]
|
||||
pub(crate) struct Span {
|
||||
handle: handle::Handle,
|
||||
}
|
||||
|
||||
impl !Send for Span {}
|
||||
impl !Sync for Span {}
|
||||
|
||||
impl<S> Encode<S> for Span {
|
||||
fn encode(self, w: &mut Writer, s: &mut S) {
|
||||
self.handle.encode(w, s);
|
||||
}
|
||||
}
|
||||
|
||||
impl<S> Decode<'_, '_, S> for Span {
|
||||
fn decode(r: &mut Reader<'_>, s: &mut S) -> Self {
|
||||
Span { handle: handle::Handle::decode(r, s) }
|
||||
}
|
||||
}
|
||||
with_api_handle_types!(define_client_handles);
|
||||
|
||||
// FIXME(eddyb) generate these impls by pattern-matching on the
|
||||
// names of methods - also could use the presence of `fn drop`
|
||||
@@ -102,7 +75,7 @@ fn decode(r: &mut Reader<'_>, s: &mut S) -> Self {
|
||||
|
||||
impl Clone for TokenStream {
|
||||
fn clone(&self) -> Self {
|
||||
self.clone()
|
||||
Methods::ts_clone(self)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -122,23 +95,27 @@ pub(crate) fn mixed_site() -> Span {
|
||||
|
||||
impl fmt::Debug for Span {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
f.write_str(&self.debug())
|
||||
f.write_str(&Methods::span_debug(*self))
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) use super::Methods;
|
||||
pub(crate) use super::symbol::Symbol;
|
||||
|
||||
macro_rules! define_client_side {
|
||||
($($name:ident {
|
||||
$(fn $method:ident($($arg:ident: $arg_ty:ty),* $(,)?) $(-> $ret_ty:ty)?;)*
|
||||
}),* $(,)?) => {
|
||||
$(impl $name {
|
||||
(
|
||||
Methods {
|
||||
$(fn $method:ident($($arg:ident: $arg_ty:ty),* $(,)?) $(-> $ret_ty:ty)*;)*
|
||||
},
|
||||
$($name:ident),* $(,)?
|
||||
) => {
|
||||
impl Methods {
|
||||
$(pub(crate) fn $method($($arg: $arg_ty),*) $(-> $ret_ty)? {
|
||||
Bridge::with(|bridge| {
|
||||
let mut buf = bridge.cached_buffer.take();
|
||||
|
||||
buf.clear();
|
||||
api_tags::Method::$name(api_tags::$name::$method).encode(&mut buf, &mut ());
|
||||
api_tags::Method::$method.encode(&mut buf, &mut ());
|
||||
$($arg.encode(&mut buf, &mut ());)*
|
||||
|
||||
buf = bridge.dispatch.call(buf);
|
||||
@@ -150,7 +127,7 @@ macro_rules! define_client_side {
|
||||
r.unwrap_or_else(|e| panic::resume_unwind(e.into()))
|
||||
})
|
||||
})*
|
||||
})*
|
||||
}
|
||||
}
|
||||
}
|
||||
with_api!(self, self, define_client_side);
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
use std::collections::BTreeMap;
|
||||
use std::hash::Hash;
|
||||
use std::num::NonZero;
|
||||
use std::ops::{Index, IndexMut};
|
||||
use std::ops::Index;
|
||||
use std::sync::atomic::{AtomicU32, Ordering};
|
||||
|
||||
use super::fxhash::FxHashMap;
|
||||
@@ -47,12 +47,6 @@ fn index(&self, h: Handle) -> &T {
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> IndexMut<Handle> for OwnedStore<T> {
|
||||
fn index_mut(&mut self, h: Handle) -> &mut T {
|
||||
self.data.get_mut(&h).expect("use-after-free in `proc_macro` handle")
|
||||
}
|
||||
}
|
||||
|
||||
/// Like `OwnedStore`, but avoids storing any value more than once.
|
||||
pub(super) struct InternedStore<T: 'static> {
|
||||
owned: OwnedStore<T>,
|
||||
|
||||
@@ -21,14 +21,15 @@
|
||||
/// `with_api!(MySelf, my_self, my_macro)` expands to:
|
||||
/// ```rust,ignore (pseudo-code)
|
||||
/// my_macro! {
|
||||
/// // ...
|
||||
/// Literal {
|
||||
/// Methods {
|
||||
/// // ...
|
||||
/// fn character(ch: char) -> MySelf::Literal;
|
||||
/// fn lit_character(ch: char) -> MySelf::Literal;
|
||||
/// // ...
|
||||
/// fn span(my_self: &MySelf::Literal) -> MySelf::Span;
|
||||
/// fn set_span(my_self: &mut MySelf::Literal, span: MySelf::Span);
|
||||
/// fn lit_span(my_self: &MySelf::Literal) -> MySelf::Span;
|
||||
/// fn lit_set_span(my_self: &mut MySelf::Literal, span: MySelf::Span);
|
||||
/// },
|
||||
/// Literal,
|
||||
/// Span,
|
||||
/// // ...
|
||||
/// }
|
||||
/// ```
|
||||
@@ -48,77 +49,62 @@
|
||||
macro_rules! with_api {
|
||||
($S:ident, $self:ident, $m:ident) => {
|
||||
$m! {
|
||||
FreeFunctions {
|
||||
fn drop($self: $S::FreeFunctions);
|
||||
Methods {
|
||||
fn injected_env_var(var: &str) -> Option<String>;
|
||||
fn track_env_var(var: &str, value: Option<&str>);
|
||||
fn track_path(path: &str);
|
||||
fn literal_from_str(s: &str) -> Result<Literal<$S::Span, $S::Symbol>, ()>;
|
||||
fn emit_diagnostic(diagnostic: Diagnostic<$S::Span>);
|
||||
},
|
||||
TokenStream {
|
||||
fn drop($self: $S::TokenStream);
|
||||
fn clone($self: &$S::TokenStream) -> $S::TokenStream;
|
||||
fn is_empty($self: &$S::TokenStream) -> bool;
|
||||
fn expand_expr($self: &$S::TokenStream) -> Result<$S::TokenStream, ()>;
|
||||
fn from_str(src: &str) -> $S::TokenStream;
|
||||
fn to_string($self: &$S::TokenStream) -> String;
|
||||
fn from_token_tree(
|
||||
|
||||
fn ts_drop(stream: $S::TokenStream);
|
||||
fn ts_clone(stream: &$S::TokenStream) -> $S::TokenStream;
|
||||
fn ts_is_empty(stream: &$S::TokenStream) -> bool;
|
||||
fn ts_expand_expr(stream: &$S::TokenStream) -> Result<$S::TokenStream, ()>;
|
||||
fn ts_from_str(src: &str) -> $S::TokenStream;
|
||||
fn ts_to_string(stream: &$S::TokenStream) -> String;
|
||||
fn ts_from_token_tree(
|
||||
tree: TokenTree<$S::TokenStream, $S::Span, $S::Symbol>,
|
||||
) -> $S::TokenStream;
|
||||
fn concat_trees(
|
||||
fn ts_concat_trees(
|
||||
base: Option<$S::TokenStream>,
|
||||
trees: Vec<TokenTree<$S::TokenStream, $S::Span, $S::Symbol>>,
|
||||
) -> $S::TokenStream;
|
||||
fn concat_streams(
|
||||
fn ts_concat_streams(
|
||||
base: Option<$S::TokenStream>,
|
||||
streams: Vec<$S::TokenStream>,
|
||||
) -> $S::TokenStream;
|
||||
fn into_trees(
|
||||
$self: $S::TokenStream
|
||||
fn ts_into_trees(
|
||||
stream: $S::TokenStream
|
||||
) -> Vec<TokenTree<$S::TokenStream, $S::Span, $S::Symbol>>;
|
||||
},
|
||||
Span {
|
||||
fn debug($self: $S::Span) -> String;
|
||||
fn parent($self: $S::Span) -> Option<$S::Span>;
|
||||
fn source($self: $S::Span) -> $S::Span;
|
||||
fn byte_range($self: $S::Span) -> Range<usize>;
|
||||
fn start($self: $S::Span) -> $S::Span;
|
||||
fn end($self: $S::Span) -> $S::Span;
|
||||
fn line($self: $S::Span) -> usize;
|
||||
fn column($self: $S::Span) -> usize;
|
||||
fn file($self: $S::Span) -> String;
|
||||
fn local_file($self: $S::Span) -> Option<String>;
|
||||
fn join($self: $S::Span, other: $S::Span) -> Option<$S::Span>;
|
||||
fn subspan($self: $S::Span, start: Bound<usize>, end: Bound<usize>) -> Option<$S::Span>;
|
||||
fn resolved_at($self: $S::Span, at: $S::Span) -> $S::Span;
|
||||
fn source_text($self: $S::Span) -> Option<String>;
|
||||
fn save_span($self: $S::Span) -> usize;
|
||||
fn recover_proc_macro_span(id: usize) -> $S::Span;
|
||||
},
|
||||
Symbol {
|
||||
fn normalize_and_validate_ident(string: &str) -> Result<$S::Symbol, ()>;
|
||||
},
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
// Similar to `with_api`, but only lists the types requiring handles, and they
|
||||
// are divided into the two storage categories.
|
||||
macro_rules! with_api_handle_types {
|
||||
($m:ident) => {
|
||||
$m! {
|
||||
'owned:
|
||||
FreeFunctions,
|
||||
fn span_debug(span: $S::Span) -> String;
|
||||
fn span_parent(span: $S::Span) -> Option<$S::Span>;
|
||||
fn span_source(span: $S::Span) -> $S::Span;
|
||||
fn span_byte_range(span: $S::Span) -> Range<usize>;
|
||||
fn span_start(span: $S::Span) -> $S::Span;
|
||||
fn span_end(span: $S::Span) -> $S::Span;
|
||||
fn span_line(span: $S::Span) -> usize;
|
||||
fn span_column(span: $S::Span) -> usize;
|
||||
fn span_file(span: $S::Span) -> String;
|
||||
fn span_local_file(span: $S::Span) -> Option<String>;
|
||||
fn span_join(span: $S::Span, other: $S::Span) -> Option<$S::Span>;
|
||||
fn span_subspan(span: $S::Span, start: Bound<usize>, end: Bound<usize>) -> Option<$S::Span>;
|
||||
fn span_resolved_at(span: $S::Span, at: $S::Span) -> $S::Span;
|
||||
fn span_source_text(span: $S::Span) -> Option<String>;
|
||||
fn span_save_span(span: $S::Span) -> usize;
|
||||
fn span_recover_proc_macro_span(id: usize) -> $S::Span;
|
||||
|
||||
fn symbol_normalize_and_validate_ident(string: &str) -> Result<$S::Symbol, ()>;
|
||||
},
|
||||
TokenStream,
|
||||
|
||||
'interned:
|
||||
Span,
|
||||
// Symbol is handled manually
|
||||
Symbol,
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
pub(crate) struct Methods;
|
||||
|
||||
#[allow(unsafe_code)]
|
||||
mod arena;
|
||||
#[allow(unsafe_code)]
|
||||
@@ -171,20 +157,16 @@ mod api_tags {
|
||||
use super::rpc::{Decode, Encode, Reader, Writer};
|
||||
|
||||
macro_rules! declare_tags {
|
||||
($($name:ident {
|
||||
$(fn $method:ident($($arg:ident: $arg_ty:ty),* $(,)?) $(-> $ret_ty:ty)*;)*
|
||||
}),* $(,)?) => {
|
||||
$(
|
||||
pub(super) enum $name {
|
||||
$($method),*
|
||||
}
|
||||
rpc_encode_decode!(enum $name { $($method),* });
|
||||
)*
|
||||
|
||||
(
|
||||
Methods {
|
||||
$(fn $method:ident($($arg:ident: $arg_ty:ty),* $(,)?) $(-> $ret_ty:ty)*;)*
|
||||
},
|
||||
$($name:ident),* $(,)?
|
||||
) => {
|
||||
pub(super) enum Method {
|
||||
$($name($name)),*
|
||||
$($method),*
|
||||
}
|
||||
rpc_encode_decode!(enum Method { $($name(m)),* });
|
||||
rpc_encode_decode!(enum Method { $($method),* });
|
||||
}
|
||||
}
|
||||
with_api!(self, self, declare_tags);
|
||||
|
||||
@@ -5,108 +5,66 @@
|
||||
|
||||
use super::*;
|
||||
|
||||
macro_rules! define_server_handles {
|
||||
(
|
||||
'owned: $($oty:ident,)*
|
||||
'interned: $($ity:ident,)*
|
||||
) => {
|
||||
#[allow(non_snake_case)]
|
||||
pub(super) struct HandleStore<S: Types> {
|
||||
$($oty: handle::OwnedStore<S::$oty>,)*
|
||||
$($ity: handle::InternedStore<S::$ity>,)*
|
||||
pub(super) struct HandleStore<S: Types> {
|
||||
token_stream: handle::OwnedStore<Marked<S::TokenStream, client::TokenStream>>,
|
||||
span: handle::InternedStore<Marked<S::Span, client::Span>>,
|
||||
}
|
||||
|
||||
impl<S: Types> HandleStore<S> {
|
||||
fn new(handle_counters: &'static client::HandleCounters) -> Self {
|
||||
HandleStore {
|
||||
token_stream: handle::OwnedStore::new(&handle_counters.token_stream),
|
||||
span: handle::InternedStore::new(&handle_counters.span),
|
||||
}
|
||||
|
||||
impl<S: Types> HandleStore<S> {
|
||||
fn new(handle_counters: &'static client::HandleCounters) -> Self {
|
||||
HandleStore {
|
||||
$($oty: handle::OwnedStore::new(&handle_counters.$oty),)*
|
||||
$($ity: handle::InternedStore::new(&handle_counters.$ity),)*
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$(
|
||||
impl<S: Types> Encode<HandleStore<MarkedTypes<S>>> for Marked<S::$oty, client::$oty> {
|
||||
fn encode(self, w: &mut Writer, s: &mut HandleStore<MarkedTypes<S>>) {
|
||||
s.$oty.alloc(self).encode(w, s);
|
||||
}
|
||||
}
|
||||
|
||||
impl<S: Types> Decode<'_, '_, HandleStore<MarkedTypes<S>>>
|
||||
for Marked<S::$oty, client::$oty>
|
||||
{
|
||||
fn decode(r: &mut Reader<'_>, s: &mut HandleStore<MarkedTypes<S>>) -> Self {
|
||||
s.$oty.take(handle::Handle::decode(r, &mut ()))
|
||||
}
|
||||
}
|
||||
|
||||
impl<'s, S: Types> Decode<'_, 's, HandleStore<MarkedTypes<S>>>
|
||||
for &'s Marked<S::$oty, client::$oty>
|
||||
{
|
||||
fn decode(r: &mut Reader<'_>, s: &'s mut HandleStore<MarkedTypes<S>>) -> Self {
|
||||
&s.$oty[handle::Handle::decode(r, &mut ())]
|
||||
}
|
||||
}
|
||||
|
||||
impl<'s, S: Types> Decode<'_, 's, HandleStore<MarkedTypes<S>>>
|
||||
for &'s mut Marked<S::$oty, client::$oty>
|
||||
{
|
||||
fn decode(
|
||||
r: &mut Reader<'_>,
|
||||
s: &'s mut HandleStore<MarkedTypes<S>>
|
||||
) -> Self {
|
||||
&mut s.$oty[handle::Handle::decode(r, &mut ())]
|
||||
}
|
||||
}
|
||||
)*
|
||||
|
||||
$(
|
||||
impl<S: Types> Encode<HandleStore<MarkedTypes<S>>> for Marked<S::$ity, client::$ity> {
|
||||
fn encode(self, w: &mut Writer, s: &mut HandleStore<MarkedTypes<S>>) {
|
||||
s.$ity.alloc(self).encode(w, s);
|
||||
}
|
||||
}
|
||||
|
||||
impl<S: Types> Decode<'_, '_, HandleStore<MarkedTypes<S>>>
|
||||
for Marked<S::$ity, client::$ity>
|
||||
{
|
||||
fn decode(r: &mut Reader<'_>, s: &mut HandleStore<MarkedTypes<S>>) -> Self {
|
||||
s.$ity.copy(handle::Handle::decode(r, &mut ()))
|
||||
}
|
||||
}
|
||||
)*
|
||||
}
|
||||
}
|
||||
with_api_handle_types!(define_server_handles);
|
||||
|
||||
impl<S: Types> Encode<HandleStore<S>> for Marked<S::TokenStream, client::TokenStream> {
|
||||
fn encode(self, w: &mut Writer, s: &mut HandleStore<S>) {
|
||||
s.token_stream.alloc(self).encode(w, s);
|
||||
}
|
||||
}
|
||||
|
||||
impl<S: Types> Decode<'_, '_, HandleStore<S>> for Marked<S::TokenStream, client::TokenStream> {
|
||||
fn decode(r: &mut Reader<'_>, s: &mut HandleStore<S>) -> Self {
|
||||
s.token_stream.take(handle::Handle::decode(r, &mut ()))
|
||||
}
|
||||
}
|
||||
|
||||
impl<'s, S: Types> Decode<'_, 's, HandleStore<S>>
|
||||
for &'s Marked<S::TokenStream, client::TokenStream>
|
||||
{
|
||||
fn decode(r: &mut Reader<'_>, s: &'s mut HandleStore<S>) -> Self {
|
||||
&s.token_stream[handle::Handle::decode(r, &mut ())]
|
||||
}
|
||||
}
|
||||
|
||||
impl<S: Types> Encode<HandleStore<S>> for Marked<S::Span, client::Span> {
|
||||
fn encode(self, w: &mut Writer, s: &mut HandleStore<S>) {
|
||||
s.span.alloc(self).encode(w, s);
|
||||
}
|
||||
}
|
||||
|
||||
impl<S: Types> Decode<'_, '_, HandleStore<S>> for Marked<S::Span, client::Span> {
|
||||
fn decode(r: &mut Reader<'_>, s: &mut HandleStore<S>) -> Self {
|
||||
s.span.copy(handle::Handle::decode(r, &mut ()))
|
||||
}
|
||||
}
|
||||
|
||||
pub trait Types {
|
||||
type FreeFunctions: 'static;
|
||||
type TokenStream: 'static + Clone;
|
||||
type Span: 'static + Copy + Eq + Hash;
|
||||
type Symbol: 'static;
|
||||
}
|
||||
|
||||
/// Declare an associated fn of one of the traits below, adding necessary
|
||||
/// default bodies.
|
||||
macro_rules! associated_fn {
|
||||
(fn drop(&mut self, $arg:ident: $arg_ty:ty)) =>
|
||||
(fn drop(&mut self, $arg: $arg_ty) { mem::drop($arg) });
|
||||
|
||||
(fn clone(&mut self, $arg:ident: $arg_ty:ty) -> $ret_ty:ty) =>
|
||||
(fn clone(&mut self, $arg: $arg_ty) -> $ret_ty { $arg.clone() });
|
||||
|
||||
($($item:tt)*) => ($($item)*;)
|
||||
}
|
||||
|
||||
macro_rules! declare_server_traits {
|
||||
($($name:ident {
|
||||
$(fn $method:ident($($arg:ident: $arg_ty:ty),* $(,)?) $(-> $ret_ty:ty)?;)*
|
||||
}),* $(,)?) => {
|
||||
$(pub trait $name: Types {
|
||||
$(associated_fn!(fn $method(&mut self, $($arg: $arg_ty),*) $(-> $ret_ty)?);)*
|
||||
})*
|
||||
|
||||
pub trait Server: Types $(+ $name)* {
|
||||
(
|
||||
Methods {
|
||||
$(fn $method:ident($($arg:ident: $arg_ty:ty),* $(,)?) $(-> $ret_ty:ty)*;)*
|
||||
},
|
||||
$($name:ident),* $(,)?
|
||||
) => {
|
||||
pub trait Server: Types {
|
||||
fn globals(&mut self) -> ExpnGlobals<Self::Span>;
|
||||
|
||||
/// Intern a symbol received from RPC
|
||||
@@ -114,51 +72,25 @@ pub trait Server: Types $(+ $name)* {
|
||||
|
||||
/// Recover the string value of a symbol, and invoke a callback with it.
|
||||
fn with_symbol_string(symbol: &Self::Symbol, f: impl FnOnce(&str));
|
||||
|
||||
$(fn $method(&mut self, $($arg: $arg_ty),*) $(-> $ret_ty)?;)*
|
||||
}
|
||||
}
|
||||
}
|
||||
with_api!(Self, self_, declare_server_traits);
|
||||
|
||||
pub(super) struct MarkedTypes<S: Types>(S);
|
||||
|
||||
impl<S: Server> Server for MarkedTypes<S> {
|
||||
fn globals(&mut self) -> ExpnGlobals<Self::Span> {
|
||||
<_>::mark(Server::globals(&mut self.0))
|
||||
}
|
||||
fn intern_symbol(ident: &str) -> Self::Symbol {
|
||||
<_>::mark(S::intern_symbol(ident))
|
||||
}
|
||||
fn with_symbol_string(symbol: &Self::Symbol, f: impl FnOnce(&str)) {
|
||||
S::with_symbol_string(symbol.unmark(), f)
|
||||
}
|
||||
}
|
||||
|
||||
macro_rules! define_mark_types_impls {
|
||||
($($name:ident {
|
||||
$(fn $method:ident($($arg:ident: $arg_ty:ty),* $(,)?) $(-> $ret_ty:ty)?;)*
|
||||
}),* $(,)?) => {
|
||||
impl<S: Types> Types for MarkedTypes<S> {
|
||||
$(type $name = Marked<S::$name, client::$name>;)*
|
||||
}
|
||||
|
||||
$(impl<S: $name> $name for MarkedTypes<S> {
|
||||
$(fn $method(&mut self, $($arg: $arg_ty),*) $(-> $ret_ty)? {
|
||||
<_>::mark($name::$method(&mut self.0, $($arg.unmark()),*))
|
||||
})*
|
||||
})*
|
||||
}
|
||||
}
|
||||
with_api!(Self, self_, define_mark_types_impls);
|
||||
|
||||
struct Dispatcher<S: Types> {
|
||||
handle_store: HandleStore<S>,
|
||||
server: S,
|
||||
}
|
||||
|
||||
macro_rules! define_dispatcher_impl {
|
||||
($($name:ident {
|
||||
$(fn $method:ident($($arg:ident: $arg_ty:ty),* $(,)?) $(-> $ret_ty:ty)?;)*
|
||||
}),* $(,)?) => {
|
||||
(
|
||||
Methods {
|
||||
$(fn $method:ident($($arg:ident: $arg_ty:ty),* $(,)?) $(-> $ret_ty:ty)*;)*
|
||||
},
|
||||
$($name:ident),* $(,)?
|
||||
) => {
|
||||
// FIXME(eddyb) `pub` only for `ExecutionStrategy` below.
|
||||
pub trait DispatcherTrait {
|
||||
// HACK(eddyb) these are here to allow `Self::$name` to work below.
|
||||
@@ -167,35 +99,37 @@ pub trait DispatcherTrait {
|
||||
fn dispatch(&mut self, buf: Buffer) -> Buffer;
|
||||
}
|
||||
|
||||
impl<S: Server> DispatcherTrait for Dispatcher<MarkedTypes<S>> {
|
||||
$(type $name = <MarkedTypes<S> as Types>::$name;)*
|
||||
impl<S: Server> DispatcherTrait for Dispatcher<S> {
|
||||
$(type $name = Marked<S::$name, client::$name>;)*
|
||||
|
||||
fn dispatch(&mut self, mut buf: Buffer) -> Buffer {
|
||||
let Dispatcher { handle_store, server } = self;
|
||||
|
||||
let mut reader = &buf[..];
|
||||
match api_tags::Method::decode(&mut reader, &mut ()) {
|
||||
$(api_tags::Method::$name(m) => match m {
|
||||
$(api_tags::$name::$method => {
|
||||
let mut call_method = || {
|
||||
$(let $arg = <$arg_ty>::decode(&mut reader, handle_store);)*
|
||||
$name::$method(server, $($arg),*)
|
||||
};
|
||||
// HACK(eddyb) don't use `panic::catch_unwind` in a panic.
|
||||
// If client and server happen to use the same `std`,
|
||||
// `catch_unwind` asserts that the panic counter was 0,
|
||||
// even when the closure passed to it didn't panic.
|
||||
let r = if thread::panicking() {
|
||||
Ok(call_method())
|
||||
} else {
|
||||
panic::catch_unwind(panic::AssertUnwindSafe(call_method))
|
||||
.map_err(PanicMessage::from)
|
||||
};
|
||||
$(api_tags::Method::$method => {
|
||||
let mut call_method = || {
|
||||
$(let $arg = <$arg_ty>::decode(&mut reader, handle_store).unmark();)*
|
||||
let r = server.$method($($arg),*);
|
||||
$(
|
||||
let r: $ret_ty = Mark::mark(r);
|
||||
)*
|
||||
r
|
||||
};
|
||||
// HACK(eddyb) don't use `panic::catch_unwind` in a panic.
|
||||
// If client and server happen to use the same `std`,
|
||||
// `catch_unwind` asserts that the panic counter was 0,
|
||||
// even when the closure passed to it didn't panic.
|
||||
let r = if thread::panicking() {
|
||||
Ok(call_method())
|
||||
} else {
|
||||
panic::catch_unwind(panic::AssertUnwindSafe(call_method))
|
||||
.map_err(PanicMessage::from)
|
||||
};
|
||||
|
||||
buf.clear();
|
||||
r.encode(&mut buf, handle_store);
|
||||
})*
|
||||
}),*
|
||||
buf.clear();
|
||||
r.encode(&mut buf, handle_store);
|
||||
})*
|
||||
}
|
||||
buf
|
||||
}
|
||||
@@ -354,8 +288,8 @@ pub trait MessagePipe<T>: Sized {
|
||||
|
||||
fn run_server<
|
||||
S: Server,
|
||||
I: Encode<HandleStore<MarkedTypes<S>>>,
|
||||
O: for<'a, 's> Decode<'a, 's, HandleStore<MarkedTypes<S>>>,
|
||||
I: Encode<HandleStore<S>>,
|
||||
O: for<'a, 's> Decode<'a, 's, HandleStore<S>>,
|
||||
>(
|
||||
strategy: &impl ExecutionStrategy,
|
||||
handle_counters: &'static client::HandleCounters,
|
||||
@@ -364,13 +298,13 @@ fn run_server<
|
||||
run_client: extern "C" fn(BridgeConfig<'_>) -> Buffer,
|
||||
force_show_panics: bool,
|
||||
) -> Result<O, PanicMessage> {
|
||||
let mut dispatcher =
|
||||
Dispatcher { handle_store: HandleStore::new(handle_counters), server: MarkedTypes(server) };
|
||||
let mut dispatcher = Dispatcher { handle_store: HandleStore::new(handle_counters), server };
|
||||
|
||||
let globals = dispatcher.server.globals();
|
||||
|
||||
let mut buf = Buffer::new();
|
||||
(globals, input).encode(&mut buf, &mut dispatcher.handle_store);
|
||||
(<ExpnGlobals<Marked<S::Span, client::Span>> as Mark>::mark(globals), input)
|
||||
.encode(&mut buf, &mut dispatcher.handle_store);
|
||||
|
||||
buf = strategy.run_bridge_and_client(&mut dispatcher, buf, run_client, force_show_panics);
|
||||
|
||||
@@ -394,11 +328,13 @@ pub fn run<S>(
|
||||
strategy,
|
||||
handle_counters,
|
||||
server,
|
||||
<MarkedTypes<S> as Types>::TokenStream::mark(input),
|
||||
<Marked<S::TokenStream, client::TokenStream>>::mark(input),
|
||||
run,
|
||||
force_show_panics,
|
||||
)
|
||||
.map(|s| <Option<<MarkedTypes<S> as Types>::TokenStream>>::unmark(s).unwrap_or_default())
|
||||
.map(|s| {
|
||||
<Option<Marked<S::TokenStream, client::TokenStream>>>::unmark(s).unwrap_or_default()
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
@@ -421,12 +357,14 @@ pub fn run<S>(
|
||||
handle_counters,
|
||||
server,
|
||||
(
|
||||
<MarkedTypes<S> as Types>::TokenStream::mark(input),
|
||||
<MarkedTypes<S> as Types>::TokenStream::mark(input2),
|
||||
<Marked<S::TokenStream, client::TokenStream>>::mark(input),
|
||||
<Marked<S::TokenStream, client::TokenStream>>::mark(input2),
|
||||
),
|
||||
run,
|
||||
force_show_panics,
|
||||
)
|
||||
.map(|s| <Option<<MarkedTypes<S> as Types>::TokenStream>>::unmark(s).unwrap_or_default())
|
||||
.map(|s| {
|
||||
<Option<Marked<S::TokenStream, client::TokenStream>>>::unmark(s).unwrap_or_default()
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
@@ -46,7 +46,7 @@ pub(crate) fn new_ident(string: &str, is_raw: bool) -> Self {
|
||||
if string.is_ascii() {
|
||||
Err(())
|
||||
} else {
|
||||
client::Symbol::normalize_and_validate_ident(string)
|
||||
client::Methods::symbol_normalize_and_validate_ident(string)
|
||||
}
|
||||
.unwrap_or_else(|_| panic!("`{:?}` is not a valid identifier", string))
|
||||
}
|
||||
@@ -99,18 +99,14 @@ fn encode(self, w: &mut Writer, s: &mut S) {
|
||||
}
|
||||
}
|
||||
|
||||
impl<S: server::Server> Decode<'_, '_, server::HandleStore<server::MarkedTypes<S>>>
|
||||
for Marked<S::Symbol, Symbol>
|
||||
{
|
||||
fn decode(r: &mut Reader<'_>, s: &mut server::HandleStore<server::MarkedTypes<S>>) -> Self {
|
||||
impl<S: server::Server> Decode<'_, '_, server::HandleStore<S>> for Marked<S::Symbol, Symbol> {
|
||||
fn decode(r: &mut Reader<'_>, s: &mut server::HandleStore<S>) -> Self {
|
||||
Mark::mark(S::intern_symbol(<&str>::decode(r, s)))
|
||||
}
|
||||
}
|
||||
|
||||
impl<S: server::Server> Encode<server::HandleStore<server::MarkedTypes<S>>>
|
||||
for Marked<S::Symbol, Symbol>
|
||||
{
|
||||
fn encode(self, w: &mut Writer, s: &mut server::HandleStore<server::MarkedTypes<S>>) {
|
||||
impl<S: server::Server> Encode<server::HandleStore<S>> for Marked<S::Symbol, Symbol> {
|
||||
fn encode(self, w: &mut Writer, s: &mut server::HandleStore<S>) {
|
||||
S::with_symbol_string(&self.unmark(), |sym| sym.encode(w, s))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -170,6 +170,6 @@ fn to_internal(diag: Diagnostic) -> crate::bridge::Diagnostic<crate::bridge::cli
|
||||
}
|
||||
}
|
||||
|
||||
crate::bridge::client::FreeFunctions::emit_diagnostic(to_internal(self));
|
||||
crate::bridge::client::Methods::emit_diagnostic(to_internal(self));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -58,6 +58,7 @@
|
||||
#[unstable(feature = "proc_macro_totokens", issue = "130977")]
|
||||
pub use to_tokens::ToTokens;
|
||||
|
||||
use crate::bridge::client::Methods as BridgeMethods;
|
||||
use crate::escape::{EscapeOptions, escape_bytes};
|
||||
|
||||
/// Errors returned when trying to retrieve a literal unescaped value.
|
||||
@@ -158,7 +159,7 @@ pub fn new() -> TokenStream {
|
||||
/// Checks if this `TokenStream` is empty.
|
||||
#[stable(feature = "proc_macro_lib2", since = "1.29.0")]
|
||||
pub fn is_empty(&self) -> bool {
|
||||
self.0.as_ref().map(|h| h.is_empty()).unwrap_or(true)
|
||||
self.0.as_ref().map(|h| BridgeMethods::ts_is_empty(h)).unwrap_or(true)
|
||||
}
|
||||
|
||||
/// Parses this `TokenStream` as an expression and attempts to expand any
|
||||
@@ -174,7 +175,7 @@ pub fn is_empty(&self) -> bool {
|
||||
#[unstable(feature = "proc_macro_expand", issue = "90765")]
|
||||
pub fn expand_expr(&self) -> Result<TokenStream, ExpandError> {
|
||||
let stream = self.0.as_ref().ok_or(ExpandError)?;
|
||||
match bridge::client::TokenStream::expand_expr(stream) {
|
||||
match BridgeMethods::ts_expand_expr(stream) {
|
||||
Ok(stream) => Ok(TokenStream(Some(stream))),
|
||||
Err(_) => Err(ExpandError),
|
||||
}
|
||||
@@ -193,7 +194,7 @@ impl FromStr for TokenStream {
|
||||
type Err = LexError;
|
||||
|
||||
fn from_str(src: &str) -> Result<TokenStream, LexError> {
|
||||
Ok(TokenStream(Some(bridge::client::TokenStream::from_str(src))))
|
||||
Ok(TokenStream(Some(BridgeMethods::ts_from_str(src))))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -212,7 +213,7 @@ fn from_str(src: &str) -> Result<TokenStream, LexError> {
|
||||
impl fmt::Display for TokenStream {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
match &self.0 {
|
||||
Some(ts) => write!(f, "{}", ts.to_string()),
|
||||
Some(ts) => write!(f, "{}", BridgeMethods::ts_to_string(ts)),
|
||||
None => Ok(()),
|
||||
}
|
||||
}
|
||||
@@ -252,7 +253,7 @@ fn tree_to_bridge_tree(
|
||||
#[stable(feature = "proc_macro_lib2", since = "1.29.0")]
|
||||
impl From<TokenTree> for TokenStream {
|
||||
fn from(tree: TokenTree) -> TokenStream {
|
||||
TokenStream(Some(bridge::client::TokenStream::from_token_tree(tree_to_bridge_tree(tree))))
|
||||
TokenStream(Some(BridgeMethods::ts_from_token_tree(tree_to_bridge_tree(tree))))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -281,7 +282,7 @@ fn build(self) -> TokenStream {
|
||||
if self.trees.is_empty() {
|
||||
TokenStream(None)
|
||||
} else {
|
||||
TokenStream(Some(bridge::client::TokenStream::concat_trees(None, self.trees)))
|
||||
TokenStream(Some(BridgeMethods::ts_concat_trees(None, self.trees)))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -289,7 +290,7 @@ fn append_to(self, stream: &mut TokenStream) {
|
||||
if self.trees.is_empty() {
|
||||
return;
|
||||
}
|
||||
stream.0 = Some(bridge::client::TokenStream::concat_trees(stream.0.take(), self.trees))
|
||||
stream.0 = Some(BridgeMethods::ts_concat_trees(stream.0.take(), self.trees))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -314,7 +315,7 @@ fn build(mut self) -> TokenStream {
|
||||
if self.streams.len() <= 1 {
|
||||
TokenStream(self.streams.pop())
|
||||
} else {
|
||||
TokenStream(Some(bridge::client::TokenStream::concat_streams(None, self.streams)))
|
||||
TokenStream(Some(BridgeMethods::ts_concat_streams(None, self.streams)))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -326,7 +327,7 @@ fn append_to(mut self, stream: &mut TokenStream) {
|
||||
if base.is_none() && self.streams.len() == 1 {
|
||||
stream.0 = self.streams.pop();
|
||||
} else {
|
||||
stream.0 = Some(bridge::client::TokenStream::concat_streams(base, self.streams));
|
||||
stream.0 = Some(BridgeMethods::ts_concat_streams(base, self.streams));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -377,7 +378,7 @@ fn extend<I: IntoIterator<Item = TokenStream>>(&mut self, streams: I) {
|
||||
macro_rules! extend_items {
|
||||
($($item:ident)*) => {
|
||||
$(
|
||||
#[stable(feature = "token_stream_extend_tt_items", since = "1.92.0")]
|
||||
#[stable(feature = "token_stream_extend_ts_items", since = "1.92.0")]
|
||||
impl Extend<$item> for TokenStream {
|
||||
fn extend<T: IntoIterator<Item = $item>>(&mut self, iter: T) {
|
||||
self.extend(iter.into_iter().map(TokenTree::$item));
|
||||
@@ -392,7 +393,7 @@ fn extend<T: IntoIterator<Item = $item>>(&mut self, iter: T) {
|
||||
/// Public implementation details for the `TokenStream` type, such as iterators.
|
||||
#[stable(feature = "proc_macro_lib2", since = "1.29.0")]
|
||||
pub mod token_stream {
|
||||
use crate::{Group, Ident, Literal, Punct, TokenStream, TokenTree, bridge};
|
||||
use crate::{BridgeMethods, Group, Ident, Literal, Punct, TokenStream, TokenTree, bridge};
|
||||
|
||||
/// An iterator over `TokenStream`'s `TokenTree`s.
|
||||
/// The iteration is "shallow", e.g., the iterator doesn't recurse into delimited groups,
|
||||
@@ -437,7 +438,9 @@ impl IntoIterator for TokenStream {
|
||||
type IntoIter = IntoIter;
|
||||
|
||||
fn into_iter(self) -> IntoIter {
|
||||
IntoIter(self.0.map(|v| v.into_trees()).unwrap_or_default().into_iter())
|
||||
IntoIter(
|
||||
self.0.map(|v| BridgeMethods::ts_into_trees(v)).unwrap_or_default().into_iter(),
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -509,7 +512,7 @@ pub fn mixed_site() -> Span {
|
||||
/// `self` was generated from, if any.
|
||||
#[unstable(feature = "proc_macro_span", issue = "54725")]
|
||||
pub fn parent(&self) -> Option<Span> {
|
||||
self.0.parent().map(Span)
|
||||
BridgeMethods::span_parent(self.0).map(Span)
|
||||
}
|
||||
|
||||
/// The span for the origin source code that `self` was generated from. If
|
||||
@@ -517,25 +520,25 @@ pub fn parent(&self) -> Option<Span> {
|
||||
/// value is the same as `*self`.
|
||||
#[unstable(feature = "proc_macro_span", issue = "54725")]
|
||||
pub fn source(&self) -> Span {
|
||||
Span(self.0.source())
|
||||
Span(BridgeMethods::span_source(self.0))
|
||||
}
|
||||
|
||||
/// Returns the span's byte position range in the source file.
|
||||
#[unstable(feature = "proc_macro_span", issue = "54725")]
|
||||
pub fn byte_range(&self) -> Range<usize> {
|
||||
self.0.byte_range()
|
||||
BridgeMethods::span_byte_range(self.0)
|
||||
}
|
||||
|
||||
/// Creates an empty span pointing to directly before this span.
|
||||
#[stable(feature = "proc_macro_span_location", since = "1.88.0")]
|
||||
pub fn start(&self) -> Span {
|
||||
Span(self.0.start())
|
||||
Span(BridgeMethods::span_start(self.0))
|
||||
}
|
||||
|
||||
/// Creates an empty span pointing to directly after this span.
|
||||
#[stable(feature = "proc_macro_span_location", since = "1.88.0")]
|
||||
pub fn end(&self) -> Span {
|
||||
Span(self.0.end())
|
||||
Span(BridgeMethods::span_end(self.0))
|
||||
}
|
||||
|
||||
/// The one-indexed line of the source file where the span starts.
|
||||
@@ -543,7 +546,7 @@ pub fn end(&self) -> Span {
|
||||
/// To obtain the line of the span's end, use `span.end().line()`.
|
||||
#[stable(feature = "proc_macro_span_location", since = "1.88.0")]
|
||||
pub fn line(&self) -> usize {
|
||||
self.0.line()
|
||||
BridgeMethods::span_line(self.0)
|
||||
}
|
||||
|
||||
/// The one-indexed column of the source file where the span starts.
|
||||
@@ -551,7 +554,7 @@ pub fn line(&self) -> usize {
|
||||
/// To obtain the column of the span's end, use `span.end().column()`.
|
||||
#[stable(feature = "proc_macro_span_location", since = "1.88.0")]
|
||||
pub fn column(&self) -> usize {
|
||||
self.0.column()
|
||||
BridgeMethods::span_column(self.0)
|
||||
}
|
||||
|
||||
/// The path to the source file in which this span occurs, for display purposes.
|
||||
@@ -560,7 +563,7 @@ pub fn column(&self) -> usize {
|
||||
/// It might be remapped (e.g. `"/src/lib.rs"`) or an artificial path (e.g. `"<command line>"`).
|
||||
#[stable(feature = "proc_macro_span_file", since = "1.88.0")]
|
||||
pub fn file(&self) -> String {
|
||||
self.0.file()
|
||||
BridgeMethods::span_file(self.0)
|
||||
}
|
||||
|
||||
/// The path to the source file in which this span occurs on the local file system.
|
||||
@@ -570,7 +573,7 @@ pub fn file(&self) -> String {
|
||||
/// This path should not be embedded in the output of the macro; prefer `file()` instead.
|
||||
#[stable(feature = "proc_macro_span_file", since = "1.88.0")]
|
||||
pub fn local_file(&self) -> Option<PathBuf> {
|
||||
self.0.local_file().map(PathBuf::from)
|
||||
BridgeMethods::span_local_file(self.0).map(PathBuf::from)
|
||||
}
|
||||
|
||||
/// Creates a new span encompassing `self` and `other`.
|
||||
@@ -578,14 +581,14 @@ pub fn local_file(&self) -> Option<PathBuf> {
|
||||
/// Returns `None` if `self` and `other` are from different files.
|
||||
#[unstable(feature = "proc_macro_span", issue = "54725")]
|
||||
pub fn join(&self, other: Span) -> Option<Span> {
|
||||
self.0.join(other.0).map(Span)
|
||||
BridgeMethods::span_join(self.0, other.0).map(Span)
|
||||
}
|
||||
|
||||
/// Creates a new span with the same line/column information as `self` but
|
||||
/// that resolves symbols as though it were at `other`.
|
||||
#[stable(feature = "proc_macro_span_resolved_at", since = "1.45.0")]
|
||||
pub fn resolved_at(&self, other: Span) -> Span {
|
||||
Span(self.0.resolved_at(other.0))
|
||||
Span(BridgeMethods::span_resolved_at(self.0, other.0))
|
||||
}
|
||||
|
||||
/// Creates a new span with the same name resolution behavior as `self` but
|
||||
@@ -610,21 +613,21 @@ pub fn eq(&self, other: &Span) -> bool {
|
||||
/// be used for diagnostics only.
|
||||
#[stable(feature = "proc_macro_source_text", since = "1.66.0")]
|
||||
pub fn source_text(&self) -> Option<String> {
|
||||
self.0.source_text()
|
||||
BridgeMethods::span_source_text(self.0)
|
||||
}
|
||||
|
||||
// Used by the implementation of `Span::quote`
|
||||
#[doc(hidden)]
|
||||
#[unstable(feature = "proc_macro_internals", issue = "27812")]
|
||||
pub fn save_span(&self) -> usize {
|
||||
self.0.save_span()
|
||||
BridgeMethods::span_save_span(self.0)
|
||||
}
|
||||
|
||||
// Used by the implementation of `Span::quote`
|
||||
#[doc(hidden)]
|
||||
#[unstable(feature = "proc_macro_internals", issue = "27812")]
|
||||
pub fn recover_proc_macro_span(id: usize) -> Span {
|
||||
Span(bridge::client::Span::recover_proc_macro_span(id))
|
||||
Span(BridgeMethods::span_recover_proc_macro_span(id))
|
||||
}
|
||||
|
||||
diagnostic_method!(error, Level::Error);
|
||||
@@ -1389,7 +1392,12 @@ pub fn set_span(&mut self, span: Span) {
|
||||
// was 'c' or whether it was '\u{63}'.
|
||||
#[unstable(feature = "proc_macro_span", issue = "54725")]
|
||||
pub fn subspan<R: RangeBounds<usize>>(&self, range: R) -> Option<Span> {
|
||||
self.0.span.subspan(range.start_bound().cloned(), range.end_bound().cloned()).map(Span)
|
||||
BridgeMethods::span_subspan(
|
||||
self.0.span,
|
||||
range.start_bound().cloned(),
|
||||
range.end_bound().cloned(),
|
||||
)
|
||||
.map(Span)
|
||||
}
|
||||
|
||||
fn with_symbol_and_suffix<R>(&self, f: impl FnOnce(&str, &str) -> R) -> R {
|
||||
@@ -1559,7 +1567,7 @@ impl FromStr for Literal {
|
||||
type Err = LexError;
|
||||
|
||||
fn from_str(src: &str) -> Result<Self, LexError> {
|
||||
match bridge::client::FreeFunctions::literal_from_str(src) {
|
||||
match BridgeMethods::literal_from_str(src) {
|
||||
Ok(literal) => Ok(Literal(literal)),
|
||||
Err(()) => Err(LexError),
|
||||
}
|
||||
@@ -1601,11 +1609,12 @@ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
)]
|
||||
/// Functionality for adding environment state to the build dependency info.
|
||||
pub mod tracked {
|
||||
|
||||
use std::env::{self, VarError};
|
||||
use std::ffi::OsStr;
|
||||
use std::path::Path;
|
||||
|
||||
use crate::BridgeMethods;
|
||||
|
||||
/// Retrieve an environment variable and add it to build dependency info.
|
||||
/// The build system executing the compiler will know that the variable was accessed during
|
||||
/// compilation, and will be able to rerun the build when the value of that variable changes.
|
||||
@@ -1614,9 +1623,8 @@ pub mod tracked {
|
||||
#[unstable(feature = "proc_macro_tracked_env", issue = "99515")]
|
||||
pub fn env_var<K: AsRef<OsStr> + AsRef<str>>(key: K) -> Result<String, VarError> {
|
||||
let key: &str = key.as_ref();
|
||||
let value = crate::bridge::client::FreeFunctions::injected_env_var(key)
|
||||
.map_or_else(|| env::var(key), Ok);
|
||||
crate::bridge::client::FreeFunctions::track_env_var(key, value.as_deref().ok());
|
||||
let value = BridgeMethods::injected_env_var(key).map_or_else(|| env::var(key), Ok);
|
||||
BridgeMethods::track_env_var(key, value.as_deref().ok());
|
||||
value
|
||||
}
|
||||
|
||||
@@ -1626,6 +1634,6 @@ pub fn env_var<K: AsRef<OsStr> + AsRef<str>>(key: K) -> Result<String, VarError>
|
||||
#[unstable(feature = "proc_macro_tracked_path", issue = "99515")]
|
||||
pub fn path<P: AsRef<Path>>(path: P) {
|
||||
let path: &str = path.as_ref().to_str().unwrap();
|
||||
crate::bridge::client::FreeFunctions::track_path(path);
|
||||
BridgeMethods::track_path(path);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -509,6 +509,12 @@ fn run(self, builder: &Builder<'_>) {
|
||||
cargo.arg("--workspace");
|
||||
cargo.arg("--exclude=xtask");
|
||||
|
||||
if build_compiler.stage == 0 {
|
||||
// This builds a proc macro against the bootstrap libproc_macro, which is not ABI
|
||||
// compatible with the ABI proc-macro-srv expects to load.
|
||||
cargo.arg("--exclude=proc-macro-srv");
|
||||
}
|
||||
|
||||
let mut skip_tests = vec![];
|
||||
|
||||
// NOTE: the following test skips is a bit cheeky in that it assumes there are no
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
//! `proc_macro::bridge` newtypes.
|
||||
|
||||
use proc_macro::bridge as pm_bridge;
|
||||
use rustc_proc_macro::bridge as pm_bridge;
|
||||
|
||||
pub use pm_bridge::{DelimSpan, Diagnostic, ExpnGlobals, LitKind};
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
mod proc_macros;
|
||||
mod version;
|
||||
|
||||
use proc_macro::bridge;
|
||||
use rustc_proc_macro::bridge;
|
||||
use std::{fmt, fs, io, time::SystemTime};
|
||||
use temp_dir::TempDir;
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
//! Proc macro ABI
|
||||
use crate::{ProcMacroClientHandle, ProcMacroKind, ProcMacroSrvSpan, token_stream::TokenStream};
|
||||
use proc_macro::bridge;
|
||||
use rustc_proc_macro::bridge;
|
||||
|
||||
#[repr(transparent)]
|
||||
pub(crate) struct ProcMacros([bridge::client::ProcMacro]);
|
||||
|
||||
@@ -22,9 +22,9 @@
|
||||
)]
|
||||
#![deny(deprecated_safe, clippy::undocumented_unsafe_blocks)]
|
||||
|
||||
extern crate proc_macro;
|
||||
#[cfg(feature = "in-rust-tree")]
|
||||
extern crate rustc_driver as _;
|
||||
extern crate rustc_proc_macro;
|
||||
|
||||
#[cfg(not(feature = "in-rust-tree"))]
|
||||
extern crate ra_ap_rustc_lexer as rustc_lexer;
|
||||
@@ -52,7 +52,7 @@
|
||||
|
||||
pub use crate::server_impl::token_id::SpanId;
|
||||
|
||||
pub use proc_macro::Delimiter;
|
||||
pub use rustc_proc_macro::Delimiter;
|
||||
pub use span;
|
||||
|
||||
pub use crate::bridge::*;
|
||||
@@ -181,7 +181,9 @@ fn expander(&self, path: &Utf8Path) -> Result<Arc<dylib::Expander>, String> {
|
||||
}
|
||||
|
||||
pub trait ProcMacroSrvSpan: Copy + Send + Sync {
|
||||
type Server<'a>: proc_macro::bridge::server::Server<TokenStream = crate::token_stream::TokenStream<Self>>;
|
||||
type Server<'a>: rustc_proc_macro::bridge::server::Server<
|
||||
TokenStream = crate::token_stream::TokenStream<Self>,
|
||||
>;
|
||||
fn make_server<'a>(
|
||||
call_site: Self,
|
||||
def_site: Self,
|
||||
|
||||
+51
-54
@@ -10,7 +10,7 @@
|
||||
};
|
||||
|
||||
use intern::Symbol;
|
||||
use proc_macro::bridge::server;
|
||||
use rustc_proc_macro::bridge::server;
|
||||
use span::{FIXUP_ERASED_FILE_AST_ID_MARKER, Span, TextRange, TextSize};
|
||||
|
||||
use crate::{
|
||||
@@ -19,8 +19,6 @@
|
||||
server_impl::literal_from_str,
|
||||
};
|
||||
|
||||
pub struct FreeFunctions;
|
||||
|
||||
pub struct RaSpanServer<'a> {
|
||||
// FIXME: Report this back to the caller to track as dependencies
|
||||
pub tracked_env_vars: HashMap<Box<str>, Option<Box<str>>>,
|
||||
@@ -33,13 +31,28 @@ pub struct RaSpanServer<'a> {
|
||||
}
|
||||
|
||||
impl server::Types for RaSpanServer<'_> {
|
||||
type FreeFunctions = FreeFunctions;
|
||||
type TokenStream = crate::token_stream::TokenStream<Span>;
|
||||
type Span = Span;
|
||||
type Symbol = Symbol;
|
||||
}
|
||||
|
||||
impl server::FreeFunctions for RaSpanServer<'_> {
|
||||
impl server::Server for RaSpanServer<'_> {
|
||||
fn globals(&mut self) -> ExpnGlobals<Self::Span> {
|
||||
ExpnGlobals {
|
||||
def_site: self.def_site,
|
||||
call_site: self.call_site,
|
||||
mixed_site: self.mixed_site,
|
||||
}
|
||||
}
|
||||
|
||||
fn intern_symbol(ident: &str) -> Self::Symbol {
|
||||
Symbol::intern(ident)
|
||||
}
|
||||
|
||||
fn with_symbol_string(symbol: &Self::Symbol, f: impl FnOnce(&str)) {
|
||||
f(symbol.as_str())
|
||||
}
|
||||
|
||||
fn injected_env_var(&mut self, _: &str) -> Option<std::string::String> {
|
||||
None
|
||||
}
|
||||
@@ -58,13 +71,19 @@ fn literal_from_str(&mut self, s: &str) -> Result<Literal<Self::Span>, ()> {
|
||||
fn emit_diagnostic(&mut self, _: Diagnostic<Self::Span>) {
|
||||
// FIXME handle diagnostic
|
||||
}
|
||||
}
|
||||
|
||||
impl server::TokenStream for RaSpanServer<'_> {
|
||||
fn is_empty(&mut self, stream: &Self::TokenStream) -> bool {
|
||||
fn ts_drop(&mut self, stream: Self::TokenStream) {
|
||||
drop(stream);
|
||||
}
|
||||
|
||||
fn ts_clone(&mut self, stream: &Self::TokenStream) -> Self::TokenStream {
|
||||
stream.clone()
|
||||
}
|
||||
|
||||
fn ts_is_empty(&mut self, stream: &Self::TokenStream) -> bool {
|
||||
stream.is_empty()
|
||||
}
|
||||
fn from_str(&mut self, src: &str) -> Self::TokenStream {
|
||||
fn ts_from_str(&mut self, src: &str) -> Self::TokenStream {
|
||||
Self::TokenStream::from_str(src, self.call_site).unwrap_or_else(|e| {
|
||||
Self::TokenStream::from_str(
|
||||
&format!("compile_error!(\"failed to parse str to token stream: {e}\")"),
|
||||
@@ -73,15 +92,15 @@ fn from_str(&mut self, src: &str) -> Self::TokenStream {
|
||||
.unwrap()
|
||||
})
|
||||
}
|
||||
fn to_string(&mut self, stream: &Self::TokenStream) -> String {
|
||||
fn ts_to_string(&mut self, stream: &Self::TokenStream) -> String {
|
||||
stream.to_string()
|
||||
}
|
||||
|
||||
fn from_token_tree(&mut self, tree: TokenTree<Self::Span>) -> Self::TokenStream {
|
||||
fn ts_from_token_tree(&mut self, tree: TokenTree<Self::Span>) -> Self::TokenStream {
|
||||
Self::TokenStream::new(vec![tree])
|
||||
}
|
||||
|
||||
fn expand_expr(&mut self, self_: &Self::TokenStream) -> Result<Self::TokenStream, ()> {
|
||||
fn ts_expand_expr(&mut self, self_: &Self::TokenStream) -> Result<Self::TokenStream, ()> {
|
||||
// FIXME: requires db, more importantly this requires name resolution so we would need to
|
||||
// eagerly expand this proc-macro, but we can't know that this proc-macro is eager until we
|
||||
// expand it ...
|
||||
@@ -90,7 +109,7 @@ fn expand_expr(&mut self, self_: &Self::TokenStream) -> Result<Self::TokenStream
|
||||
Ok(self_.clone())
|
||||
}
|
||||
|
||||
fn concat_trees(
|
||||
fn ts_concat_trees(
|
||||
&mut self,
|
||||
base: Option<Self::TokenStream>,
|
||||
trees: Vec<TokenTree<Self::Span>>,
|
||||
@@ -106,7 +125,7 @@ fn concat_trees(
|
||||
}
|
||||
}
|
||||
|
||||
fn concat_streams(
|
||||
fn ts_concat_streams(
|
||||
&mut self,
|
||||
base: Option<Self::TokenStream>,
|
||||
streams: Vec<Self::TokenStream>,
|
||||
@@ -118,28 +137,26 @@ fn concat_streams(
|
||||
stream
|
||||
}
|
||||
|
||||
fn into_trees(&mut self, stream: Self::TokenStream) -> Vec<TokenTree<Self::Span>> {
|
||||
fn ts_into_trees(&mut self, stream: Self::TokenStream) -> Vec<TokenTree<Self::Span>> {
|
||||
(*stream.0).clone()
|
||||
}
|
||||
}
|
||||
|
||||
impl server::Span for RaSpanServer<'_> {
|
||||
fn debug(&mut self, span: Self::Span) -> String {
|
||||
fn span_debug(&mut self, span: Self::Span) -> String {
|
||||
format!("{:?}", span)
|
||||
}
|
||||
fn file(&mut self, span: Self::Span) -> String {
|
||||
fn span_file(&mut self, span: Self::Span) -> String {
|
||||
self.callback.as_mut().map(|cb| cb.file(span.anchor.file_id.file_id())).unwrap_or_default()
|
||||
}
|
||||
fn local_file(&mut self, span: Self::Span) -> Option<String> {
|
||||
fn span_local_file(&mut self, span: Self::Span) -> Option<String> {
|
||||
self.callback.as_mut().and_then(|cb| cb.local_file(span.anchor.file_id.file_id()))
|
||||
}
|
||||
fn save_span(&mut self, _span: Self::Span) -> usize {
|
||||
fn span_save_span(&mut self, _span: Self::Span) -> usize {
|
||||
// FIXME, quote is incompatible with third-party tools
|
||||
// This is called by the quote proc-macro which is expanded when the proc-macro is compiled
|
||||
// As such, r-a will never observe this
|
||||
0
|
||||
}
|
||||
fn recover_proc_macro_span(&mut self, _id: usize) -> Self::Span {
|
||||
fn span_recover_proc_macro_span(&mut self, _id: usize) -> Self::Span {
|
||||
// FIXME, quote is incompatible with third-party tools
|
||||
// This is called by the expansion of quote!, r-a will observe this, but we don't have
|
||||
// access to the spans that were encoded
|
||||
@@ -149,23 +166,23 @@ fn recover_proc_macro_span(&mut self, _id: usize) -> Self::Span {
|
||||
///
|
||||
/// See PR:
|
||||
/// https://github.com/rust-lang/rust/pull/55780
|
||||
fn source_text(&mut self, span: Self::Span) -> Option<String> {
|
||||
fn span_source_text(&mut self, span: Self::Span) -> Option<String> {
|
||||
self.callback.as_mut()?.source_text(span)
|
||||
}
|
||||
|
||||
fn parent(&mut self, _span: Self::Span) -> Option<Self::Span> {
|
||||
fn span_parent(&mut self, _span: Self::Span) -> Option<Self::Span> {
|
||||
// FIXME requires db, looks up the parent call site
|
||||
None
|
||||
}
|
||||
fn source(&mut self, span: Self::Span) -> Self::Span {
|
||||
fn span_source(&mut self, span: Self::Span) -> Self::Span {
|
||||
// FIXME requires db, returns the top level call site
|
||||
span
|
||||
}
|
||||
fn byte_range(&mut self, span: Self::Span) -> Range<usize> {
|
||||
fn span_byte_range(&mut self, span: Self::Span) -> Range<usize> {
|
||||
// FIXME requires db to resolve the ast id, THIS IS NOT INCREMENTAL
|
||||
Range { start: span.range.start().into(), end: span.range.end().into() }
|
||||
}
|
||||
fn join(&mut self, first: Self::Span, second: Self::Span) -> Option<Self::Span> {
|
||||
fn span_join(&mut self, first: Self::Span, second: Self::Span) -> Option<Self::Span> {
|
||||
// We can't modify the span range for fixup spans, those are meaningful to fixup, so just
|
||||
// prefer the non-fixup span.
|
||||
if first.anchor.ast_id == FIXUP_ERASED_FILE_AST_ID_MARKER {
|
||||
@@ -193,7 +210,7 @@ fn join(&mut self, first: Self::Span, second: Self::Span) -> Option<Self::Span>
|
||||
ctx: second.ctx,
|
||||
})
|
||||
}
|
||||
fn subspan(
|
||||
fn span_subspan(
|
||||
&mut self,
|
||||
span: Self::Span,
|
||||
start: Bound<usize>,
|
||||
@@ -237,11 +254,11 @@ fn subspan(
|
||||
})
|
||||
}
|
||||
|
||||
fn resolved_at(&mut self, span: Self::Span, at: Self::Span) -> Self::Span {
|
||||
fn span_resolved_at(&mut self, span: Self::Span, at: Self::Span) -> Self::Span {
|
||||
Span { ctx: at.ctx, ..span }
|
||||
}
|
||||
|
||||
fn end(&mut self, span: Self::Span) -> Self::Span {
|
||||
fn span_end(&mut self, span: Self::Span) -> Self::Span {
|
||||
// We can't modify the span range for fixup spans, those are meaningful to fixup.
|
||||
if span.anchor.ast_id == FIXUP_ERASED_FILE_AST_ID_MARKER {
|
||||
return span;
|
||||
@@ -249,7 +266,7 @@ fn end(&mut self, span: Self::Span) -> Self::Span {
|
||||
Span { range: TextRange::empty(span.range.end()), ..span }
|
||||
}
|
||||
|
||||
fn start(&mut self, span: Self::Span) -> Self::Span {
|
||||
fn span_start(&mut self, span: Self::Span) -> Self::Span {
|
||||
// We can't modify the span range for fixup spans, those are meaningful to fixup.
|
||||
if span.anchor.ast_id == FIXUP_ERASED_FILE_AST_ID_MARKER {
|
||||
return span;
|
||||
@@ -257,38 +274,18 @@ fn start(&mut self, span: Self::Span) -> Self::Span {
|
||||
Span { range: TextRange::empty(span.range.start()), ..span }
|
||||
}
|
||||
|
||||
fn line(&mut self, _span: Self::Span) -> usize {
|
||||
fn span_line(&mut self, _span: Self::Span) -> usize {
|
||||
// FIXME requires db to resolve line index, THIS IS NOT INCREMENTAL
|
||||
1
|
||||
}
|
||||
|
||||
fn column(&mut self, _span: Self::Span) -> usize {
|
||||
fn span_column(&mut self, _span: Self::Span) -> usize {
|
||||
// FIXME requires db to resolve line index, THIS IS NOT INCREMENTAL
|
||||
1
|
||||
}
|
||||
}
|
||||
|
||||
impl server::Symbol for RaSpanServer<'_> {
|
||||
fn normalize_and_validate_ident(&mut self, string: &str) -> Result<Self::Symbol, ()> {
|
||||
fn symbol_normalize_and_validate_ident(&mut self, string: &str) -> Result<Self::Symbol, ()> {
|
||||
// FIXME: nfc-normalize and validate idents
|
||||
Ok(<Self as server::Server>::intern_symbol(string))
|
||||
}
|
||||
}
|
||||
|
||||
impl server::Server for RaSpanServer<'_> {
|
||||
fn globals(&mut self) -> ExpnGlobals<Self::Span> {
|
||||
ExpnGlobals {
|
||||
def_site: self.def_site,
|
||||
call_site: self.call_site,
|
||||
mixed_site: self.mixed_site,
|
||||
}
|
||||
}
|
||||
|
||||
fn intern_symbol(ident: &str) -> Self::Symbol {
|
||||
Symbol::intern(ident)
|
||||
}
|
||||
|
||||
fn with_symbol_string(symbol: &Self::Symbol, f: impl FnOnce(&str)) {
|
||||
f(symbol.as_str())
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
};
|
||||
|
||||
use intern::Symbol;
|
||||
use proc_macro::bridge::server;
|
||||
use rustc_proc_macro::bridge::server;
|
||||
|
||||
use crate::{
|
||||
ProcMacroClientHandle,
|
||||
@@ -25,8 +25,6 @@ fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
|
||||
type Span = SpanId;
|
||||
|
||||
pub struct FreeFunctions;
|
||||
|
||||
pub struct SpanIdServer<'a> {
|
||||
// FIXME: Report this back to the caller to track as dependencies
|
||||
pub tracked_env_vars: HashMap<Box<str>, Option<Box<str>>>,
|
||||
@@ -39,161 +37,11 @@ pub struct SpanIdServer<'a> {
|
||||
}
|
||||
|
||||
impl server::Types for SpanIdServer<'_> {
|
||||
type FreeFunctions = FreeFunctions;
|
||||
type TokenStream = crate::token_stream::TokenStream<Span>;
|
||||
type Span = Span;
|
||||
type Symbol = Symbol;
|
||||
}
|
||||
|
||||
impl server::FreeFunctions for SpanIdServer<'_> {
|
||||
fn injected_env_var(&mut self, _: &str) -> Option<std::string::String> {
|
||||
None
|
||||
}
|
||||
fn track_env_var(&mut self, var: &str, value: Option<&str>) {
|
||||
self.tracked_env_vars.insert(var.into(), value.map(Into::into));
|
||||
}
|
||||
fn track_path(&mut self, path: &str) {
|
||||
self.tracked_paths.insert(path.into());
|
||||
}
|
||||
|
||||
fn literal_from_str(&mut self, s: &str) -> Result<Literal<Self::Span>, ()> {
|
||||
literal_from_str(s, self.call_site)
|
||||
}
|
||||
|
||||
fn emit_diagnostic(&mut self, _: Diagnostic<Self::Span>) {}
|
||||
}
|
||||
|
||||
impl server::TokenStream for SpanIdServer<'_> {
|
||||
fn is_empty(&mut self, stream: &Self::TokenStream) -> bool {
|
||||
stream.is_empty()
|
||||
}
|
||||
fn from_str(&mut self, src: &str) -> Self::TokenStream {
|
||||
Self::TokenStream::from_str(src, self.call_site).unwrap_or_else(|e| {
|
||||
Self::TokenStream::from_str(
|
||||
&format!("compile_error!(\"failed to parse str to token stream: {e}\")"),
|
||||
self.call_site,
|
||||
)
|
||||
.unwrap()
|
||||
})
|
||||
}
|
||||
fn to_string(&mut self, stream: &Self::TokenStream) -> String {
|
||||
stream.to_string()
|
||||
}
|
||||
fn from_token_tree(&mut self, tree: TokenTree<Self::Span>) -> Self::TokenStream {
|
||||
Self::TokenStream::new(vec![tree])
|
||||
}
|
||||
|
||||
fn expand_expr(&mut self, self_: &Self::TokenStream) -> Result<Self::TokenStream, ()> {
|
||||
Ok(self_.clone())
|
||||
}
|
||||
|
||||
fn concat_trees(
|
||||
&mut self,
|
||||
base: Option<Self::TokenStream>,
|
||||
trees: Vec<TokenTree<Self::Span>>,
|
||||
) -> Self::TokenStream {
|
||||
match base {
|
||||
Some(mut base) => {
|
||||
for tt in trees {
|
||||
base.push_tree(tt);
|
||||
}
|
||||
base
|
||||
}
|
||||
None => Self::TokenStream::new(trees),
|
||||
}
|
||||
}
|
||||
|
||||
fn concat_streams(
|
||||
&mut self,
|
||||
base: Option<Self::TokenStream>,
|
||||
streams: Vec<Self::TokenStream>,
|
||||
) -> Self::TokenStream {
|
||||
let mut stream = base.unwrap_or_default();
|
||||
for s in streams {
|
||||
stream.push_stream(s);
|
||||
}
|
||||
stream
|
||||
}
|
||||
|
||||
fn into_trees(&mut self, stream: Self::TokenStream) -> Vec<TokenTree<Self::Span>> {
|
||||
(*stream.0).clone()
|
||||
}
|
||||
}
|
||||
|
||||
impl server::Span for SpanIdServer<'_> {
|
||||
fn debug(&mut self, span: Self::Span) -> String {
|
||||
format!("{:?}", span.0)
|
||||
}
|
||||
fn file(&mut self, _span: Self::Span) -> String {
|
||||
String::new()
|
||||
}
|
||||
fn local_file(&mut self, _span: Self::Span) -> Option<String> {
|
||||
None
|
||||
}
|
||||
fn save_span(&mut self, _span: Self::Span) -> usize {
|
||||
0
|
||||
}
|
||||
fn recover_proc_macro_span(&mut self, _id: usize) -> Self::Span {
|
||||
self.call_site
|
||||
}
|
||||
/// Recent feature, not yet in the proc_macro
|
||||
///
|
||||
/// See PR:
|
||||
/// https://github.com/rust-lang/rust/pull/55780
|
||||
fn source_text(&mut self, _span: Self::Span) -> Option<String> {
|
||||
None
|
||||
}
|
||||
|
||||
fn parent(&mut self, _span: Self::Span) -> Option<Self::Span> {
|
||||
None
|
||||
}
|
||||
fn source(&mut self, span: Self::Span) -> Self::Span {
|
||||
span
|
||||
}
|
||||
fn byte_range(&mut self, _span: Self::Span) -> Range<usize> {
|
||||
Range { start: 0, end: 0 }
|
||||
}
|
||||
fn join(&mut self, first: Self::Span, _second: Self::Span) -> Option<Self::Span> {
|
||||
// Just return the first span again, because some macros will unwrap the result.
|
||||
Some(first)
|
||||
}
|
||||
fn subspan(
|
||||
&mut self,
|
||||
span: Self::Span,
|
||||
_start: Bound<usize>,
|
||||
_end: Bound<usize>,
|
||||
) -> Option<Self::Span> {
|
||||
// Just return the span again, because some macros will unwrap the result.
|
||||
Some(span)
|
||||
}
|
||||
fn resolved_at(&mut self, _span: Self::Span, _at: Self::Span) -> Self::Span {
|
||||
self.call_site
|
||||
}
|
||||
|
||||
fn end(&mut self, _self_: Self::Span) -> Self::Span {
|
||||
self.call_site
|
||||
}
|
||||
|
||||
fn start(&mut self, _self_: Self::Span) -> Self::Span {
|
||||
self.call_site
|
||||
}
|
||||
|
||||
fn line(&mut self, _span: Self::Span) -> usize {
|
||||
1
|
||||
}
|
||||
|
||||
fn column(&mut self, _span: Self::Span) -> usize {
|
||||
1
|
||||
}
|
||||
}
|
||||
|
||||
impl server::Symbol for SpanIdServer<'_> {
|
||||
fn normalize_and_validate_ident(&mut self, string: &str) -> Result<Self::Symbol, ()> {
|
||||
// FIXME: nfc-normalize and validate idents
|
||||
Ok(<Self as server::Server>::intern_symbol(string))
|
||||
}
|
||||
}
|
||||
|
||||
impl server::Server for SpanIdServer<'_> {
|
||||
fn globals(&mut self) -> ExpnGlobals<Self::Span> {
|
||||
ExpnGlobals {
|
||||
@@ -210,4 +58,153 @@ fn intern_symbol(ident: &str) -> Self::Symbol {
|
||||
fn with_symbol_string(symbol: &Self::Symbol, f: impl FnOnce(&str)) {
|
||||
f(symbol.as_str())
|
||||
}
|
||||
|
||||
fn injected_env_var(&mut self, _: &str) -> Option<std::string::String> {
|
||||
None
|
||||
}
|
||||
fn track_env_var(&mut self, var: &str, value: Option<&str>) {
|
||||
self.tracked_env_vars.insert(var.into(), value.map(Into::into));
|
||||
}
|
||||
fn track_path(&mut self, path: &str) {
|
||||
self.tracked_paths.insert(path.into());
|
||||
}
|
||||
|
||||
fn literal_from_str(&mut self, s: &str) -> Result<Literal<Self::Span>, ()> {
|
||||
literal_from_str(s, self.call_site)
|
||||
}
|
||||
|
||||
fn emit_diagnostic(&mut self, _: Diagnostic<Self::Span>) {}
|
||||
|
||||
fn ts_drop(&mut self, stream: Self::TokenStream) {
|
||||
drop(stream);
|
||||
}
|
||||
|
||||
fn ts_clone(&mut self, stream: &Self::TokenStream) -> Self::TokenStream {
|
||||
stream.clone()
|
||||
}
|
||||
|
||||
fn ts_is_empty(&mut self, stream: &Self::TokenStream) -> bool {
|
||||
stream.is_empty()
|
||||
}
|
||||
fn ts_from_str(&mut self, src: &str) -> Self::TokenStream {
|
||||
Self::TokenStream::from_str(src, self.call_site).unwrap_or_else(|e| {
|
||||
Self::TokenStream::from_str(
|
||||
&format!("compile_error!(\"failed to parse str to token stream: {e}\")"),
|
||||
self.call_site,
|
||||
)
|
||||
.unwrap()
|
||||
})
|
||||
}
|
||||
fn ts_to_string(&mut self, stream: &Self::TokenStream) -> String {
|
||||
stream.to_string()
|
||||
}
|
||||
fn ts_from_token_tree(&mut self, tree: TokenTree<Self::Span>) -> Self::TokenStream {
|
||||
Self::TokenStream::new(vec![tree])
|
||||
}
|
||||
|
||||
fn ts_expand_expr(&mut self, self_: &Self::TokenStream) -> Result<Self::TokenStream, ()> {
|
||||
Ok(self_.clone())
|
||||
}
|
||||
|
||||
fn ts_concat_trees(
|
||||
&mut self,
|
||||
base: Option<Self::TokenStream>,
|
||||
trees: Vec<TokenTree<Self::Span>>,
|
||||
) -> Self::TokenStream {
|
||||
match base {
|
||||
Some(mut base) => {
|
||||
for tt in trees {
|
||||
base.push_tree(tt);
|
||||
}
|
||||
base
|
||||
}
|
||||
None => Self::TokenStream::new(trees),
|
||||
}
|
||||
}
|
||||
|
||||
fn ts_concat_streams(
|
||||
&mut self,
|
||||
base: Option<Self::TokenStream>,
|
||||
streams: Vec<Self::TokenStream>,
|
||||
) -> Self::TokenStream {
|
||||
let mut stream = base.unwrap_or_default();
|
||||
for s in streams {
|
||||
stream.push_stream(s);
|
||||
}
|
||||
stream
|
||||
}
|
||||
|
||||
fn ts_into_trees(&mut self, stream: Self::TokenStream) -> Vec<TokenTree<Self::Span>> {
|
||||
(*stream.0).clone()
|
||||
}
|
||||
|
||||
fn span_debug(&mut self, span: Self::Span) -> String {
|
||||
format!("{:?}", span.0)
|
||||
}
|
||||
fn span_file(&mut self, _span: Self::Span) -> String {
|
||||
String::new()
|
||||
}
|
||||
fn span_local_file(&mut self, _span: Self::Span) -> Option<String> {
|
||||
None
|
||||
}
|
||||
fn span_save_span(&mut self, _span: Self::Span) -> usize {
|
||||
0
|
||||
}
|
||||
fn span_recover_proc_macro_span(&mut self, _id: usize) -> Self::Span {
|
||||
self.call_site
|
||||
}
|
||||
/// Recent feature, not yet in the proc_macro
|
||||
///
|
||||
/// See PR:
|
||||
/// https://github.com/rust-lang/rust/pull/55780
|
||||
fn span_source_text(&mut self, _span: Self::Span) -> Option<String> {
|
||||
None
|
||||
}
|
||||
|
||||
fn span_parent(&mut self, _span: Self::Span) -> Option<Self::Span> {
|
||||
None
|
||||
}
|
||||
fn span_source(&mut self, span: Self::Span) -> Self::Span {
|
||||
span
|
||||
}
|
||||
fn span_byte_range(&mut self, _span: Self::Span) -> Range<usize> {
|
||||
Range { start: 0, end: 0 }
|
||||
}
|
||||
fn span_join(&mut self, first: Self::Span, _second: Self::Span) -> Option<Self::Span> {
|
||||
// Just return the first span again, because some macros will unwrap the result.
|
||||
Some(first)
|
||||
}
|
||||
fn span_subspan(
|
||||
&mut self,
|
||||
span: Self::Span,
|
||||
_start: Bound<usize>,
|
||||
_end: Bound<usize>,
|
||||
) -> Option<Self::Span> {
|
||||
// Just return the span again, because some macros will unwrap the result.
|
||||
Some(span)
|
||||
}
|
||||
fn span_resolved_at(&mut self, _span: Self::Span, _at: Self::Span) -> Self::Span {
|
||||
self.call_site
|
||||
}
|
||||
|
||||
fn span_end(&mut self, _self_: Self::Span) -> Self::Span {
|
||||
self.call_site
|
||||
}
|
||||
|
||||
fn span_start(&mut self, _self_: Self::Span) -> Self::Span {
|
||||
self.call_site
|
||||
}
|
||||
|
||||
fn span_line(&mut self, _span: Self::Span) -> usize {
|
||||
1
|
||||
}
|
||||
|
||||
fn span_column(&mut self, _span: Self::Span) -> usize {
|
||||
1
|
||||
}
|
||||
|
||||
fn symbol_normalize_and_validate_ident(&mut self, string: &str) -> Result<Self::Symbol, ()> {
|
||||
// FIXME: nfc-normalize and validate idents
|
||||
Ok(<Self as server::Server>::intern_symbol(string))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,8 +4,8 @@
|
||||
use std::{mem, sync::Arc};
|
||||
|
||||
use intern::Symbol;
|
||||
use proc_macro::Delimiter;
|
||||
use rustc_lexer::{DocStyle, LiteralKind};
|
||||
use rustc_proc_macro::Delimiter;
|
||||
|
||||
use crate::bridge::{DelimSpan, Group, Ident, LitKind, Literal, Punct, TokenTree};
|
||||
|
||||
@@ -52,7 +52,7 @@ pub(crate) fn from_str(s: &str, span: S) -> Result<Self, String>
|
||||
S: SpanLike + Copy,
|
||||
{
|
||||
let mut groups = Vec::new();
|
||||
groups.push((proc_macro::Delimiter::None, 0..0, vec![]));
|
||||
groups.push((rustc_proc_macro::Delimiter::None, 0..0, vec![]));
|
||||
let mut offset = 0;
|
||||
let mut tokens = rustc_lexer::tokenize(s, rustc_lexer::FrontmatterAllowed::No).peekable();
|
||||
while let Some(token) = tokens.next() {
|
||||
@@ -102,7 +102,7 @@ pub(crate) fn from_str(s: &str, span: S) -> Result<Self, String>
|
||||
};
|
||||
match token.kind {
|
||||
rustc_lexer::TokenKind::OpenParen => {
|
||||
groups.push((proc_macro::Delimiter::Parenthesis, range, vec![]))
|
||||
groups.push((rustc_proc_macro::Delimiter::Parenthesis, range, vec![]))
|
||||
}
|
||||
rustc_lexer::TokenKind::CloseParen if *open_delim != Delimiter::Parenthesis => {
|
||||
return if *open_delim == Delimiter::None {
|
||||
@@ -130,7 +130,7 @@ pub(crate) fn from_str(s: &str, span: S) -> Result<Self, String>
|
||||
);
|
||||
}
|
||||
rustc_lexer::TokenKind::OpenBrace => {
|
||||
groups.push((proc_macro::Delimiter::Brace, range, vec![]))
|
||||
groups.push((rustc_proc_macro::Delimiter::Brace, range, vec![]))
|
||||
}
|
||||
rustc_lexer::TokenKind::CloseBrace if *open_delim != Delimiter::Brace => {
|
||||
return if *open_delim == Delimiter::None {
|
||||
@@ -158,7 +158,7 @@ pub(crate) fn from_str(s: &str, span: S) -> Result<Self, String>
|
||||
);
|
||||
}
|
||||
rustc_lexer::TokenKind::OpenBracket => {
|
||||
groups.push((proc_macro::Delimiter::Bracket, range, vec![]))
|
||||
groups.push((rustc_proc_macro::Delimiter::Bracket, range, vec![]))
|
||||
}
|
||||
rustc_lexer::TokenKind::CloseBracket if *open_delim != Delimiter::Bracket => {
|
||||
return if *open_delim == Delimiter::None {
|
||||
@@ -460,10 +460,10 @@ fn display_token_tree<S>(
|
||||
f,
|
||||
"{}",
|
||||
match delimiter {
|
||||
proc_macro::Delimiter::Parenthesis => "(",
|
||||
proc_macro::Delimiter::Brace => "{",
|
||||
proc_macro::Delimiter::Bracket => "[",
|
||||
proc_macro::Delimiter::None => "",
|
||||
rustc_proc_macro::Delimiter::Parenthesis => "(",
|
||||
rustc_proc_macro::Delimiter::Brace => "{",
|
||||
rustc_proc_macro::Delimiter::Bracket => "[",
|
||||
rustc_proc_macro::Delimiter::None => "",
|
||||
}
|
||||
)?;
|
||||
if let Some(stream) = stream {
|
||||
@@ -473,10 +473,10 @@ fn display_token_tree<S>(
|
||||
f,
|
||||
"{}",
|
||||
match delimiter {
|
||||
proc_macro::Delimiter::Parenthesis => ")",
|
||||
proc_macro::Delimiter::Brace => "}",
|
||||
proc_macro::Delimiter::Bracket => "]",
|
||||
proc_macro::Delimiter::None => "",
|
||||
rustc_proc_macro::Delimiter::Parenthesis => ")",
|
||||
rustc_proc_macro::Delimiter::Brace => "}",
|
||||
rustc_proc_macro::Delimiter::Bracket => "]",
|
||||
rustc_proc_macro::Delimiter::None => "",
|
||||
}
|
||||
)?;
|
||||
}
|
||||
@@ -587,16 +587,16 @@ fn debug_token_tree<S: fmt::Debug>(
|
||||
f,
|
||||
"GROUP {}{} {:#?} {:#?} {:#?}",
|
||||
match delimiter {
|
||||
proc_macro::Delimiter::Parenthesis => "(",
|
||||
proc_macro::Delimiter::Brace => "{",
|
||||
proc_macro::Delimiter::Bracket => "[",
|
||||
proc_macro::Delimiter::None => "$",
|
||||
rustc_proc_macro::Delimiter::Parenthesis => "(",
|
||||
rustc_proc_macro::Delimiter::Brace => "{",
|
||||
rustc_proc_macro::Delimiter::Bracket => "[",
|
||||
rustc_proc_macro::Delimiter::None => "$",
|
||||
},
|
||||
match delimiter {
|
||||
proc_macro::Delimiter::Parenthesis => ")",
|
||||
proc_macro::Delimiter::Brace => "}",
|
||||
proc_macro::Delimiter::Bracket => "]",
|
||||
proc_macro::Delimiter::None => "$",
|
||||
rustc_proc_macro::Delimiter::Parenthesis => ")",
|
||||
rustc_proc_macro::Delimiter::Brace => "}",
|
||||
rustc_proc_macro::Delimiter::Bracket => "]",
|
||||
rustc_proc_macro::Delimiter::None => "$",
|
||||
},
|
||||
span.open,
|
||||
span.close,
|
||||
|
||||
Reference in New Issue
Block a user