about summary refs log tree commit diff
diff options
context:
space:
mode:
authorNika Layzell <nika@thelayzells.com>2021-06-28 22:30:55 -0400
committerNika Layzell <nika@thelayzells.com>2022-06-26 22:20:33 -0400
commit72bfe618fa06ba09fa898c1fd818b8d5886c6035 (patch)
treee311d2500a3fe71085727da2c2dc5eaebc831e79
parent3b0d4813ab461ec81eab8980bb884691c97c5a35 (diff)
downloadrust-72bfe618fa06ba09fa898c1fd818b8d5886c6035.tar.gz
rust-72bfe618fa06ba09fa898c1fd818b8d5886c6035.zip
proc_macro: stop using a remote object handle for Punct
This greatly reduces round-trips to fetch relevant extra information about the
token in proc macro code, and avoids RPC messages to create Punct tokens.
-rw-r--r--compiler/rustc_expand/src/proc_macro_server.rs76
-rw-r--r--library/proc_macro/src/bridge/client.rs1
-rw-r--r--library/proc_macro/src/bridge/mod.rs28
-rw-r--r--library/proc_macro/src/bridge/server.rs1
-rw-r--r--library/proc_macro/src/lib.rs36
-rw-r--r--src/test/ui/proc-macro/invalid-punct-ident-1.rs2
6 files changed, 49 insertions, 95 deletions
diff --git a/compiler/rustc_expand/src/proc_macro_server.rs b/compiler/rustc_expand/src/proc_macro_server.rs
index 6b9bc0ab54b..12d7338c39b 100644
--- a/compiler/rustc_expand/src/proc_macro_server.rs
+++ b/compiler/rustc_expand/src/proc_macro_server.rs
@@ -14,8 +14,8 @@ use rustc_span::def_id::CrateNum;
 use rustc_span::symbol::{self, kw, sym, Symbol};
 use rustc_span::{BytePos, FileName, Pos, SourceFile, Span};
 
-use pm::bridge::{server, ExpnGlobals, TokenTree};
-use pm::{Delimiter, Level, LineColumn, Spacing};
+use pm::bridge::{server, ExpnGlobals, Punct, TokenTree};
+use pm::{Delimiter, Level, LineColumn};
 use std::ops::Bound;
 use std::{ascii, panic};
 
