]> git.lizzy.rs Git - rust.git/blobdiff - library/proc_macro/src/lib.rs
proc_macro: stop using a remote object handle for Ident
[rust.git] / library / proc_macro / src / lib.rs
index 771ee50e138617fc1528b680664f04b3b9f15bc5..911deaef8c97835e388503c328658eb16de0f212 100644 (file)
 #![feature(staged_api)]
 #![feature(allow_internal_unstable)]
 #![feature(decl_macro)]
+#![feature(local_key_cell_methods)]
+#![feature(maybe_uninit_write_slice)]
 #![feature(negative_impls)]
+#![feature(new_uninit)]
 #![feature(restricted_std)]
 #![feature(rustc_attrs)]
 #![feature(min_specialization)]
+#![feature(strict_provenance)]
 #![recursion_limit = "256"]
 
 #[unstable(feature = "proc_macro_internals", issue = "27812")]
@@ -212,9 +216,9 @@ fn default() -> Self {
 fn tree_to_bridge_tree(
     tree: TokenTree,
 ) -> bridge::TokenTree<
-    bridge::client::Group,
-    bridge::client::Punct,
-    bridge::client::Ident,
+    bridge::client::TokenStream,
+    bridge::client::Span,
+    bridge::client::Symbol,
     bridge::client::Literal,
 > {
     match tree {
@@ -238,9 +242,9 @@ fn from(tree: TokenTree) -> TokenStream {
 struct ConcatTreesHelper {
     trees: Vec<
         bridge::TokenTree<
-            bridge::client::Group,
-            bridge::client::Punct,
-            bridge::client::Ident,
+            bridge::client::TokenStream,
+            bridge::client::Span,
+            bridge::client::Symbol,
             bridge::client::Literal,
         >,
     >,
@@ -365,9 +369,9 @@ pub mod token_stream {
     pub struct IntoIter(
         std::vec::IntoIter<
             bridge::TokenTree<
-                bridge::client::Group,
-                bridge::client::Punct,
-                bridge::client::Ident,
+                bridge::client::TokenStream,
+                bridge::client::Span,
+                bridge::client::Symbol,
                 bridge::client::Literal,
             >,
         >,
@@ -788,7 +792,7 @@ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
 /// A `Group` internally contains a `TokenStream` which is surrounded by `Delimiter`s.
 #[derive(Clone)]
 #[stable(feature = "proc_macro_lib2", since = "1.29.0")]
-pub struct Group(bridge::client::Group);
+pub struct Group(bridge::Group<bridge::client::TokenStream, bridge::client::Span>);
 
 #[stable(feature = "proc_macro_lib2", since = "1.29.0")]
 impl !Send for Group {}
@@ -825,13 +829,17 @@ impl Group {
     /// method below.
     #[stable(feature = "proc_macro_lib2", since = "1.29.0")]
     pub fn new(delimiter: Delimiter, stream: TokenStream) -> Group {
-        Group(bridge::client::Group::new(delimiter, stream.0))
+        Group(bridge::Group {
+            delimiter,
+            stream: stream.0,
+            span: bridge::DelimSpan::from_single(Span::call_site().0),
+        })
     }
 
     /// Returns the delimiter of this `Group`
     #[stable(feature = "proc_macro_lib2", since = "1.29.0")]
     pub fn delimiter(&self) -> Delimiter {
-        self.0.delimiter()
+        self.0.delimiter
     }
 
     /// Returns the `TokenStream` of tokens that are delimited in this `Group`.
@@ -840,7 +848,7 @@ pub fn delimiter(&self) -> Delimiter {
     /// returned above.
     #[stable(feature = "proc_macro_lib2", since = "1.29.0")]
     pub fn stream(&self) -> TokenStream {
-        TokenStream(Some(self.0.stream()))
+        TokenStream(self.0.stream.clone())
     }
 
     /// Returns the span for the delimiters of this token stream, spanning the
@@ -852,7 +860,7 @@ pub fn stream(&self) -> TokenStream {
     /// ```
     #[stable(feature = "proc_macro_lib2", since = "1.29.0")]
     pub fn span(&self) -> Span {
-        Span(self.0.span())
+        Span(self.0.span.entire)
     }
 
     /// Returns the span pointing to the opening delimiter of this group.
@@ -863,7 +871,7 @@ pub fn span(&self) -> Span {
     /// ```
     #[stable(feature = "proc_macro_group_span", since = "1.55.0")]
     pub fn span_open(&self) -> Span {
-        Span(self.0.span_open())
+        Span(self.0.span.open)
     }
 
     /// Returns the span pointing to the closing delimiter of this group.
@@ -874,7 +882,7 @@ pub fn span_open(&self) -> Span {
     /// ```
     #[stable(feature = "proc_macro_group_span", since = "1.55.0")]
     pub fn span_close(&self) -> Span {
-        Span(self.0.span_close())
+        Span(self.0.span.close)
     }
 
     /// Configures the span for this `Group`'s delimiters, but not its internal
@@ -885,7 +893,7 @@ pub fn span_close(&self) -> Span {
     /// tokens at the level of the `Group`.
     #[stable(feature = "proc_macro_lib2", since = "1.29.0")]
     pub fn set_span(&mut self, span: Span) {
-        self.0.set_span(span.0);
+        self.0.span = bridge::DelimSpan::from_single(span.0);
     }
 }
 
@@ -925,7 +933,7 @@ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
 /// 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 +966,24 @@ 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: ch as u8,
+            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 as char
     }
 
     /// Returns the spacing of this punctuation character, indicating whether it's immediately
@@ -973,28 +992,26 @@ pub fn as_char(&self) -> char {
     /// (`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);
+        self.0.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")]
+#[stable(feature = "proc_macro_lib2", since = "1.29.0")]
 impl ToString for Punct {
     fn to_string(&self) -> String {
-        TokenStream::from(TokenTree::from(self.clone())).to_string()
+        self.as_char().to_string()
     }
 }
 
@@ -1003,7 +1020,7 @@ fn to_string(&self) -> String {
 #[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())
     }
 }
 
@@ -1035,7 +1052,7 @@ fn eq(&self, rhs: &Punct) -> bool {
 /// An identifier (`ident`).
 #[derive(Clone)]
 #[stable(feature = "proc_macro_lib2", since = "1.29.0")]
-pub struct Ident(bridge::client::Ident);
+pub struct Ident(bridge::Ident<bridge::client::Span, bridge::client::Symbol>);
 
 impl Ident {
     /// Creates a new `Ident` with the given `string` as well as the specified
@@ -1059,7 +1076,11 @@ impl Ident {
     /// tokens, requires a `Span` to be specified at construction.
     #[stable(feature = "proc_macro_lib2", since = "1.29.0")]
     pub fn new(string: &str, span: Span) -> Ident {
-        Ident(bridge::client::Ident::new(string, span.0, false))
+        Ident(bridge::Ident {
+            sym: bridge::client::Symbol::new_ident(string, false),
+            is_raw: false,
+            span: span.0,
+        })
     }
 
     /// Same as `Ident::new`, but creates a raw identifier (`r#ident`).
@@ -1068,38 +1089,45 @@ pub fn new(string: &str, span: Span) -> Ident {
     /// (e.g. `self`, `super`) are not supported, and will cause a panic.
     #[stable(feature = "proc_macro_raw_ident", since = "1.47.0")]
     pub fn new_raw(string: &str, span: Span) -> Ident {
-        Ident(bridge::client::Ident::new(string, span.0, true))
+        Ident(bridge::Ident {
+            sym: bridge::client::Symbol::new_ident(string, true),
+            is_raw: true,
+            span: span.0,
+        })
     }
 
     /// Returns the span of this `Ident`, encompassing the entire string returned
-    /// by [`to_string`](Self::to_string).
+    /// by [`to_string`](ToString::to_string).
     #[stable(feature = "proc_macro_lib2", since = "1.29.0")]
     pub fn span(&self) -> Span {
-        Span(self.0.span())
+        Span(self.0.span)
     }
 
     /// Configures the span of this `Ident`, possibly changing its hygiene context.
     #[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);
+        self.0.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")]
+/// Converts the identifier to a string that should be losslessly convertible
+/// back into the same identifier.
+#[stable(feature = "proc_macro_lib2", since = "1.29.0")]
 impl ToString for Ident {
     fn to_string(&self) -> String {
-        TokenStream::from(TokenTree::from(self.clone())).to_string()
+        self.0.sym.with(|sym| if self.0.is_raw { ["r#", sym].concat() } else { sym.to_owned() })
     }
 }
 
-/// Prints the identifier as a string that should be losslessly convertible
-/// back into the same identifier.
+/// Prints the identifier as a string that should be losslessly convertible back
+/// into the same identifier.
 #[stable(feature = "proc_macro_lib2", since = "1.29.0")]
 impl fmt::Display for Ident {
     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
-        f.write_str(&self.to_string())
+        if self.0.is_raw {
+            f.write_str("r#")?;
+        }
+        fmt::Display::fmt(&self.0.sym, f)
     }
 }