about summary refs log tree commit diff
diff options
context:
space:
mode:
authorNicholas Nethercote <n.nethercote@gmail.com>2023-07-27 10:10:32 +1000
committerNicholas Nethercote <n.nethercote@gmail.com>2023-07-27 11:58:42 +1000
commit55a732461dcd104311b24cc048dcef2ed0c9d57c (patch)
treeef302ce08d475f7456908bb044763039b174a5c0
parent103bd4a8208d813a958f3d3653c687be577ec3c2 (diff)
Make `TokenTree::uninterpolate` take `&self` and return a `Cow`.
Making it similar to `Token::uninterpolate`. This avoids some more token
tree cloning.
-rw-r--r--compiler/rustc_ast/src/attr/mod.rs14
-rw-r--r--compiler/rustc_ast/src/tokenstream.rs12
2 files changed, 14 insertions, 12 deletions
diff --git a/compiler/rustc_ast/src/attr/mod.rs b/compiler/rustc_ast/src/attr/mod.rs
index 466765f2dbf..8b9bb1df5dc 100644
--- a/compiler/rustc_ast/src/attr/mod.rs
+++ b/compiler/rustc_ast/src/attr/mod.rs
@@ -290,12 +290,12 @@ impl MetaItem {
         I: Iterator<Item = &'a TokenTree>,
     {
         // FIXME: Share code with `parse_path`.
-        let path = match tokens.next().map(|tt| TokenTree::uninterpolate(tt.clone())) {
-            Some(TokenTree::Token(
-                Token { kind: kind @ (token::Ident(..) | token::ModSep), span },
+        let path = match tokens.next().map(|tt| TokenTree::uninterpolate(tt)).as_deref() {
+            Some(&TokenTree::Token(
+                Token { kind: ref kind @ (token::Ident(..) | token::ModSep), span },
                 _,
             )) => 'arm: {
-                let mut segments = if let token::Ident(name, _) = kind {
+                let mut segments = if let &token::Ident(name, _) = kind {
                     if let Some(TokenTree::Token(Token { kind: token::ModSep, .. }, _)) =
                         tokens.peek()
                     {
@@ -308,8 +308,8 @@ impl MetaItem {
                     thin_vec![PathSegment::path_root(span)]
                 };
                 loop {
-                    if let Some(TokenTree::Token(Token { kind: token::Ident(name, _), span }, _)) =
-                        tokens.next().map(|tt| TokenTree::uninterpolate(tt.clone()))
+                    if let Some(&TokenTree::Token(Token { kind: token::Ident(name, _), span }, _)) =
+                        tokens.next().map(|tt| TokenTree::uninterpolate(tt)).as_deref()
                     {
                         segments.push(PathSegment::from_ident(Ident::new(name, span)));
                     } else {
@@ -326,7 +326,7 @@ impl MetaItem {
                 let span = span.with_hi(segments.last().unwrap().ident.span.hi());
                 Path { span, segments, tokens: None }
             }
-            Some(TokenTree::Token(Token { kind: token::Interpolated(nt), .. }, _)) => match &*nt {
+            Some(TokenTree::Token(Token { kind: token::Interpolated(nt), .. }, _)) => match &**nt {
                 token::Nonterminal::NtMeta(item) => return item.meta(item.path.span),
                 token::Nonterminal::NtPath(path) => (**path).clone(),
                 _ => return None,
diff --git a/compiler/rustc_ast/src/tokenstream.rs b/compiler/rustc_ast/src/tokenstream.rs
index ca4a739abd7..c6f0643147d 100644
--- a/compiler/rustc_ast/src/tokenstream.rs
+++ b/compiler/rustc_ast/src/tokenstream.rs
@@ -25,6 +25,7 @@ use rustc_serialize::{Decodable, Decoder, Encodable, Encoder};
 use rustc_span::{Span, DUMMY_SP};
 use smallvec::{smallvec, SmallVec};
 
+use std::borrow::Cow;
 use std::{fmt, iter, mem};
 
 /// When the main Rust parser encounters a syntax-extension invocation, it
@@ -98,12 +99,13 @@ impl TokenTree {
         TokenTree::Token(Token::new(kind, span), Spacing::Joint)
     }
 
-    pub fn uninterpolate(self) -> TokenTree {
+    pub fn uninterpolate(&self) -> Cow<'_, TokenTree> {
         match self {
-            TokenTree::Token(token, spacing) => {
-                TokenTree::Token(token.uninterpolate().into_owned(), spacing)
-            }
-            tt => tt,
+            TokenTree::Token(token, spacing) => match token.uninterpolate() {
+                Cow::Owned(token) => Cow::Owned(TokenTree::Token(token, *spacing)),
+                Cow::Borrowed(_) => Cow::Borrowed(self),
+            },
+            _ => Cow::Borrowed(self),
         }
     }
 }