Unnamed repository; edit this file 'description' to name the repository.
Diffstat (limited to 'crates/mbe/src/expander.rs')
| -rw-r--r-- | crates/mbe/src/expander.rs | 36 |
1 files changed, 20 insertions, 16 deletions
diff --git a/crates/mbe/src/expander.rs b/crates/mbe/src/expander.rs index 2f2c0aa6ff..cfad8bcc0b 100644 --- a/crates/mbe/src/expander.rs +++ b/crates/mbe/src/expander.rs @@ -6,10 +6,10 @@ mod matcher; mod transcriber; use rustc_hash::FxHashMap; -use span::Span; +use span::{Edition, Span}; use syntax::SmolStr; -use crate::{parser::MetaVarKind, ExpandError, ExpandResult}; +use crate::{parser::MetaVarKind, ExpandError, ExpandResult, MatchedArmIndex}; pub(crate) fn expand_rules( rules: &[crate::Rule], @@ -17,10 +17,11 @@ pub(crate) fn expand_rules( marker: impl Fn(&mut Span) + Copy, new_meta_vars: bool, call_site: Span, -) -> ExpandResult<tt::Subtree<Span>> { - let mut match_: Option<(matcher::Match, &crate::Rule)> = None; - for rule in rules { - let new_match = matcher::match_(&rule.lhs, input); + def_site_edition: Edition, +) -> ExpandResult<(tt::Subtree<Span>, MatchedArmIndex)> { + let mut match_: Option<(matcher::Match, &crate::Rule, usize)> = None; + for (idx, rule) in rules.iter().enumerate() { + let new_match = matcher::match_(&rule.lhs, input, def_site_edition); if new_match.err.is_none() { // If we find a rule that applies without errors, we're done. @@ -34,31 +35,34 @@ pub(crate) fn expand_rules( call_site, ); if transcribe_err.is_none() { - return ExpandResult::ok(value); + return ExpandResult::ok((value, Some(idx as u32))); } } // Use the rule if we matched more tokens, or bound variables count - if let Some((prev_match, _)) = &match_ { + if let Some((prev_match, _, _)) = &match_ { if (new_match.unmatched_tts, -(new_match.bound_count as i32)) < (prev_match.unmatched_tts, -(prev_match.bound_count as i32)) { - match_ = Some((new_match, rule)); + match_ = Some((new_match, rule, idx)); } } else { - match_ = Some((new_match, rule)); + match_ = Some((new_match, rule, idx)); } } - if let Some((match_, rule)) = match_ { + if let Some((match_, rule, idx)) = match_ { // if we got here, there was no match without errors let ExpandResult { value, err: transcribe_err } = transcriber::transcribe(&rule.rhs, &match_.bindings, marker, new_meta_vars, call_site); - ExpandResult { value, err: match_.err.or(transcribe_err) } + ExpandResult { value: (value, idx.try_into().ok()), err: match_.err.or(transcribe_err) } } else { ExpandResult::new( - tt::Subtree { - delimiter: tt::Delimiter::invisible_spanned(call_site), - token_trees: Box::new([]), - }, + ( + tt::Subtree { + delimiter: tt::Delimiter::invisible_spanned(call_site), + token_trees: Box::default(), + }, + None, + ), ExpandError::NoMatchingRule, ) } |