Unnamed repository; edit this file 'description' to name the repository.
Diffstat (limited to 'crates/mbe/src/expander/matcher.rs')
-rw-r--r--crates/mbe/src/expander/matcher.rs34
1 files changed, 22 insertions, 12 deletions
diff --git a/crates/mbe/src/expander/matcher.rs b/crates/mbe/src/expander/matcher.rs
index f4ea9e5c81..474826079d 100644
--- a/crates/mbe/src/expander/matcher.rs
+++ b/crates/mbe/src/expander/matcher.rs
@@ -111,8 +111,8 @@ impl Match {
}
/// Matching errors are added to the `Match`.
-pub(super) fn match_(pattern: &MetaTemplate, input: &tt::Subtree) -> Match {
- let mut res = match_loop(pattern, input);
+pub(super) fn match_(pattern: &MetaTemplate, input: &tt::Subtree, is_2021: bool) -> Match {
+ let mut res = match_loop(pattern, input, is_2021);
res.bound_count = count(res.bindings.bindings());
return res;
@@ -332,7 +332,7 @@ struct MatchState<'t> {
/// Cached result of meta variable parsing
meta_result: Option<(TtIter<'t>, ExpandResult<Option<Fragment>>)>,
- /// Is error occuried in this state, will `poised` to "parent"
+ /// Is error occurred in this state, will `poised` to "parent"
is_error: bool,
}
@@ -354,6 +354,7 @@ struct MatchState<'t> {
/// - `eof_items`: the set of items that would be valid if this was the EOF.
/// - `bb_items`: the set of items that are waiting for the black-box parser.
/// - `error_items`: the set of items in errors, used for error-resilient parsing
+#[inline]
fn match_loop_inner<'t>(
src: TtIter<'t>,
stack: &[TtIter<'t>],
@@ -364,6 +365,7 @@ fn match_loop_inner<'t>(
next_items: &mut Vec<MatchState<'t>>,
eof_items: &mut SmallVec<[MatchState<'t>; 1]>,
error_items: &mut SmallVec<[MatchState<'t>; 1]>,
+ is_2021: bool,
) {
macro_rules! try_push {
($items: expr, $it:expr) => {
@@ -474,7 +476,7 @@ fn match_loop_inner<'t>(
OpDelimited::Op(Op::Var { kind, name, .. }) => {
if let &Some(kind) = kind {
let mut fork = src.clone();
- let match_res = match_meta_var(kind, &mut fork);
+ let match_res = match_meta_var(kind, &mut fork, is_2021);
match match_res.err {
None => {
// Some meta variables are optional (e.g. vis)
@@ -565,7 +567,9 @@ fn match_loop_inner<'t>(
item.is_error = true;
error_items.push(item);
}
- OpDelimited::Op(Op::Ignore { .. } | Op::Index { .. }) => {}
+ OpDelimited::Op(Op::Ignore { .. } | Op::Index { .. } | Op::Count { .. }) => {
+ stdx::never!("metavariable expression in lhs found");
+ }
OpDelimited::Open => {
if matches!(src.peek_n(0), Some(tt::TokenTree::Subtree(..))) {
item.dot.next();
@@ -583,7 +587,7 @@ fn match_loop_inner<'t>(
}
}
-fn match_loop(pattern: &MetaTemplate, src: &tt::Subtree) -> Match {
+fn match_loop(pattern: &MetaTemplate, src: &tt::Subtree, is_2021: bool) -> Match {
let mut src = TtIter::new(src);
let mut stack: SmallVec<[TtIter<'_>; 1]> = SmallVec::new();
let mut res = Match::default();
@@ -622,6 +626,7 @@ fn match_loop(pattern: &MetaTemplate, src: &tt::Subtree) -> Match {
&mut next_items,
&mut eof_items,
&mut error_items,
+ is_2021,
);
stdx::always!(cur_items.is_empty());
@@ -731,14 +736,17 @@ fn match_loop(pattern: &MetaTemplate, src: &tt::Subtree) -> Match {
}
}
-fn match_meta_var(kind: MetaVarKind, input: &mut TtIter<'_>) -> ExpandResult<Option<Fragment>> {
+fn match_meta_var(
+ kind: MetaVarKind,
+ input: &mut TtIter<'_>,
+ is_2021: bool,
+) -> ExpandResult<Option<Fragment>> {
let fragment = match kind {
MetaVarKind::Path => parser::PrefixEntryPoint::Path,
MetaVarKind::Ty => parser::PrefixEntryPoint::Ty,
- // FIXME: These two should actually behave differently depending on the edition.
- //
- // https://doc.rust-lang.org/edition-guide/rust-2021/or-patterns-macro-rules.html
- MetaVarKind::Pat | MetaVarKind::PatParam => parser::PrefixEntryPoint::Pat,
+ MetaVarKind::Pat if is_2021 => parser::PrefixEntryPoint::PatTop,
+ MetaVarKind::Pat => parser::PrefixEntryPoint::Pat,
+ MetaVarKind::PatParam => parser::PrefixEntryPoint::Pat,
MetaVarKind::Stmt => parser::PrefixEntryPoint::Stmt,
MetaVarKind::Block => parser::PrefixEntryPoint::Block,
MetaVarKind::Meta => parser::PrefixEntryPoint::MetaItem,
@@ -805,7 +813,9 @@ fn collect_vars(collector_fun: &mut impl FnMut(SmolStr), pattern: &MetaTemplate)
Op::Var { name, .. } => collector_fun(name.clone()),
Op::Subtree { tokens, .. } => collect_vars(collector_fun, tokens),
Op::Repeat { tokens, .. } => collect_vars(collector_fun, tokens),
- Op::Ignore { .. } | Op::Index { .. } | Op::Literal(_) | Op::Ident(_) | Op::Punct(_) => {
+ Op::Literal(_) | Op::Ident(_) | Op::Punct(_) => {}
+ Op::Ignore { .. } | Op::Index { .. } | Op::Count { .. } => {
+ stdx::never!("metavariable expression in lhs found");
}
}
}