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.rs | 91 |
1 files changed, 48 insertions, 43 deletions
diff --git a/crates/mbe/src/expander/matcher.rs b/crates/mbe/src/expander/matcher.rs index 189efcd15c..8f6627a60f 100644 --- a/crates/mbe/src/expander/matcher.rs +++ b/crates/mbe/src/expander/matcher.rs @@ -63,7 +63,6 @@ use std::{rc::Rc, sync::Arc}; use intern::{Symbol, sym}; use smallvec::{SmallVec, smallvec}; -use span::{Edition, Span}; use tt::{ DelimSpan, iter::{TtElement, TtIter}, @@ -71,7 +70,7 @@ use tt::{ use crate::{ ExpandError, ExpandErrorKind, MetaTemplate, ValueResult, - expander::{Binding, Bindings, ExpandResult, Fragment}, + expander::{Binding, Bindings, ExpandResult, Fragment, TokensOrigin}, expect_fragment, parser::{ExprKind, MetaVarKind, Op, RepeatKind, Separator}, }; @@ -112,11 +111,11 @@ impl Match<'_> { /// Matching errors are added to the `Match`. pub(super) fn match_<'t>( + db: &dyn salsa::Database, pattern: &'t MetaTemplate, - input: &'t tt::TopSubtree<Span>, - edition: Edition, + input: &'t tt::TopSubtree, ) -> Match<'t> { - let mut res = match_loop(pattern, input, edition); + let mut res = match_loop(db, pattern, input); res.bound_count = count(res.bindings.bindings()); return res; @@ -339,7 +338,7 @@ struct MatchState<'t> { bindings: BindingsIdx, /// Cached result of meta variable parsing - meta_result: Option<(TtIter<'t, Span>, ExpandResult<Option<Fragment<'t>>>)>, + meta_result: Option<(TtIter<'t>, ExpandResult<Option<Fragment<'t>>>)>, /// Is error occurred in this state, will `poised` to "parent" is_error: bool, @@ -365,8 +364,9 @@ struct MatchState<'t> { /// - `error_items`: the set of items in errors, used for error-resilient parsing #[inline] fn match_loop_inner<'t>( - src: TtIter<'t, Span>, - stack: &[TtIter<'t, Span>], + db: &dyn salsa::Database, + src: TtIter<'t>, + stack: &[TtIter<'t>], res: &mut Match<'t>, bindings_builder: &mut BindingsBuilder<'t>, cur_items: &mut SmallVec<[MatchState<'t>; 1]>, @@ -374,8 +374,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]>, - delim_span: tt::DelimSpan<Span>, - edition: Edition, + delim_span: tt::DelimSpan, ) { macro_rules! try_push { ($items: expr, $it:expr) => { @@ -486,7 +485,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, delim_span, edition); + let match_res = match_meta_var(db, kind, &mut fork, delim_span); match match_res.err { None => { // Some meta variables are optional (e.g. vis) @@ -518,7 +517,8 @@ fn match_loop_inner<'t>( } OpDelimited::Op(Op::Literal(lhs)) => { if let Ok(rhs) = src.clone().expect_leaf() { - if matches!(rhs, tt::Leaf::Literal(it) if it.symbol == lhs.symbol) { + if matches!(&rhs, tt::Leaf::Literal(it) if it.text_and_suffix == lhs.text_and_suffix) + { item.dot.next(); } else { res.add_err(ExpandError::new( @@ -538,7 +538,7 @@ fn match_loop_inner<'t>( } OpDelimited::Op(Op::Ident(lhs)) => { if let Ok(rhs) = src.clone().expect_leaf() { - if matches!(rhs, tt::Leaf::Ident(it) if it.sym == lhs.sym) { + if matches!(&rhs, tt::Leaf::Ident(it) if it.sym == lhs.sym) { item.dot.next(); } else { res.add_err(ExpandError::new( @@ -621,13 +621,13 @@ fn match_loop_inner<'t>( } fn match_loop<'t>( + db: &dyn salsa::Database, pattern: &'t MetaTemplate, - src: &'t tt::TopSubtree<Span>, - edition: Edition, + src: &'t tt::TopSubtree, ) -> Match<'t> { let span = src.top_subtree().delimiter.delim_span(); let mut src = src.iter(); - let mut stack: SmallVec<[TtIter<'_, Span>; 1]> = SmallVec::new(); + let mut stack: SmallVec<[TtIter<'_>; 1]> = SmallVec::new(); let mut res = Match::default(); let mut error_recover_item = None; @@ -655,6 +655,7 @@ fn match_loop<'t>( stdx::always!(next_items.is_empty()); match_loop_inner( + db, src.clone(), &stack, &mut res, @@ -665,7 +666,6 @@ fn match_loop<'t>( &mut eof_items, &mut error_items, span, - edition, ); stdx::always!(cur_items.is_empty()); @@ -702,7 +702,7 @@ fn match_loop<'t>( || !(bb_items.is_empty() || next_items.is_empty()) || bb_items.len() > 1; if has_leftover_tokens { - res.unmatched_tts += src.remaining().flat_tokens().len(); + res.unmatched_tts += src.remaining().len(); res.add_err(ExpandError::new(span.open, ExpandErrorKind::LeftoverTokens)); if let Some(error_recover_item) = error_recover_item { @@ -772,14 +772,14 @@ fn match_loop<'t>( } fn match_meta_var<'t>( + db: &dyn salsa::Database, kind: MetaVarKind, - input: &mut TtIter<'t, Span>, - delim_span: DelimSpan<Span>, - edition: Edition, + input: &mut TtIter<'t>, + delim_span: DelimSpan, ) -> ExpandResult<Fragment<'t>> { let fragment = match kind { MetaVarKind::Path => { - return expect_fragment(input, parser::PrefixEntryPoint::Path, edition, delim_span) + return expect_fragment(db, input, parser::PrefixEntryPoint::Path, delim_span) .map(Fragment::Path); } MetaVarKind::Expr(expr) => { @@ -807,7 +807,7 @@ fn match_meta_var<'t>( } _ => {} }; - return expect_fragment(input, parser::PrefixEntryPoint::Expr, edition, delim_span) + return expect_fragment(db, input, parser::PrefixEntryPoint::Expr, delim_span) .map(Fragment::Expr); } MetaVarKind::Ident | MetaVarKind::Tt | MetaVarKind::Lifetime | MetaVarKind::Literal => { @@ -842,18 +842,23 @@ fn match_meta_var<'t>( } .err(); let tt_result = input.from_savepoint(savepoint); - return ValueResult { value: Fragment::Tokens(tt_result), err }; + return ValueResult { + value: Fragment::Tokens { tree: tt_result, origin: TokensOrigin::Raw }, + err, + }; } - MetaVarKind::Ty => parser::PrefixEntryPoint::Ty, - MetaVarKind::Pat => parser::PrefixEntryPoint::PatTop, - MetaVarKind::PatParam => parser::PrefixEntryPoint::Pat, - MetaVarKind::Stmt => parser::PrefixEntryPoint::Stmt, - MetaVarKind::Block => parser::PrefixEntryPoint::Block, - MetaVarKind::Meta => parser::PrefixEntryPoint::MetaItem, - MetaVarKind::Item => parser::PrefixEntryPoint::Item, - MetaVarKind::Vis => parser::PrefixEntryPoint::Vis, + MetaVarKind::Ty => (parser::PrefixEntryPoint::Ty, TokensOrigin::Ast), + MetaVarKind::Pat => (parser::PrefixEntryPoint::PatTop, TokensOrigin::Ast), + MetaVarKind::PatParam => (parser::PrefixEntryPoint::Pat, TokensOrigin::Ast), + MetaVarKind::Stmt => (parser::PrefixEntryPoint::Stmt, TokensOrigin::Ast), + MetaVarKind::Block => (parser::PrefixEntryPoint::Block, TokensOrigin::Ast), + MetaVarKind::Meta => (parser::PrefixEntryPoint::MetaItem, TokensOrigin::Ast), + MetaVarKind::Item => (parser::PrefixEntryPoint::Item, TokensOrigin::Ast), + MetaVarKind::Vis => (parser::PrefixEntryPoint::Vis, TokensOrigin::Ast), }; - expect_fragment(input, fragment, edition, delim_span).map(Fragment::Tokens) + let (entry_point, origin) = fragment; + expect_fragment(db, input, entry_point, delim_span) + .map(|tree| Fragment::Tokens { tree, origin }) } fn collect_vars(collector_fun: &mut impl FnMut(Symbol), pattern: &MetaTemplate) { @@ -874,10 +879,10 @@ fn collect_vars(collector_fun: &mut impl FnMut(Symbol), pattern: &MetaTemplate) } } impl MetaTemplate { - fn iter_delimited_with(&self, delimiter: tt::Delimiter<Span>) -> OpDelimitedIter<'_> { + fn iter_delimited_with(&self, delimiter: tt::Delimiter) -> OpDelimitedIter<'_> { OpDelimitedIter { inner: &self.0, idx: 0, delimited: delimiter } } - fn iter_delimited(&self, span: tt::DelimSpan<Span>) -> OpDelimitedIter<'_> { + fn iter_delimited(&self, span: tt::DelimSpan) -> OpDelimitedIter<'_> { OpDelimitedIter { inner: &self.0, idx: 0, @@ -896,7 +901,7 @@ enum OpDelimited<'a> { #[derive(Debug, Clone, Copy)] struct OpDelimitedIter<'a> { inner: &'a [Op], - delimited: tt::Delimiter<Span>, + delimited: tt::Delimiter, idx: usize, } @@ -940,7 +945,7 @@ impl<'a> Iterator for OpDelimitedIter<'a> { } } -fn expect_separator<S: Copy>(iter: &mut TtIter<'_, S>, separator: &Separator) -> bool { +fn expect_separator(iter: &mut TtIter<'_>, separator: &Separator) -> bool { let mut fork = iter.clone(); let ok = match separator { Separator::Ident(lhs) => match fork.expect_ident_or_underscore() { @@ -949,8 +954,8 @@ fn expect_separator<S: Copy>(iter: &mut TtIter<'_, S>, separator: &Separator) -> }, Separator::Literal(lhs) => match fork.expect_literal() { Ok(rhs) => match rhs { - tt::Leaf::Literal(rhs) => rhs.symbol == lhs.symbol, - tt::Leaf::Ident(rhs) => rhs.sym == lhs.symbol, + tt::Leaf::Literal(rhs) => rhs.text_and_suffix == lhs.text_and_suffix, + tt::Leaf::Ident(rhs) => rhs.sym == lhs.text_and_suffix, tt::Leaf::Punct(_) => false, }, Err(_) => false, @@ -974,7 +979,7 @@ fn expect_separator<S: Copy>(iter: &mut TtIter<'_, S>, separator: &Separator) -> ok } -fn expect_tt<S: Copy>(iter: &mut TtIter<'_, S>) -> Result<(), ()> { +fn expect_tt(iter: &mut TtIter<'_>) -> Result<(), ()> { if let Some(TtElement::Leaf(tt::Leaf::Punct(punct))) = iter.peek() { if punct.char == '\'' { expect_lifetime(iter)?; @@ -987,7 +992,7 @@ fn expect_tt<S: Copy>(iter: &mut TtIter<'_, S>) -> Result<(), ()> { Ok(()) } -fn expect_lifetime<'a, S: Copy>(iter: &mut TtIter<'a, S>) -> Result<&'a tt::Ident<S>, ()> { +fn expect_lifetime<'a>(iter: &mut TtIter<'a>) -> Result<tt::Ident, ()> { let punct = iter.expect_single_punct()?; if punct.char != '\'' { return Err(()); @@ -995,8 +1000,8 @@ fn expect_lifetime<'a, S: Copy>(iter: &mut TtIter<'a, S>) -> Result<&'a tt::Iden iter.expect_ident_or_underscore() } -fn eat_char<S: Copy>(iter: &mut TtIter<'_, S>, c: char) { - if matches!(iter.peek(), Some(TtElement::Leaf(tt::Leaf::Punct(tt::Punct { char, .. }))) if *char == c) +fn eat_char(iter: &mut TtIter<'_>, c: char) { + if matches!(iter.peek(), Some(TtElement::Leaf(tt::Leaf::Punct(tt::Punct { char, .. }))) if char == c) { iter.next().expect("already peeked"); } |