about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--compiler/rustc_expand/src/mbe/transcribe.rs67
1 files changed, 38 insertions, 29 deletions
diff --git a/compiler/rustc_expand/src/mbe/transcribe.rs b/compiler/rustc_expand/src/mbe/transcribe.rs
index b1ab2cc4578..ca2908d7923 100644
--- a/compiler/rustc_expand/src/mbe/transcribe.rs
+++ b/compiler/rustc_expand/src/mbe/transcribe.rs
@@ -5,7 +5,6 @@ use rustc_ast::mut_visit::{self, MutVisitor};
 use rustc_ast::token::{self, Token, TokenKind};
 use rustc_ast::tokenstream::{DelimSpan, TokenStream, TokenTree, TreeAndSpacing};
 use rustc_data_structures::fx::FxHashMap;
-use rustc_data_structures::sync::Lrc;
 use rustc_errors::{pluralize, PResult};
 use rustc_errors::{DiagnosticBuilder, ErrorGuaranteed};
 use rustc_span::hygiene::{LocalExpnId, Transparency};
@@ -27,31 +26,35 @@ impl MutVisitor for Marker {
 }
 
 /// An iterator over the token trees in a delimited token tree (`{ ... }`) or a sequence (`$(...)`).
-enum Frame {
-    Delimited { forest: Lrc<mbe::Delimited>, idx: usize, span: DelimSpan },
-    Sequence { forest: Lrc<mbe::SequenceRepetition>, idx: usize, sep: Option<Token> },
+enum Frame<'a> {
+    Delimited {
+        tts: &'a [mbe::TokenTree],
+        delim_token: token::DelimToken,
+        idx: usize,
+        span: DelimSpan,
+    },
+    Sequence {
+        tts: &'a [mbe::TokenTree],
+        idx: usize,
+        sep: Option<Token>,
+    },
 }
 
-impl Frame {
+impl<'a> Frame<'a> {
     /// Construct a new frame around the delimited set of tokens.
-    fn new(tts: Vec<mbe::TokenTree>) -> Frame {
-        let forest = Lrc::new(mbe::Delimited { delim: token::NoDelim, tts });
-        Frame::Delimited { forest, idx: 0, span: DelimSpan::dummy() }
+    fn new(tts: &'a [mbe::TokenTree]) -> Frame<'a> {
+        Frame::Delimited { tts, delim_token: token::NoDelim, idx: 0, span: DelimSpan::dummy() }
     }
 }
 
-impl Iterator for Frame {
-    type Item = mbe::TokenTree;
+impl<'a> Iterator for Frame<'a> {
+    type Item = &'a mbe::TokenTree;
 
-    fn next(&mut self) -> Option<mbe::TokenTree> {
-        match *self {
-            Frame::Delimited { ref forest, ref mut idx, .. } => {
-                let res = forest.tts.get(*idx).cloned();
-                *idx += 1;
-                res
-            }
-            Frame::Sequence { ref forest, ref mut idx, .. } => {
-                let res = forest.tts.get(*idx).cloned();
+    fn next(&mut self) -> Option<&'a mbe::TokenTree> {
+        match self {
+            Frame::Delimited { tts, ref mut idx, .. }
+            | Frame::Sequence { tts, ref mut idx, .. } => {
+                let res = tts.get(*idx);
                 *idx += 1;
                 res
             }
@@ -92,7 +95,7 @@ pub(super) fn transcribe<'a>(
 
     // We descend into the RHS (`src`), expanding things as we go. This stack contains the things
     // we have yet to expand/are still expanding. We start the stack off with the whole RHS.
-    let mut stack: SmallVec<[Frame; 1]> = smallvec![Frame::new(src)];
+    let mut stack: SmallVec<[Frame<'_>; 1]> = smallvec![Frame::new(&src)];
 
     // As we descend in the RHS, we will need to be able to match nested sequences of matchers.
     // `repeats` keeps track of where we are in matching at each level, with the last element being
@@ -146,14 +149,14 @@ pub(super) fn transcribe<'a>(
                 // We are done processing a Delimited. If this is the top-level delimited, we are
                 // done. Otherwise, we unwind the result_stack to append what we have produced to
                 // any previous results.
-                Frame::Delimited { forest, span, .. } => {
+                Frame::Delimited { delim_token, span, .. } => {
                     if result_stack.is_empty() {
                         // No results left to compute! We are back at the top-level.
                         return Ok(TokenStream::new(result));
                     }
 
                     // Step back into the parent Delimited.
-                    let tree = TokenTree::Delimited(span, forest.delim, TokenStream::new(result));
+                    let tree = TokenTree::Delimited(span, delim_token, TokenStream::new(result));
                     result = result_stack.pop().unwrap();
                     result.push(tree.into());
                 }
@@ -167,7 +170,7 @@ pub(super) fn transcribe<'a>(
             // We are descending into a sequence. We first make sure that the matchers in the RHS
             // and the matches in `interp` have the same shape. Otherwise, either the caller or the
             // macro writer has made a mistake.
-            seq @ mbe::TokenTree::Sequence(..) => {
+            seq @ mbe::TokenTree::Sequence(_, delimited) => {
                 match lockstep_iter_size(&seq, interp, &repeats) {
                     LockstepIterSize::Unconstrained => {
                         return Err(cx.struct_span_err(
@@ -214,7 +217,7 @@ pub(super) fn transcribe<'a>(
                             stack.push(Frame::Sequence {
                                 idx: 0,
                                 sep: seq.separator.clone(),
-                                forest: seq,
+                                tts: &delimited.tts,
                             });
                         }
                     }
@@ -272,15 +275,21 @@ pub(super) fn transcribe<'a>(
             // the previous results (from outside the Delimited).
             mbe::TokenTree::Delimited(mut span, delimited) => {
                 mut_visit::visit_delim_span(&mut span, &mut marker);
-                stack.push(Frame::Delimited { forest: delimited, idx: 0, span });
+                stack.push(Frame::Delimited {
+                    tts: &delimited.tts,
+                    delim_token: delimited.delim,
+                    idx: 0,
+                    span,
+                });
                 result_stack.push(mem::take(&mut result));
             }
 
             // Nothing much to do here. Just push the token to the result, being careful to
             // preserve syntax context.
             mbe::TokenTree::Token(token) => {
-                let mut tt = TokenTree::Token(token);
-                mut_visit::visit_tt(&mut tt, &mut marker);
+                let mut token = token.clone();
+                mut_visit::visit_token(&mut token, &mut marker);
+                let tt = TokenTree::Token(token);
                 result.push(tt.into());
             }
 
@@ -516,7 +525,7 @@ fn out_of_bounds_err<'a>(
 
 fn transcribe_metavar_expr<'a>(
     cx: &ExtCtxt<'a>,
-    expr: MetaVarExpr,
+    expr: &MetaVarExpr,
     interp: &FxHashMap<MacroRulesNormalizedIdent, NamedMatch>,
     marker: &mut Marker,
     repeats: &[(usize, usize)],
@@ -528,7 +537,7 @@ fn transcribe_metavar_expr<'a>(
         marker.visit_span(&mut span);
         span
     };
-    match expr {
+    match *expr {
         MetaVarExpr::Count(original_ident, depth_opt) => {
             let matched = matched_from_ident(cx, original_ident, interp)?;
             let count = count_repetitions(cx, depth_opt, matched, &repeats, sp)?;