about summary refs log tree commit diff
path: root/compiler/rustc_expand/src
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2023-07-28 01:21:27 +0000
committerbors <bors@rust-lang.org>2023-07-28 01:21:27 +0000
commit0699d9951695c0d8ad2efa1e208e97bcc5dfbb53 (patch)
tree20832650c38b19704b7b2c3c813025fa4f414a17 /compiler/rustc_expand/src
parent6cacb5247fbb5c38f06c1ad71262b0c4eb91a84d (diff)
parent4ebf2be8bb91e41fdf6c7c337482c72317508cef (diff)
downloadrust-0699d9951695c0d8ad2efa1e208e97bcc5dfbb53.tar.gz
rust-0699d9951695c0d8ad2efa1e208e97bcc5dfbb53.zip
Auto merge of #114115 - nnethercote:less-token-tree-cloning, r=petrochenkov
Less `TokenTree` cloning

`TokenTreeCursor` has this comment on it:
```
// FIXME: Many uses of this can be replaced with by-reference iterator to avoid clones.
```
This PR completes that FIXME. It doesn't have much perf effect, but at least we now know that.

r? `@petrochenkov`
Diffstat (limited to 'compiler/rustc_expand/src')
-rw-r--r--compiler/rustc_expand/src/config.rs6
-rw-r--r--compiler/rustc_expand/src/mbe/macro_rules.rs4
-rw-r--r--compiler/rustc_expand/src/mbe/quoted.rs42
-rw-r--r--compiler/rustc_expand/src/parse/tests.rs9
-rw-r--r--compiler/rustc_expand/src/proc_macro_server.rs4
5 files changed, 31 insertions, 34 deletions
diff --git a/compiler/rustc_expand/src/config.rs b/compiler/rustc_expand/src/config.rs
index 4ec5ac22e90..aeb4f6e861b 100644
--- a/compiler/rustc_expand/src/config.rs
+++ b/compiler/rustc_expand/src/config.rs
@@ -365,9 +365,9 @@ impl<'a> StripUnconfigured<'a> {
 
         // Use the `#` in `#[cfg_attr(pred, attr)]` as the `#` token
         // for `attr` when we expand it to `#[attr]`
-        let mut orig_trees = orig_tokens.into_trees();
+        let mut orig_trees = orig_tokens.trees();
         let TokenTree::Token(pound_token @ Token { kind: TokenKind::Pound, .. }, _) =
-            orig_trees.next().unwrap()
+            orig_trees.next().unwrap().clone()
         else {
             panic!("Bad tokens for attribute {:?}", attr);
         };
@@ -377,7 +377,7 @@ impl<'a> StripUnconfigured<'a> {
         if attr.style == AttrStyle::Inner {
             // For inner attributes, we do the same thing for the `!` in `#![some_attr]`
             let TokenTree::Token(bang_token @ Token { kind: TokenKind::Not, .. }, _) =
-                orig_trees.next().unwrap()
+                orig_trees.next().unwrap().clone()
             else {
                 panic!("Bad tokens for attribute {:?}", attr);
             };
diff --git a/compiler/rustc_expand/src/mbe/macro_rules.rs b/compiler/rustc_expand/src/mbe/macro_rules.rs
index 102bae2a744..7398a124fdb 100644
--- a/compiler/rustc_expand/src/mbe/macro_rules.rs
+++ b/compiler/rustc_expand/src/mbe/macro_rules.rs
@@ -500,7 +500,7 @@ pub fn compile_declarative_macro(
             .map(|m| {
                 if let MatchedTokenTree(tt) = m {
                     let tt = mbe::quoted::parse(
-                        TokenStream::new(vec![tt.clone()]),
+                        &TokenStream::new(vec![tt.clone()]),
                         true,
                         &sess.parse_sess,
                         def.id,
@@ -524,7 +524,7 @@ pub fn compile_declarative_macro(
             .map(|m| {
                 if let MatchedTokenTree(tt) = m {
                     return mbe::quoted::parse(
-                        TokenStream::new(vec![tt.clone()]),
+                        &TokenStream::new(vec![tt.clone()]),
                         false,
                         &sess.parse_sess,
                         def.id,
diff --git a/compiler/rustc_expand/src/mbe/quoted.rs b/compiler/rustc_expand/src/mbe/quoted.rs
index 40bfa3715be..ac862ae8c4f 100644
--- a/compiler/rustc_expand/src/mbe/quoted.rs
+++ b/compiler/rustc_expand/src/mbe/quoted.rs
@@ -36,7 +36,7 @@ const VALID_FRAGMENT_NAMES_MSG: &str = "valid fragment specifiers are \
 ///
 /// A collection of `self::TokenTree`. There may also be some errors emitted to `sess`.
 pub(super) fn parse(
-    input: tokenstream::TokenStream,
+    input: &tokenstream::TokenStream,
     parsing_patterns: bool,
     sess: &ParseSess,
     node_id: NodeId,
@@ -48,7 +48,7 @@ pub(super) fn parse(
 
     // For each token tree in `input`, parse the token into a `self::TokenTree`, consuming
     // additional trees if need be.
-    let mut trees = input.into_trees();
+    let mut trees = input.trees();
     while let Some(tree) = trees.next() {
         // Given the parsed tree, if there is a metavar and we are expecting matchers, actually
         // parse out the matcher (i.e., in `$id:ident` this would parse the `:` and `ident`).
@@ -56,7 +56,7 @@ pub(super) fn parse(
         match tree {
             TokenTree::MetaVar(start_sp, ident) if parsing_patterns => {
                 let span = match trees.next() {
-                    Some(tokenstream::TokenTree::Token(Token { kind: token::Colon, span }, _)) => {
+                    Some(&tokenstream::TokenTree::Token(Token { kind: token::Colon, span }, _)) => {
                         match trees.next() {
                             Some(tokenstream::TokenTree::Token(token, _)) => match token.ident() {
                                 Some((frag, _)) => {
@@ -96,10 +96,10 @@ pub(super) fn parse(
                                 }
                                 _ => token.span,
                             },
-                            tree => tree.as_ref().map_or(span, tokenstream::TokenTree::span),
+                            tree => tree.map_or(span, tokenstream::TokenTree::span),
                         }
                     }
-                    tree => tree.as_ref().map_or(start_sp, tokenstream::TokenTree::span),
+                    tree => tree.map_or(start_sp, tokenstream::TokenTree::span),
                 };
 
                 result.push(TokenTree::MetaVarDecl(span, ident, None));
@@ -134,9 +134,9 @@ fn maybe_emit_macro_metavar_expr_feature(features: &Features, sess: &ParseSess,
 /// - `parsing_patterns`: same as [parse].
 /// - `sess`: the parsing session. Any errors will be emitted to this session.
 /// - `features`: language features so we can do feature gating.
-fn parse_tree(
-    tree: tokenstream::TokenTree,
-    outer_trees: &mut impl Iterator<Item = tokenstream::TokenTree>,
+fn parse_tree<'a>(
+    tree: &'a tokenstream::TokenTree,
+    outer_trees: &mut impl Iterator<Item = &'a tokenstream::TokenTree>,
     parsing_patterns: bool,
     sess: &ParseSess,
     node_id: NodeId,
@@ -146,13 +146,13 @@ fn parse_tree(
     // Depending on what `tree` is, we could be parsing different parts of a macro
     match tree {
         // `tree` is a `$` token. Look at the next token in `trees`
-        tokenstream::TokenTree::Token(Token { kind: token::Dollar, span }, _) => {
+        &tokenstream::TokenTree::Token(Token { kind: token::Dollar, span }, _) => {
             // FIXME: Handle `Invisible`-delimited groups in a more systematic way
             // during parsing.
             let mut next = outer_trees.next();
-            let mut trees: Box<dyn Iterator<Item = tokenstream::TokenTree>>;
+            let mut trees: Box<dyn Iterator<Item = &tokenstream::TokenTree>>;
             if let Some(tokenstream::TokenTree::Delimited(_, Delimiter::Invisible, tts)) = next {
-                trees = Box::new(tts.into_trees());
+                trees = Box::new(tts.trees());
                 next = trees.next();
             } else {
                 trees = Box::new(outer_trees);
@@ -160,7 +160,7 @@ fn parse_tree(
 
             match next {
                 // `tree` is followed by a delimited set of token trees.
-                Some(tokenstream::TokenTree::Delimited(delim_span, delim, tts)) => {
+                Some(&tokenstream::TokenTree::Delimited(delim_span, delim, ref tts)) => {
                     if parsing_patterns {
                         if delim != Delimiter::Parenthesis {
                             span_dollar_dollar_or_metavar_in_the_lhs_err(
@@ -228,7 +228,7 @@ fn parse_tree(
                 }
 
                 // `tree` is followed by another `$`. This is an escaped `$`.
-                Some(tokenstream::TokenTree::Token(Token { kind: token::Dollar, span }, _)) => {
+                Some(&tokenstream::TokenTree::Token(Token { kind: token::Dollar, span }, _)) => {
                     if parsing_patterns {
                         span_dollar_dollar_or_metavar_in_the_lhs_err(
                             sess,
@@ -256,11 +256,11 @@ fn parse_tree(
         }
 
         // `tree` is an arbitrary token. Keep it.
-        tokenstream::TokenTree::Token(token, _) => TokenTree::Token(token),
+        tokenstream::TokenTree::Token(token, _) => TokenTree::Token(token.clone()),
 
         // `tree` is the beginning of a delimited set of tokens (e.g., `(` or `{`). We need to
         // descend into the delimited set and further parse it.
-        tokenstream::TokenTree::Delimited(span, delim, tts) => TokenTree::Delimited(
+        &tokenstream::TokenTree::Delimited(span, delim, ref tts) => TokenTree::Delimited(
             span,
             Delimited {
                 delim,
@@ -286,16 +286,16 @@ fn kleene_op(token: &Token) -> Option<KleeneOp> {
 /// - Ok(Ok((op, span))) if the next token tree is a KleeneOp
 /// - Ok(Err(tok, span)) if the next token tree is a token but not a KleeneOp
 /// - Err(span) if the next token tree is not a token
-fn parse_kleene_op(
-    input: &mut impl Iterator<Item = tokenstream::TokenTree>,
+fn parse_kleene_op<'a>(
+    input: &mut impl Iterator<Item = &'a tokenstream::TokenTree>,
     span: Span,
 ) -> Result<Result<(KleeneOp, Span), Token>, Span> {
     match input.next() {
         Some(tokenstream::TokenTree::Token(token, _)) => match kleene_op(&token) {
             Some(op) => Ok(Ok((op, token.span))),
-            None => Ok(Err(token)),
+            None => Ok(Err(token.clone())),
         },
-        tree => Err(tree.as_ref().map_or(span, tokenstream::TokenTree::span)),
+        tree => Err(tree.map_or(span, tokenstream::TokenTree::span)),
     }
 }
 
@@ -311,8 +311,8 @@ fn parse_kleene_op(
 /// session `sess`. If the next one (or possibly two) tokens in `input` correspond to a Kleene
 /// operator and separator, then a tuple with `(separator, KleeneOp)` is returned. Otherwise, an
 /// error with the appropriate span is emitted to `sess` and a dummy value is returned.
-fn parse_sep_and_kleene_op(
-    input: &mut impl Iterator<Item = tokenstream::TokenTree>,
+fn parse_sep_and_kleene_op<'a>(
+    input: &mut impl Iterator<Item = &'a tokenstream::TokenTree>,
     span: Span,
     sess: &ParseSess,
 ) -> (Option<Token>, KleeneToken) {
diff --git a/compiler/rustc_expand/src/parse/tests.rs b/compiler/rustc_expand/src/parse/tests.rs
index e133501c5d0..bdc20882a9d 100644
--- a/compiler/rustc_expand/src/parse/tests.rs
+++ b/compiler/rustc_expand/src/parse/tests.rs
@@ -69,9 +69,8 @@ fn bad_path_expr_1() {
 #[test]
 fn string_to_tts_macro() {
     create_default_session_globals_then(|| {
-        let tts: Vec<_> =
-            string_to_stream("macro_rules! zip (($a)=>($a))".to_string()).into_trees().collect();
-        let tts: &[TokenTree] = &tts[..];
+        let stream = string_to_stream("macro_rules! zip (($a)=>($a))".to_string());
+        let tts = &stream.trees().collect::<Vec<_>>()[..];
 
         match tts {
             [
@@ -300,9 +299,7 @@ fn ttdelim_span() {
         .unwrap();
 
         let ast::ExprKind::MacCall(mac) = &expr.kind else { panic!("not a macro") };
-        let tts: Vec<_> = mac.args.tokens.clone().into_trees().collect();
-
-        let span = tts.iter().rev().next().unwrap().span();
+        let span = mac.args.tokens.trees().last().unwrap().span();
 
         match sess.source_map().span_to_snippet(span) {
             Ok(s) => assert_eq!(&s[..], "{ body }"),
diff --git a/compiler/rustc_expand/src/proc_macro_server.rs b/compiler/rustc_expand/src/proc_macro_server.rs
index ecd2315112a..ac73b5d72b7 100644
--- a/compiler/rustc_expand/src/proc_macro_server.rs
+++ b/compiler/rustc_expand/src/proc_macro_server.rs
@@ -94,10 +94,10 @@ impl FromInternal<(TokenStream, &mut Rustc<'_, '_>)> for Vec<TokenTree<TokenStre
         // Estimate the capacity as `stream.len()` rounded up to the next power
         // of two to limit the number of required reallocations.
         let mut trees = Vec::with_capacity(stream.len().next_power_of_two());
-        let mut cursor = stream.into_trees();
+        let mut cursor = stream.trees();
 
         while let Some(tree) = cursor.next() {
-            let (Token { kind, span }, joint) = match tree {
+            let (Token { kind, span }, joint) = match tree.clone() {
                 tokenstream::TokenTree::Delimited(span, delim, tts) => {
                     let delimiter = pm::Delimiter::from_internal(delim);
                     trees.push(TokenTree::Group(Group {