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, idx: usize, span: DelimSpan }, - Sequence { forest: Lrc, idx: usize, sep: Option }, +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, + }, } -impl Frame { +impl<'a> Frame<'a> { /// Construct a new frame around the delimited set of tokens. - fn new(tts: Vec) -> 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 { - 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, 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)?;