aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_mbe/src/mbe_expander.rs
diff options
context:
space:
mode:
Diffstat (limited to 'crates/ra_mbe/src/mbe_expander.rs')
-rw-r--r--crates/ra_mbe/src/mbe_expander.rs22
1 files changed, 12 insertions, 10 deletions
diff --git a/crates/ra_mbe/src/mbe_expander.rs b/crates/ra_mbe/src/mbe_expander.rs
index 3c00e3b64..7adb70d45 100644
--- a/crates/ra_mbe/src/mbe_expander.rs
+++ b/crates/ra_mbe/src/mbe_expander.rs
@@ -16,10 +16,15 @@ pub(crate) fn expand(rules: &crate::MacroRules, input: &tt::Subtree) -> ExpandRe
16 16
17fn expand_rules(rules: &[crate::Rule], input: &tt::Subtree) -> ExpandResult<tt::Subtree> { 17fn expand_rules(rules: &[crate::Rule], input: &tt::Subtree) -> ExpandResult<tt::Subtree> {
18 let mut match_: Option<(matcher::Match, &crate::Rule)> = None; 18 let mut match_: Option<(matcher::Match, &crate::Rule)> = None;
19 let mut err = Some(ExpandError::NoMatchingRule);
20 for rule in rules { 19 for rule in rules {
21 let ExpandResult(new_match, bindings_err) = matcher::match_(&rule.lhs, input); 20 let new_match = match matcher::match_(&rule.lhs, input) {
22 if bindings_err.is_none() { 21 Ok(m) => m,
22 Err(_e) => {
23 // error in pattern parsing
24 continue;
25 }
26 };
27 if new_match.err.is_none() {
23 // If we find a rule that applies without errors, we're done. 28 // If we find a rule that applies without errors, we're done.
24 // Unconditionally returning the transcription here makes the 29 // Unconditionally returning the transcription here makes the
25 // `test_repeat_bad_var` test fail. 30 // `test_repeat_bad_var` test fail.
@@ -32,25 +37,22 @@ fn expand_rules(rules: &[crate::Rule], input: &tt::Subtree) -> ExpandResult<tt::
32 // Use the rule if we matched more tokens, or had fewer patterns left, 37 // Use the rule if we matched more tokens, or had fewer patterns left,
33 // or had no error 38 // or had no error
34 if let Some((prev_match, _)) = &match_ { 39 if let Some((prev_match, _)) = &match_ {
35 if (new_match.unmatched_tokens, new_match.unmatched_patterns) 40 if (new_match.unmatched_tts, new_match.err_count)
36 < (prev_match.unmatched_tokens, prev_match.unmatched_patterns) 41 < (prev_match.unmatched_tts, prev_match.err_count)
37 || err.is_some() && bindings_err.is_none()
38 { 42 {
39 match_ = Some((new_match, rule)); 43 match_ = Some((new_match, rule));
40 err = bindings_err;
41 } 44 }
42 } else { 45 } else {
43 match_ = Some((new_match, rule)); 46 match_ = Some((new_match, rule));
44 err = bindings_err;
45 } 47 }
46 } 48 }
47 if let Some((match_, rule)) = match_ { 49 if let Some((match_, rule)) = match_ {
48 // if we got here, there was no match without errors 50 // if we got here, there was no match without errors
49 let ExpandResult(result, transcribe_err) = 51 let ExpandResult(result, transcribe_err) =
50 transcriber::transcribe(&rule.rhs, &match_.bindings); 52 transcriber::transcribe(&rule.rhs, &match_.bindings);
51 ExpandResult(result, err.or(transcribe_err)) 53 ExpandResult(result, match_.err.or(transcribe_err))
52 } else { 54 } else {
53 ExpandResult(tt::Subtree::default(), err) 55 ExpandResult(tt::Subtree::default(), Some(ExpandError::NoMatchingRule))
54 } 56 }
55} 57}
56 58