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.rs33
1 files changed, 18 insertions, 15 deletions
diff --git a/crates/mbe/src/expander/matcher.rs b/crates/mbe/src/expander/matcher.rs
index 8053a85934..40b4c7cdd6 100644
--- a/crates/mbe/src/expander/matcher.rs
+++ b/crates/mbe/src/expander/matcher.rs
@@ -63,7 +63,7 @@ use std::rc::Rc;
use smallvec::{smallvec, SmallVec};
use syntax::SmolStr;
-use tt::Span;
+use tt::{DelimSpan, Span};
use crate::{
expander::{Binding, Bindings, ExpandResult, Fragment},
@@ -74,11 +74,7 @@ use crate::{
impl<S: Span> Bindings<S> {
fn push_optional(&mut self, name: &SmolStr) {
- // FIXME: Do we have a better way to represent an empty token ?
- // Insert an empty subtree for empty token
- let tt =
- tt::Subtree { delimiter: tt::Delimiter::DUMMY_INVISIBLE, token_trees: vec![] }.into();
- self.inner.insert(name.clone(), Binding::Fragment(Fragment::Tokens(tt)));
+ self.inner.insert(name.clone(), Binding::Fragment(Fragment::Empty));
}
fn push_empty(&mut self, name: &SmolStr) {
@@ -387,6 +383,7 @@ fn match_loop_inner<'t, S: Span>(
eof_items: &mut SmallVec<[MatchState<'t, S>; 1]>,
error_items: &mut SmallVec<[MatchState<'t, S>; 1]>,
is_2021: bool,
+ delim_span: tt::DelimSpan<S>,
) {
macro_rules! try_push {
($items: expr, $it:expr) => {
@@ -474,7 +471,7 @@ fn match_loop_inner<'t, S: Span>(
cur_items.push(new_item);
}
cur_items.push(MatchState {
- dot: tokens.iter_delimited(None),
+ dot: tokens.iter_delimited(delim_span),
stack: Default::default(),
up: Some(Box::new(item)),
sep: separator.clone(),
@@ -489,7 +486,7 @@ fn match_loop_inner<'t, S: Span>(
if let Ok(subtree) = src.clone().expect_subtree() {
if subtree.delimiter.kind == delimiter.kind {
item.stack.push(item.dot);
- item.dot = tokens.iter_delimited(Some(*delimiter));
+ item.dot = tokens.iter_delimited_with(*delimiter);
cur_items.push(item);
}
}
@@ -497,7 +494,7 @@ fn match_loop_inner<'t, S: Span>(
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, is_2021);
+ let match_res = match_meta_var(kind, &mut fork, is_2021, delim_span);
match match_res.err {
None => {
// Some meta variables are optional (e.g. vis)
@@ -611,6 +608,7 @@ fn match_loop_inner<'t, S: Span>(
}
fn match_loop<S: Span>(pattern: &MetaTemplate<S>, src: &tt::Subtree<S>, is_2021: bool) -> Match<S> {
+ let span = src.delimiter.delim_span();
let mut src = TtIter::new(src);
let mut stack: SmallVec<[TtIter<'_, S>; 1]> = SmallVec::new();
let mut res = Match::default();
@@ -619,7 +617,7 @@ fn match_loop<S: Span>(pattern: &MetaTemplate<S>, src: &tt::Subtree<S>, is_2021:
let mut bindings_builder = BindingsBuilder::default();
let mut cur_items = smallvec![MatchState {
- dot: pattern.iter_delimited(None),
+ dot: pattern.iter_delimited(span),
stack: Default::default(),
up: None,
sep: None,
@@ -650,6 +648,7 @@ fn match_loop<S: Span>(pattern: &MetaTemplate<S>, src: &tt::Subtree<S>, is_2021:
&mut eof_items,
&mut error_items,
is_2021,
+ span,
);
stdx::always!(cur_items.is_empty());
@@ -763,12 +762,13 @@ fn match_meta_var<S: Span>(
kind: MetaVarKind,
input: &mut TtIter<'_, S>,
is_2021: bool,
+ delim_span: DelimSpan<S>,
) -> ExpandResult<Option<Fragment<S>>> {
let fragment = match kind {
MetaVarKind::Path => {
- return input
- .expect_fragment(parser::PrefixEntryPoint::Path)
- .map(|it| it.map(tt::TokenTree::subtree_or_wrap).map(Fragment::Path));
+ return input.expect_fragment(parser::PrefixEntryPoint::Path).map(|it| {
+ it.map(|it| tt::TokenTree::subtree_or_wrap(it, delim_span)).map(Fragment::Path)
+ });
}
MetaVarKind::Ty => parser::PrefixEntryPoint::Ty,
MetaVarKind::Pat if is_2021 => parser::PrefixEntryPoint::PatTop,
@@ -860,11 +860,14 @@ fn collect_vars<S: Span>(collector_fun: &mut impl FnMut(SmolStr), pattern: &Meta
}
}
impl<S: Span> MetaTemplate<S> {
- fn iter_delimited(&self, delimited: Option<tt::Delimiter<S>>) -> OpDelimitedIter<'_, S> {
+ fn iter_delimited_with(&self, delimiter: tt::Delimiter<S>) -> OpDelimitedIter<'_, S> {
+ OpDelimitedIter { inner: &self.0, idx: 0, delimited: delimiter }
+ }
+ fn iter_delimited(&self, span: tt::DelimSpan<S>) -> OpDelimitedIter<'_, S> {
OpDelimitedIter {
inner: &self.0,
idx: 0,
- delimited: delimited.unwrap_or(tt::Delimiter::DUMMY_INVISIBLE),
+ delimited: tt::Delimiter::invisible_delim_spanned(span),
}
}
}