@@ -50,7 +50,7 @@ impl ToInternal<token::Delimiter> for Delimiter {
 }
 
 impl FromInternal<(TreeAndSpacing, &'_ mut Vec<Self>, &mut Rustc<'_, '_>)>
-    for TokenTree<Group, Punct, Ident, Literal>
+    for TokenTree<Span, Group, Ident, Literal>
 {
     fn from_internal(
         ((tree, spacing), stack, rustc): (TreeAndSpacing, &mut Vec<Self>, &mut Rustc<'_, '_>),
@@ -79,16 +79,16 @@ impl FromInternal<(TreeAndSpacing, &'_ mut Vec<Self>, &mut Rustc<'_, '_>)>
         }
         macro_rules! op {
             ($a:expr) => {
-                tt!(Punct::new($a, joint))
+                tt!(Punct { ch: $a, joint })
             };
             ($a:expr, $b:expr) => {{
-                stack.push(tt!(Punct::new($b, joint)));
-                tt!(Punct::new($a, true))
+                stack.push(tt!(Punct { ch: $b, joint }));
+                tt!(Punct { ch: $a, joint: true })
             }};
             ($a:expr, $b:expr, $c:expr) => {{
-                stack.push(tt!(Punct::new($c, joint)));
-                stack.push(tt!(Punct::new($b, true)));
-                tt!(Punct::new($a, true))
+                stack.push(tt!(Punct { ch: $c, joint }));
+                stack.push(tt!(Punct { ch: $b, joint: true }));
+                tt!(Punct { ch: $a, joint: true })
             }};
         }
 
@@ -146,7 +146,7 @@ impl FromInternal<(TreeAndSpacing, &'_ mut Vec<Self>, &mut Rustc<'_, '_>)>
             Lifetime(name) => {
                 let ident = symbol::Ident::new(name, span).without_first_quote();
                 stack.push(tt!(Ident::new(rustc.sess(), ident.name, false)));
-                tt!(Punct::new('\'', true))
+                tt!(Punct { ch: '\'', joint: true })
             }
             Literal(lit) => tt!(Literal { lit }),
             DocComment(_, attr_style, data) => {
@@ -169,9 +169,9 @@ impl FromInternal<(TreeAndSpacing, &'_ mut Vec<Self>, &mut Rustc<'_, '_>)>
                     flatten: false,
                 }));
                 if attr_style == ast::AttrStyle::Inner {
-                    stack.push(tt!(Punct::new('!', false)));
+                    stack.push(tt!(Punct { ch: '!', joint: false }));
                 }
-                tt!(Punct::new('#', false))
+                tt!(Punct { ch: '#', joint: false })
             }
 
             Interpolated(nt) if let NtIdent(ident, is_raw) = *nt => {
@@ -192,7 +192,7 @@ impl FromInternal<(TreeAndSpacing, &'_ mut Vec<Self>, &mut Rustc<'_, '_>)>
     }
 }
 
-impl ToInternal<TokenStream> for TokenTree<Group, Punct, Ident, Literal> {
+impl ToInternal<TokenStream> for TokenTree<Span, Group, Ident, Literal> {
     fn to_internal(self) -> TokenStream {
         use rustc_ast::token::*;
 
@@ -289,27 +289,6 @@ pub struct Group {
 }
 
 #[derive(Copy, Clone, PartialEq, Eq, Hash)]
-pub struct Punct {
-    ch: char,
-    // NB. not using `Spacing` here because it doesn't implement `Hash`.
-    joint: bool,
-    span: Span,
-}
-
-impl Punct {
-    fn new(ch: char, joint: bool, span: Span) -> Punct {
-        const LEGAL_CHARS: &[char] = &[
-            '=', '<', '>', '!', '~', '+', '-', '*', '/', '%', '^', '&', '|', '@', '.', ',', ';',
-            ':', '#', '$', '?', '\'',
-        ];
-        if !LEGAL_CHARS.contains(&ch) {
-            panic!("unsupported character `{:?}`", ch)
-        }
-        Punct { ch, joint, span }
-    }
-}
-
-#[derive(Copy, Clone, PartialEq, Eq, Hash)]
 pub struct Ident {
     sym: Symbol,
     is_raw: bool,
@@ -378,7 +357,6 @@ impl server::Types for Rustc<'_, '_> {
     type FreeFunctions = FreeFunctions;
     type TokenStream = TokenStream;
     type Group = Group;
-    type Punct = Punct;
     type Ident = Ident;
     type Literal = Literal;
     type SourceFile = Lrc<SourceFile>;
@@ -471,7 +449,7 @@ impl server::TokenStream for Rustc<'_, '_> {
 
     fn from_token_tree(
         &mut self,
-        tree: TokenTree<Self::Group, Self::Punct, Self::Ident, Self::Literal>,
+        tree: TokenTree<Self::Span, Self::Group, Self::Ident, Self::Literal>,
     ) -> Self::TokenStream {
         tree.to_internal()
     }
@@ -479,7 +457,7 @@ impl server::TokenStream for Rustc<'_, '_> {
     fn concat_trees(
         &mut self,
         base: Option<Self::TokenStream>,
-        trees: Vec<TokenTree<Self::Group, Self::Punct, Self::Ident, Self::Literal>>,
+        trees: Vec<TokenTree<Self::Span, Self::Group, Self::Ident, Self::Literal>>,
     ) -> Self::TokenStream {
         let mut builder = tokenstream::TokenStreamBuilder::new();
         if let Some(base) = base {
@@ -509,7 +487,7 @@ impl server::TokenStream for Rustc<'_, '_> {
     fn into_trees(
         &mut self,
         stream: Self::TokenStream,
-    ) -> Vec<TokenTree<Self::Group, Self::Punct, Self::Ident, Self::Literal>> {
+    ) -> Vec<TokenTree<Self::Span, Self::Group, Self::Ident, Self::Literal>> {
         // FIXME: This is a raw port of the previous approach (which had a
         // `TokenStreamIter` server-side object with a single `next` method),
         // and can probably be optimized (for bulk conversion).
@@ -577,28 +555,6 @@ impl server::Group for Rustc<'_, '_> {
     }
 }
 
-impl server::Punct for Rustc<'_, '_> {
-    fn new(&mut self, ch: char, spacing: Spacing) -> Self::Punct {
-        Punct::new(ch, spacing == Spacing::Joint, self.call_site)
-    }
-
-    fn as_char(&mut self, punct: Self::Punct) -> char {
-        punct.ch
-    }
-
-    fn spacing(&mut self, punct: Self::Punct) -> Spacing {
-        if punct.joint { Spacing::Joint } else { Spacing::Alone }
-    }
-
-    fn span(&mut self, punct: Self::Punct) -> Self::Span {
-        punct.span
-    }
-
-    fn with_span(&mut self, punct: Self::Punct, span: Self::Span) -> Self::Punct {
-        Punct { span, ..punct }
-    }
-}
-
 impl server::Ident for Rustc<'_, '_> {
     fn new(&mut self, string: &str, span: Self::Span, is_raw: bool) -> Self::Ident {
         Ident::new(self.sess(), Symbol::intern(string), is_raw, span)
diff --git a/library/proc_macro/src/bridge/client.rs b/library/proc_macro/src/bridge/client.rs
index 74b4a91662b..e42427c30fe 100644
--- a/library/proc_macro/src/bridge/client.rs
+++ b/library/proc_macro/src/bridge/client.rs
@@ -182,7 +182,6 @@ define_handles! {
     Diagnostic,
 
     'interned:
-    Punct,
     Ident,
     Span,
 }
diff --git a/library/proc_macro/src/bridge/mod.rs b/library/proc_macro/src/bridge/mod.rs
index 3bdc9007cd2..4c081396c6f 100644
--- a/library/proc_macro/src/bridge/mod.rs
+++ b/library/proc_macro/src/bridge/mod.rs
@@ -65,11 +65,11 @@ macro_rules! with_api {
                 fn from_str(src: &str) -> $S::TokenStream;
                 fn to_string($self: &$S::TokenStream) -> String;
                 fn from_token_tree(
-                    tree: TokenTree<$S::Group, $S::Punct, $S::Ident, $S::Literal>,
+                    tree: TokenTree<$S::Span, $S::Group, $S::Ident, $S::Literal>,
                 ) -> $S::TokenStream;
                 fn concat_trees(
                     base: Option<$S::TokenStream>,
-                    trees: Vec<TokenTree<$S::Group, $S::Punct, $S::Ident, $S::Literal>>,
+                    trees: Vec<TokenTree<$S::Span, $S::Group, $S::Ident, $S::Literal>>,
                 ) -> $S::TokenStream;
                 fn concat_streams(
                     base: Option<$S::TokenStream>,
@@ -77,7 +77,7 @@ macro_rules! with_api {
                 ) -> $S::TokenStream;
                 fn into_trees(
                     $self: $S::TokenStream
-                ) -> Vec<TokenTree<$S::Group, $S::Punct, $S::Ident, $S::Literal>>;
+                ) -> Vec<TokenTree<$S::Span, $S::Group, $S::Ident, $S::Literal>>;
             },
             Group {
                 fn drop($self: $S::Group);
@@ -90,13 +90,6 @@ macro_rules! with_api {
                 fn span_close($self: &$S::Group) -> $S::Span;
                 fn set_span($self: &mut $S::Group, span: $S::Span);
             },
-            Punct {
-                fn new(ch: char, spacing: Spacing) -> $S::Punct;
-                fn as_char($self: $S::Punct) -> char;
-                fn spacing($self: $S::Punct) -> Spacing;
-                fn span($self: $S::Punct) -> $S::Span;
-                fn with_span($self: $S::Punct, span: $S::Span) -> $S::Punct;
-            },
             Ident {
                 fn new(string: &str, span: $S::Span, is_raw: bool) -> $S::Ident;
                 fn span($self: $S::Ident) -> $S::Span;
@@ -449,15 +442,24 @@ compound_traits!(
 );
 
 #[derive(Clone)]
-pub enum TokenTree<G, P, I, L> {
+pub struct Punct<S> {
+    pub ch: char,
+    pub joint: bool,
+    pub span: S,
+}
+
+compound_traits!(struct Punct<Sp> { ch, joint, span });
+
+#[derive(Clone)]
+pub enum TokenTree<S, G, I, L> {
     Group(G),
-    Punct(P),
+    Punct(Punct<S>),
     Ident(I),
     Literal(L),
 }
 
 compound_traits!(
-    enum TokenTree<G, P, I, L> {
+    enum TokenTree<Sp, G, I, L> {
         Group(tt),
         Punct(tt),
         Ident(tt),
diff --git a/library/proc_macro/src/bridge/server.rs b/library/proc_macro/src/bridge/server.rs
index 1b7657eab70..d30b60d189f 100644
--- a/library/proc_macro/src/bridge/server.rs
+++ b/library/proc_macro/src/bridge/server.rs
@@ -9,7 +9,6 @@ pub trait Types {
     type FreeFunctions: 'static;
     type TokenStream: 'static + Clone;
     type Group: 'static + Clone;
-    type Punct: 'static + Copy + Eq + Hash;
     type Ident: 'static + Copy + Eq + Hash;
     type Literal: 'static + Clone;
     type SourceFile: 'static + Clone;
diff --git a/library/proc_macro/src/lib.rs b/library/proc_macro/src/lib.rs
index 771ee50e138..05f45e5a38f 100644
--- a/library/proc_macro/src/lib.rs
+++ b/library/proc_macro/src/lib.rs
@@ -212,8 +212,8 @@ pub use quote::{quote, quote_span};
 fn tree_to_bridge_tree(
     tree: TokenTree,
 ) -> bridge::TokenTree<
+    bridge::client::Span,
     bridge::client::Group,
-    bridge::client::Punct,
     bridge::client::Ident,
     bridge::client::Literal,
 > {
@@ -238,8 +238,8 @@ impl From<TokenTree> for TokenStream {
 struct ConcatTreesHelper {
     trees: Vec<
         bridge::TokenTree<
+            bridge::client::Span,
             bridge::client::Group,
-            bridge::client::Punct,
             bridge::client::Ident,
             bridge::client::Literal,
         >,
@@ -365,8 +365,8 @@ pub mod token_stream {
     pub struct IntoIter(
         std::vec::IntoIter<
             bridge::TokenTree<
+                bridge::client::Span,
                 bridge::client::Group,
-                bridge::client::Punct,
                 bridge::client::Ident,
                 bridge::client::Literal,
             >,
@@ -925,7 +925,7 @@ impl fmt::Debug for Group {
 /// forms of `Spacing` returned.
 #[stable(feature = "proc_macro_lib2", since = "1.29.0")]
 #[derive(Clone)]
-pub struct Punct(bridge::client::Punct);
+pub struct Punct(bridge::Punct<bridge::client::Span>);
 
 #[stable(feature = "proc_macro_lib2", since = "1.29.0")]
 impl !Send for Punct {}
@@ -958,13 +958,20 @@ impl Punct {
     /// which can be further configured with the `set_span` method below.
     #[stable(feature = "proc_macro_lib2", since = "1.29.0")]
     pub fn new(ch: char, spacing: Spacing) -> Punct {
-        Punct(bridge::client::Punct::new(ch, spacing))
+        const LEGAL_CHARS: &[char] = &[
+            '=', '<', '>', '!', '~', '+', '-', '*', '/', '%', '^', '&', '|', '@', '.', ',', ';',
+            ':', '#', '$', '?', '\'',
+        ];
+        if !LEGAL_CHARS.contains(&ch) {
+            panic!("unsupported character `{:?}`", ch);
+        }
+        Punct(bridge::Punct { ch, joint: spacing == Spacing::Joint, span: Span::call_site().0 })
     }
 
     /// Returns the value of this punctuation character as `char`.
     #[stable(feature = "proc_macro_lib2", since = "1.29.0")]
     pub fn as_char(&self) -> char {
-        self.0.as_char()
+        self.0.ch
     }
 
     /// Returns the spacing of this punctuation character, indicating whether it's immediately
@@ -973,28 +980,19 @@ impl Punct {
     /// (`Alone`) so the operator has certainly ended.
     #[stable(feature = "proc_macro_lib2", since = "1.29.0")]
     pub fn spacing(&self) -> Spacing {
-        self.0.spacing()
+        if self.0.joint { Spacing::Joint } else { Spacing::Alone }
     }
 
     /// Returns the span for this punctuation character.
     #[stable(feature = "proc_macro_lib2", since = "1.29.0")]
     pub fn span(&self) -> Span {
-        Span(self.0.span())
+        Span(self.0.span)
     }
 
     /// Configure the span for this punctuation character.
     #[stable(feature = "proc_macro_lib2", since = "1.29.0")]
     pub fn set_span(&mut self, span: Span) {
-        self.0 = self.0.with_span(span.0);
-    }
-}
-
-// N.B., the bridge only provides `to_string`, implement `fmt::Display`
-// based on it (the reverse of the usual relationship between the two).
-#[stable(feature = "proc_macro_lib", since = "1.15.0")]
-impl ToString for Punct {
-    fn to_string(&self) -> String {
-        TokenStream::from(TokenTree::from(self.clone())).to_string()
+        self.0.span = span.0;
     }
 }
 
@@ -1003,7 +1001,7 @@ impl ToString for Punct {
 #[stable(feature = "proc_macro_lib2", since = "1.29.0")]
 impl fmt::Display for Punct {
     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
-        f.write_str(&self.to_string())
+        write!(f, "{}", self.as_char())
     }
 }
 
diff --git a/src/test/ui/proc-macro/invalid-punct-ident-1.rs b/src/test/ui/proc-macro/invalid-punct-ident-1.rs
index a3133a1a790..ecbb6ebf55b 100644
--- a/src/test/ui/proc-macro/invalid-punct-ident-1.rs
+++ b/src/test/ui/proc-macro/invalid-punct-ident-1.rs
@@ -2,7 +2,7 @@
 // rustc-env:RUST_BACKTRACE=0
 
 // FIXME https://github.com/rust-lang/rust/issues/59998
-// normalize-stderr-test "thread.*panicked.*proc_macro_server.rs.*\n" -> ""
+// normalize-stderr-test "thread.*panicked.*proc_macro.*lib.rs.*\n" -> ""
 // normalize-stderr-test "note:.*RUST_BACKTRACE=1.*\n" -> ""
 // normalize-stderr-test "\nerror: internal compiler error.*\n\n" -> ""
 // normalize-stderr-test "note:.*unexpectedly panicked.*\n\n" -> ""