From 218caa410aa38c29984be31a5229b9fa717560ee Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Wed, 17 Apr 2024 14:19:13 +0200 Subject: Merging upstream version 1.68.2+dfsg1. Signed-off-by: Daniel Baumann --- compiler/rustc_expand/src/mbe/diagnostics.rs | 67 +++++++++++++--- compiler/rustc_expand/src/mbe/macro_check.rs | 14 ++-- compiler/rustc_expand/src/mbe/macro_parser.rs | 37 +++++---- compiler/rustc_expand/src/mbe/macro_rules.rs | 110 ++++++++++++++++---------- compiler/rustc_expand/src/mbe/quoted.rs | 6 +- compiler/rustc_expand/src/mbe/transcribe.rs | 32 ++++---- 6 files changed, 170 insertions(+), 96 deletions(-) (limited to 'compiler/rustc_expand/src/mbe') diff --git a/compiler/rustc_expand/src/mbe/diagnostics.rs b/compiler/rustc_expand/src/mbe/diagnostics.rs index 197f05691..f469b2dae 100644 --- a/compiler/rustc_expand/src/mbe/diagnostics.rs +++ b/compiler/rustc_expand/src/mbe/diagnostics.rs @@ -43,7 +43,7 @@ pub(super) fn failed_to_match_macro<'cx>( return result; } - let Some((token, label, remaining_matcher)) = tracker.best_failure else { + let Some(BestFailure { token, msg: label, remaining_matcher, .. }) = tracker.best_failure else { return DummyResult::any(sp); }; @@ -95,12 +95,31 @@ struct CollectTrackerAndEmitter<'a, 'cx, 'matcher> { cx: &'a mut ExtCtxt<'cx>, remaining_matcher: Option<&'matcher MatcherLoc>, /// Which arm's failure should we report? (the one furthest along) - best_failure: Option<(Token, &'static str, MatcherLoc)>, + best_failure: Option, root_span: Span, result: Option>, } +struct BestFailure { + token: Token, + position_in_tokenstream: usize, + msg: &'static str, + remaining_matcher: MatcherLoc, +} + +impl BestFailure { + fn is_better_position(&self, position: usize) -> bool { + position > self.position_in_tokenstream + } +} + impl<'a, 'cx, 'matcher> Tracker<'matcher> for CollectTrackerAndEmitter<'a, 'cx, 'matcher> { + type Failure = (Token, usize, &'static str); + + fn build_failure(tok: Token, position: usize, msg: &'static str) -> Self::Failure { + (tok, position, msg) + } + fn before_match_loc(&mut self, parser: &TtParser, matcher: &'matcher MatcherLoc) { if self.remaining_matcher.is_none() || (parser.has_no_remaining_items_for_step() && *matcher != MatcherLoc::Eof) @@ -109,7 +128,7 @@ impl<'a, 'cx, 'matcher> Tracker<'matcher> for CollectTrackerAndEmitter<'a, 'cx, } } - fn after_arm(&mut self, result: &NamedParseResult) { + fn after_arm(&mut self, result: &NamedParseResult) { match result { Success(_) => { // Nonterminal parser recovery might turn failed matches into successful ones, @@ -119,18 +138,25 @@ impl<'a, 'cx, 'matcher> Tracker<'matcher> for CollectTrackerAndEmitter<'a, 'cx, "should not collect detailed info for successful macro match", ); } - Failure(token, msg) => match self.best_failure { - Some((ref best_token, _, _)) if best_token.span.lo() >= token.span.lo() => {} - _ => { - self.best_failure = Some(( - token.clone(), + Failure((token, approx_position, msg)) => { + debug!(?token, ?msg, "a new failure of an arm"); + + if self + .best_failure + .as_ref() + .map_or(true, |failure| failure.is_better_position(*approx_position)) + { + self.best_failure = Some(BestFailure { + token: token.clone(), + position_in_tokenstream: *approx_position, msg, - self.remaining_matcher + remaining_matcher: self + .remaining_matcher .expect("must have collected matcher already") .clone(), - )) + }) } - }, + } Error(err_sp, msg) => { let span = err_sp.substitute_dummy(self.root_span); self.cx.struct_span_err(span, msg).emit(); @@ -155,6 +181,21 @@ impl<'a, 'cx> CollectTrackerAndEmitter<'a, 'cx, '_> { } } +/// Currently used by macro_rules! compilation to extract a little information from the `Failure` case. +pub struct FailureForwarder; + +impl<'matcher> Tracker<'matcher> for FailureForwarder { + type Failure = (Token, usize, &'static str); + + fn build_failure(tok: Token, position: usize, msg: &'static str) -> Self::Failure { + (tok, position, msg) + } + + fn description() -> &'static str { + "failure-forwarder" + } +} + pub(super) fn emit_frag_parse_err( mut e: DiagnosticBuilder<'_, rustc_errors::ErrorGuaranteed>, parser: &Parser<'_>, @@ -178,12 +219,12 @@ pub(super) fn emit_frag_parse_err( ); if !e.span.is_dummy() { // early end of macro arm (#52866) - e.replace_span_with(parser.token.span.shrink_to_hi()); + e.replace_span_with(parser.token.span.shrink_to_hi(), true); } } if e.span.is_dummy() { // Get around lack of span in error (#30128) - e.replace_span_with(site_span); + e.replace_span_with(site_span, true); if !parser.sess.source_map().is_imported(arm_span) { e.span_label(arm_span, "in this macro arm"); } diff --git a/compiler/rustc_expand/src/mbe/macro_check.rs b/compiler/rustc_expand/src/mbe/macro_check.rs index 8994a2f78..5be134f4e 100644 --- a/compiler/rustc_expand/src/mbe/macro_check.rs +++ b/compiler/rustc_expand/src/mbe/macro_check.rs @@ -151,9 +151,9 @@ impl<'a, T> Iterator for &'a Stack<'a, T> { // Iterates from top to bottom of the stack. fn next(&mut self) -> Option<&'a T> { - match *self { + match self { Stack::Empty => None, - Stack::Push { ref top, ref prev } => { + Stack::Push { top, prev } => { *self = prev; Some(top) } @@ -437,8 +437,8 @@ fn check_nested_occurrences( // We check that the meta-variable is correctly used. check_occurrences(sess, node_id, tt, macros, binders, ops, valid); } - (NestedMacroState::MacroRulesNotName, &TokenTree::Delimited(_, ref del)) - | (NestedMacroState::MacroName, &TokenTree::Delimited(_, ref del)) + (NestedMacroState::MacroRulesNotName, TokenTree::Delimited(_, del)) + | (NestedMacroState::MacroName, TokenTree::Delimited(_, del)) if del.delim == Delimiter::Brace => { let macro_rules = state == NestedMacroState::MacroRulesNotName; @@ -468,7 +468,7 @@ fn check_nested_occurrences( // We check that the meta-variable is correctly used. check_occurrences(sess, node_id, tt, macros, binders, ops, valid); } - (NestedMacroState::MacroName, &TokenTree::Delimited(_, ref del)) + (NestedMacroState::MacroName, TokenTree::Delimited(_, del)) if del.delim == Delimiter::Parenthesis => { state = NestedMacroState::MacroNameParen; @@ -483,7 +483,7 @@ fn check_nested_occurrences( valid, ); } - (NestedMacroState::MacroNameParen, &TokenTree::Delimited(_, ref del)) + (NestedMacroState::MacroNameParen, TokenTree::Delimited(_, del)) if del.delim == Delimiter::Brace => { state = NestedMacroState::Empty; @@ -497,7 +497,7 @@ fn check_nested_occurrences( valid, ); } - (_, ref tt) => { + (_, tt) => { state = NestedMacroState::Empty; check_occurrences(sess, node_id, tt, macros, binders, ops, valid); } diff --git a/compiler/rustc_expand/src/mbe/macro_parser.rs b/compiler/rustc_expand/src/mbe/macro_parser.rs index d161868ed..2e199541b 100644 --- a/compiler/rustc_expand/src/mbe/macro_parser.rs +++ b/compiler/rustc_expand/src/mbe/macro_parser.rs @@ -305,12 +305,13 @@ enum EofMatcherPositions { } /// Represents the possible results of an attempted parse. -pub(crate) enum ParseResult { +pub(crate) enum ParseResult { /// Parsed successfully. Success(T), /// Arm failed to match. If the second parameter is `token::Eof`, it indicates an unexpected /// end of macro invocation. Otherwise, it indicates that no rules expected the given token. - Failure(Token, &'static str), + /// The usize is the approximate position of the token in the input token stream. + Failure(F), /// Fatal error (malformed macro?). Abort compilation. Error(rustc_span::Span, String), ErrorReported(ErrorGuaranteed), @@ -319,7 +320,7 @@ pub(crate) enum ParseResult { /// A `ParseResult` where the `Success` variant contains a mapping of /// `MacroRulesNormalizedIdent`s to `NamedMatch`es. This represents the mapping /// of metavars to the token trees they bind to. -pub(crate) type NamedParseResult = ParseResult; +pub(crate) type NamedParseResult = ParseResult; /// Contains a mapping of `MacroRulesNormalizedIdent`s to `NamedMatch`es. /// This represents the mapping of metavars to the token trees they bind to. @@ -455,8 +456,9 @@ impl TtParser { &mut self, matcher: &'matcher [MatcherLoc], token: &Token, + approx_position: usize, track: &mut T, - ) -> Option { + ) -> Option> { // Matcher positions that would be valid if the macro invocation was over now. Only // modified if `token == Eof`. let mut eof_mps = EofMatcherPositions::None; @@ -593,13 +595,14 @@ impl TtParser { EofMatcherPositions::Multiple => { Error(token.span, "ambiguity: multiple successful parses".to_string()) } - EofMatcherPositions::None => Failure( + EofMatcherPositions::None => Failure(T::build_failure( Token::new( token::Eof, if token.span.is_dummy() { token.span } else { token.span.shrink_to_hi() }, ), + approx_position, "missing tokens in macro arguments", - ), + )), }) } else { None @@ -612,7 +615,7 @@ impl TtParser { parser: &mut Cow<'_, Parser<'_>>, matcher: &'matcher [MatcherLoc], track: &mut T, - ) -> NamedParseResult { + ) -> NamedParseResult { // A queue of possible matcher positions. We initialize it with the matcher position in // which the "dot" is before the first token of the first token tree in `matcher`. // `parse_tt_inner` then processes all of these possible matcher positions and produces @@ -627,7 +630,12 @@ impl TtParser { // Process `cur_mps` until either we have finished the input or we need to get some // parsing from the black-box parser done. - let res = self.parse_tt_inner(matcher, &parser.token, track); + let res = self.parse_tt_inner( + matcher, + &parser.token, + parser.approx_token_stream_pos(), + track, + ); if let Some(res) = res { return res; } @@ -640,10 +648,11 @@ impl TtParser { (0, 0) => { // There are no possible next positions AND we aren't waiting for the black-box // parser: syntax error. - return Failure( + return Failure(T::build_failure( parser.token.clone(), + parser.approx_token_stream_pos(), "no rules expected this token in macro call", - ); + )); } (_, 0) => { @@ -702,11 +711,11 @@ impl TtParser { } } - fn ambiguity_error( + fn ambiguity_error( &self, matcher: &[MatcherLoc], token_span: rustc_span::Span, - ) -> NamedParseResult { + ) -> NamedParseResult { let nts = self .bb_mps .iter() @@ -732,11 +741,11 @@ impl TtParser { ) } - fn nameize>( + fn nameize, F>( &self, matcher: &[MatcherLoc], mut res: I, - ) -> NamedParseResult { + ) -> NamedParseResult { // Make that each metavar has _exactly one_ binding. If so, insert the binding into the // `NamedParseResult`. Otherwise, it's an error. let mut ret_val = FxHashMap::default(); diff --git a/compiler/rustc_expand/src/mbe/macro_rules.rs b/compiler/rustc_expand/src/mbe/macro_rules.rs index 2dbb90e21..4ebd75f01 100644 --- a/compiler/rustc_expand/src/mbe/macro_rules.rs +++ b/compiler/rustc_expand/src/mbe/macro_rules.rs @@ -141,31 +141,40 @@ fn trace_macros_note(cx_expansions: &mut FxIndexMap>, sp: Span } pub(super) trait Tracker<'matcher> { + /// The contents of `ParseResult::Failure`. + type Failure; + + /// Arm failed to match. If the token is `token::Eof`, it indicates an unexpected + /// end of macro invocation. Otherwise, it indicates that no rules expected the given token. + /// The usize is the approximate position of the token in the input token stream. + fn build_failure(tok: Token, position: usize, msg: &'static str) -> Self::Failure; + /// This is called before trying to match next MatcherLoc on the current token. - fn before_match_loc(&mut self, parser: &TtParser, matcher: &'matcher MatcherLoc); + fn before_match_loc(&mut self, _parser: &TtParser, _matcher: &'matcher MatcherLoc) {} /// This is called after an arm has been parsed, either successfully or unsuccessfully. When this is called, /// `before_match_loc` was called at least once (with a `MatcherLoc::Eof`). - fn after_arm(&mut self, result: &NamedParseResult); + fn after_arm(&mut self, _result: &NamedParseResult) {} /// For tracing. fn description() -> &'static str; - fn recovery() -> Recovery; + fn recovery() -> Recovery { + Recovery::Forbidden + } } /// A noop tracker that is used in the hot path of the expansion, has zero overhead thanks to monomorphization. pub(super) struct NoopTracker; impl<'matcher> Tracker<'matcher> for NoopTracker { - fn before_match_loc(&mut self, _: &TtParser, _: &'matcher MatcherLoc) {} - fn after_arm(&mut self, _: &NamedParseResult) {} + type Failure = (); + + fn build_failure(_tok: Token, _position: usize, _msg: &'static str) -> Self::Failure {} + fn description() -> &'static str { "none" } - fn recovery() -> Recovery { - Recovery::Forbidden - } } /// Expands the rules based macro defined by `lhses` and `rhses` for a given @@ -326,7 +335,7 @@ pub(super) fn try_match_macro<'matcher, T: Tracker<'matcher>>( return Ok((i, named_matches)); } - Failure(_, _) => { + Failure(_) => { trace!("Failed to match arm, trying the next one"); // Try the next arm. } @@ -381,11 +390,13 @@ pub fn compile_declarative_macro( let rhs_nm = Ident::new(sym::rhs, def.span); let tt_spec = Some(NonterminalKind::TT); - // Parse the macro_rules! invocation - let (macro_rules, body) = match &def.kind { - ast::ItemKind::MacroDef(def) => (def.macro_rules, def.body.tokens.clone()), + let macro_def = match &def.kind { + ast::ItemKind::MacroDef(def) => def, _ => unreachable!(), }; + let macro_rules = macro_def.macro_rules; + + // Parse the macro_rules! invocation // The pattern that macro_rules matches. // The grammar for macro_rules! is: @@ -426,13 +437,32 @@ pub fn compile_declarative_macro( // Convert it into `MatcherLoc` form. let argument_gram = mbe::macro_parser::compute_locs(&argument_gram); - let parser = Parser::new(&sess.parse_sess, body, true, rustc_parse::MACRO_ARGUMENTS); + let create_parser = || { + let body = macro_def.body.tokens.clone(); + Parser::new(&sess.parse_sess, body, true, rustc_parse::MACRO_ARGUMENTS) + }; + + let parser = create_parser(); let mut tt_parser = TtParser::new(Ident::with_dummy_span(if macro_rules { kw::MacroRules } else { kw::Macro })); let argument_map = match tt_parser.parse_tt(&mut Cow::Owned(parser), &argument_gram, &mut NoopTracker) { Success(m) => m, - Failure(token, msg) => { + Failure(()) => { + // The fast `NoopTracker` doesn't have any info on failure, so we need to retry it with another one + // that gives us the information we need. + // For this we need to reclone the macro body as the previous parser consumed it. + let retry_parser = create_parser(); + + let parse_result = tt_parser.parse_tt( + &mut Cow::Owned(retry_parser), + &argument_gram, + &mut diagnostics::FailureForwarder, + ); + let Failure((token, _, msg)) = parse_result else { + unreachable!("matcher returned something other than Failure after retry"); + }; + let s = parse_failure_msg(&token); let sp = token.span.substitute_dummy(def.span); let mut err = sess.parse_sess.span_diagnostic.struct_span_err(sp, &s); @@ -456,11 +486,11 @@ pub fn compile_declarative_macro( let mut valid = true; // Extract the arguments: - let lhses = match argument_map[&MacroRulesNormalizedIdent::new(lhs_nm)] { - MatchedSeq(ref s) => s + let lhses = match &argument_map[&MacroRulesNormalizedIdent::new(lhs_nm)] { + MatchedSeq(s) => s .iter() .map(|m| { - if let MatchedTokenTree(ref tt) = *m { + if let MatchedTokenTree(tt) = m { let tt = mbe::quoted::parse( TokenStream::new(vec![tt.clone()]), true, @@ -480,11 +510,11 @@ pub fn compile_declarative_macro( _ => sess.parse_sess.span_diagnostic.span_bug(def.span, "wrong-structured lhs"), }; - let rhses = match argument_map[&MacroRulesNormalizedIdent::new(rhs_nm)] { - MatchedSeq(ref s) => s + let rhses = match &argument_map[&MacroRulesNormalizedIdent::new(rhs_nm)] { + MatchedSeq(s) => s .iter() .map(|m| { - if let MatchedTokenTree(ref tt) = *m { + if let MatchedTokenTree(tt) = m { return mbe::quoted::parse( TokenStream::new(vec![tt.clone()]), false, @@ -594,21 +624,21 @@ fn check_lhs_nt_follows(sess: &ParseSess, def: &ast::Item, lhs: &mbe::TokenTree) fn check_lhs_no_empty_seq(sess: &ParseSess, tts: &[mbe::TokenTree]) -> bool { use mbe::TokenTree; for tt in tts { - match *tt { + match tt { TokenTree::Token(..) | TokenTree::MetaVar(..) | TokenTree::MetaVarDecl(..) | TokenTree::MetaVarExpr(..) => (), - TokenTree::Delimited(_, ref del) => { + TokenTree::Delimited(_, del) => { if !check_lhs_no_empty_seq(sess, &del.tts) { return false; } } - TokenTree::Sequence(span, ref seq) => { + TokenTree::Sequence(span, seq) => { if seq.separator.is_none() - && seq.tts.iter().all(|seq_tt| match *seq_tt { + && seq.tts.iter().all(|seq_tt| match seq_tt { TokenTree::MetaVarDecl(_, _, Some(NonterminalKind::Vis)) => true, - TokenTree::Sequence(_, ref sub_seq) => { + TokenTree::Sequence(_, sub_seq) => { sub_seq.kleene.op == mbe::KleeneOp::ZeroOrMore || sub_seq.kleene.op == mbe::KleeneOp::ZeroOrOne } @@ -706,21 +736,21 @@ impl<'tt> FirstSets<'tt> { fn build_recur<'tt>(sets: &mut FirstSets<'tt>, tts: &'tt [TokenTree]) -> TokenSet<'tt> { let mut first = TokenSet::empty(); for tt in tts.iter().rev() { - match *tt { + match tt { TokenTree::Token(..) | TokenTree::MetaVar(..) | TokenTree::MetaVarDecl(..) | TokenTree::MetaVarExpr(..) => { first.replace_with(TtHandle::TtRef(tt)); } - TokenTree::Delimited(span, ref delimited) => { + TokenTree::Delimited(span, delimited) => { build_recur(sets, &delimited.tts); first.replace_with(TtHandle::from_token_kind( token::OpenDelim(delimited.delim), span.open, )); } - TokenTree::Sequence(sp, ref seq_rep) => { + TokenTree::Sequence(sp, seq_rep) => { let subfirst = build_recur(sets, &seq_rep.tts); match sets.first.entry(sp.entire()) { @@ -774,7 +804,7 @@ impl<'tt> FirstSets<'tt> { let mut first = TokenSet::empty(); for tt in tts.iter() { assert!(first.maybe_empty); - match *tt { + match tt { TokenTree::Token(..) | TokenTree::MetaVar(..) | TokenTree::MetaVarDecl(..) @@ -782,17 +812,17 @@ impl<'tt> FirstSets<'tt> { first.add_one(TtHandle::TtRef(tt)); return first; } - TokenTree::Delimited(span, ref delimited) => { + TokenTree::Delimited(span, delimited) => { first.add_one(TtHandle::from_token_kind( token::OpenDelim(delimited.delim), span.open, )); return first; } - TokenTree::Sequence(sp, ref seq_rep) => { + TokenTree::Sequence(sp, seq_rep) => { let subfirst_owned; let subfirst = match self.first.get(&sp.entire()) { - Some(&Some(ref subfirst)) => subfirst, + Some(Some(subfirst)) => subfirst, Some(&None) => { subfirst_owned = self.first(&seq_rep.tts); &subfirst_owned @@ -1011,7 +1041,7 @@ fn check_matcher_core<'tt>( // First, update `last` so that it corresponds to the set // of NT tokens that might end the sequence `... token`. - match *token { + match token { TokenTree::Token(..) | TokenTree::MetaVar(..) | TokenTree::MetaVarDecl(..) @@ -1027,7 +1057,7 @@ fn check_matcher_core<'tt>( suffix_first = build_suffix_first(); } } - TokenTree::Delimited(span, ref d) => { + TokenTree::Delimited(span, d) => { let my_suffix = TokenSet::singleton(TtHandle::from_token_kind( token::CloseDelim(d.delim), span.close, @@ -1040,7 +1070,7 @@ fn check_matcher_core<'tt>( // against SUFFIX continue 'each_token; } - TokenTree::Sequence(_, ref seq_rep) => { + TokenTree::Sequence(_, seq_rep) => { suffix_first = build_suffix_first(); // The trick here: when we check the interior, we want // to include the separator (if any) as a potential @@ -1166,11 +1196,7 @@ fn check_matcher_core<'tt>( err.note(&format!( "{}{} or {}", msg, - ts[..ts.len() - 1] - .iter() - .copied() - .collect::>() - .join(", "), + ts[..ts.len() - 1].to_vec().join(", "), ts[ts.len() - 1], )); } @@ -1346,8 +1372,8 @@ fn is_in_follow(tok: &mbe::TokenTree, kind: NonterminalKind) -> IsInFollow { } fn quoted_tt_to_string(tt: &mbe::TokenTree) -> String { - match *tt { - mbe::TokenTree::Token(ref token) => pprust::token_to_string(&token).into(), + match tt { + mbe::TokenTree::Token(token) => pprust::token_to_string(&token).into(), mbe::TokenTree::MetaVar(_, name) => format!("${}", name), mbe::TokenTree::MetaVarDecl(_, name, Some(kind)) => format!("${}:{}", name, kind), mbe::TokenTree::MetaVarDecl(_, name, None) => format!("${}:", name), diff --git a/compiler/rustc_expand/src/mbe/quoted.rs b/compiler/rustc_expand/src/mbe/quoted.rs index ee17d54f6..bc298b0ad 100644 --- a/compiler/rustc_expand/src/mbe/quoted.rs +++ b/compiler/rustc_expand/src/mbe/quoted.rs @@ -171,7 +171,7 @@ fn parse_tree( } else { match delim { Delimiter::Brace => { - // The delimiter is `{`. This indicates the beginning + // The delimiter is `{`. This indicates the beginning // of a meta-variable expression (e.g. `${count(ident)}`). // Try to parse the meta-variable expression. match MetaVarExpr::parse(&tts, delim_span.entire(), sess) { @@ -200,7 +200,7 @@ fn parse_tree( } } // If we didn't find a metavar expression above, then we must have a - // repetition sequence in the macro (e.g. `$(pat)*`). Parse the + // repetition sequence in the macro (e.g. `$(pat)*`). Parse the // contents of the sequence itself let sequence = parse(tts, parsing_patterns, sess, node_id, features, edition); // Get the Kleene operator and optional separator @@ -356,7 +356,7 @@ fn parse_sep_and_kleene_op( // `$$` or a meta-variable is the lhs of a macro but shouldn't. // // For example, `macro_rules! foo { ( ${length()} ) => {} }` -fn span_dollar_dollar_or_metavar_in_the_lhs_err<'sess>(sess: &'sess ParseSess, token: &Token) { +fn span_dollar_dollar_or_metavar_in_the_lhs_err(sess: &ParseSess, token: &Token) { sess.span_diagnostic .span_err(token.span, &format!("unexpected token: {}", pprust::token_to_string(token))); sess.span_diagnostic.span_note_without_error( diff --git a/compiler/rustc_expand/src/mbe/transcribe.rs b/compiler/rustc_expand/src/mbe/transcribe.rs index bec6d1a2d..b79835be7 100644 --- a/compiler/rustc_expand/src/mbe/transcribe.rs +++ b/compiler/rustc_expand/src/mbe/transcribe.rs @@ -47,8 +47,7 @@ impl<'a> Iterator for Frame<'a> { fn next(&mut self) -> Option<&'a mbe::TokenTree> { match self { - Frame::Delimited { tts, ref mut idx, .. } - | Frame::Sequence { tts, ref mut idx, .. } => { + Frame::Delimited { tts, idx, .. } | Frame::Sequence { tts, idx, .. } => { let res = tts.get(*idx); *idx += 1; res @@ -220,13 +219,13 @@ pub(super) fn transcribe<'a>( let ident = MacroRulesNormalizedIdent::new(original_ident); if let Some(cur_matched) = lookup_cur_matched(ident, interp, &repeats) { match cur_matched { - MatchedTokenTree(ref tt) => { + MatchedTokenTree(tt) => { // `tt`s are emitted into the output stream directly as "raw tokens", // without wrapping them into groups. let token = tt.clone(); result.push(token); } - MatchedNonterminal(ref nt) => { + MatchedNonterminal(nt) => { // Other variables are emitted into the output stream as groups with // `Delimiter::Invisible` to maintain parsing priorities. // `Interpolated` is currently used for such groups in rustc parser. @@ -299,12 +298,11 @@ fn lookup_cur_matched<'a>( interpolations: &'a FxHashMap, repeats: &[(usize, usize)], ) -> Option<&'a NamedMatch> { - interpolations.get(&ident).map(|matched| { - let mut matched = matched; + interpolations.get(&ident).map(|mut matched| { for &(idx, _) in repeats { match matched { MatchedTokenTree(_) | MatchedNonterminal(_) => break, - MatchedSeq(ref ads) => matched = ads.get(idx).unwrap(), + MatchedSeq(ads) => matched = ads.get(idx).unwrap(), } } @@ -339,7 +337,7 @@ impl LockstepIterSize { match self { LockstepIterSize::Unconstrained => other, LockstepIterSize::Contradiction(_) => self, - LockstepIterSize::Constraint(l_len, ref l_id) => match other { + LockstepIterSize::Constraint(l_len, l_id) => match other { LockstepIterSize::Unconstrained => self, LockstepIterSize::Contradiction(_) => other, LockstepIterSize::Constraint(r_len, _) if l_len == r_len => self, @@ -378,33 +376,33 @@ fn lockstep_iter_size( repeats: &[(usize, usize)], ) -> LockstepIterSize { use mbe::TokenTree; - match *tree { - TokenTree::Delimited(_, ref delimited) => { + match tree { + TokenTree::Delimited(_, delimited) => { delimited.tts.iter().fold(LockstepIterSize::Unconstrained, |size, tt| { size.with(lockstep_iter_size(tt, interpolations, repeats)) }) } - TokenTree::Sequence(_, ref seq) => { + TokenTree::Sequence(_, seq) => { seq.tts.iter().fold(LockstepIterSize::Unconstrained, |size, tt| { size.with(lockstep_iter_size(tt, interpolations, repeats)) }) } TokenTree::MetaVar(_, name) | TokenTree::MetaVarDecl(_, name, _) => { - let name = MacroRulesNormalizedIdent::new(name); + let name = MacroRulesNormalizedIdent::new(*name); match lookup_cur_matched(name, interpolations, repeats) { Some(matched) => match matched { MatchedTokenTree(_) | MatchedNonterminal(_) => LockstepIterSize::Unconstrained, - MatchedSeq(ref ads) => LockstepIterSize::Constraint(ads.len(), name), + MatchedSeq(ads) => LockstepIterSize::Constraint(ads.len(), name), }, _ => LockstepIterSize::Unconstrained, } } - TokenTree::MetaVarExpr(_, ref expr) => { + TokenTree::MetaVarExpr(_, expr) => { let default_rslt = LockstepIterSize::Unconstrained; let Some(ident) = expr.ident() else { return default_rslt; }; let name = MacroRulesNormalizedIdent::new(ident); match lookup_cur_matched(name, interpolations, repeats) { - Some(MatchedSeq(ref ads)) => { + Some(MatchedSeq(ads)) => { default_rslt.with(LockstepIterSize::Constraint(ads.len(), name)) } _ => default_rslt, @@ -449,7 +447,7 @@ fn count_repetitions<'a>( Some(_) => Err(out_of_bounds_err(cx, declared_lhs_depth, sp.entire(), "count")), } } - MatchedSeq(ref named_matches) => { + MatchedSeq(named_matches) => { let new_declared_lhs_depth = declared_lhs_depth + 1; match depth_opt { None => named_matches @@ -472,7 +470,7 @@ fn count_repetitions<'a>( // before we start counting. `matched` contains the various levels of the // tree as we descend, and its final value is the subtree we are currently at. for &(idx, _) in repeats { - if let MatchedSeq(ref ads) = matched { + if let MatchedSeq(ads) = matched { matched = &ads[idx]; } } -- cgit v1.2.3