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.rs160
1 files changed, 68 insertions, 92 deletions
diff --git a/crates/mbe/src/expander/matcher.rs b/crates/mbe/src/expander/matcher.rs
index eea92cfba4..3170834d54 100644
--- a/crates/mbe/src/expander/matcher.rs
+++ b/crates/mbe/src/expander/matcher.rs
@@ -62,8 +62,9 @@
use std::rc::Rc;
use smallvec::{smallvec, SmallVec};
+use span::Span;
use syntax::SmolStr;
-use tt::{DelimSpan, Span};
+use tt::DelimSpan;
use crate::{
expander::{Binding, Bindings, ExpandResult, Fragment},
@@ -72,7 +73,7 @@ use crate::{
ExpandError, MetaTemplate, ValueResult,
};
-impl<S: Span> Bindings<S> {
+impl Bindings {
fn push_optional(&mut self, name: &SmolStr) {
self.inner.insert(name.clone(), Binding::Fragment(Fragment::Empty));
}
@@ -81,14 +82,14 @@ impl<S: Span> Bindings<S> {
self.inner.insert(name.clone(), Binding::Empty);
}
- fn bindings(&self) -> impl Iterator<Item = &Binding<S>> {
+ fn bindings(&self) -> impl Iterator<Item = &Binding> {
self.inner.values()
}
}
-#[derive(Clone, Debug, PartialEq, Eq)]
-pub(super) struct Match<S> {
- pub(super) bindings: Bindings<S>,
+#[derive(Clone, Default, Debug, PartialEq, Eq)]
+pub(super) struct Match {
+ pub(super) bindings: Bindings,
/// We currently just keep the first error and count the rest to compare matches.
pub(super) err: Option<ExpandError>,
pub(super) err_count: usize,
@@ -98,19 +99,7 @@ pub(super) struct Match<S> {
pub(super) bound_count: usize,
}
-impl<S> Default for Match<S> {
- fn default() -> Self {
- Self {
- bindings: Default::default(),
- err: Default::default(),
- err_count: Default::default(),
- unmatched_tts: Default::default(),
- bound_count: Default::default(),
- }
- }
-}
-
-impl<S> Match<S> {
+impl Match {
fn add_err(&mut self, err: ExpandError) {
let prev_err = self.err.take();
self.err = prev_err.or(Some(err));
@@ -119,16 +108,12 @@ impl<S> Match<S> {
}
/// Matching errors are added to the `Match`.
-pub(super) fn match_<S: Span>(
- pattern: &MetaTemplate<S>,
- input: &tt::Subtree<S>,
- is_2021: bool,
-) -> Match<S> {
- let mut res = match_loop(pattern, input, is_2021);
+pub(super) fn match_(pattern: &MetaTemplate, input: &tt::Subtree<Span>) -> Match {
+ let mut res = match_loop(pattern, input);
res.bound_count = count(res.bindings.bindings());
return res;
- fn count<'a, S: 'a>(bindings: impl Iterator<Item = &'a Binding<S>>) -> usize {
+ fn count<'a>(bindings: impl Iterator<Item = &'a Binding>) -> usize {
bindings
.map(|it| match it {
Binding::Fragment(_) => 1,
@@ -141,10 +126,10 @@ pub(super) fn match_<S: Span>(
}
#[derive(Debug, Clone)]
-enum BindingKind<S> {
+enum BindingKind {
Empty(SmolStr),
Optional(SmolStr),
- Fragment(SmolStr, Fragment<S>),
+ Fragment(SmolStr, Fragment),
Missing(SmolStr, MetaVarKind),
Nested(usize, usize),
}
@@ -158,18 +143,13 @@ enum LinkNode<T> {
Parent { idx: usize, len: usize },
}
-struct BindingsBuilder<S> {
- nodes: Vec<Vec<LinkNode<Rc<BindingKind<S>>>>>,
+#[derive(Default)]
+struct BindingsBuilder {
+ nodes: Vec<Vec<LinkNode<Rc<BindingKind>>>>,
nested: Vec<Vec<LinkNode<usize>>>,
}
-impl<S> Default for BindingsBuilder<S> {
- fn default() -> Self {
- Self { nodes: Default::default(), nested: Default::default() }
- }
-}
-
-impl<S: Span> BindingsBuilder<S> {
+impl BindingsBuilder {
fn alloc(&mut self) -> BindingsIdx {
let idx = self.nodes.len();
self.nodes.push(Vec::new());
@@ -206,7 +186,7 @@ impl<S: Span> BindingsBuilder<S> {
self.nodes[idx.0].push(LinkNode::Node(Rc::new(BindingKind::Optional(var.clone()))));
}
- fn push_fragment(&mut self, idx: &mut BindingsIdx, var: &SmolStr, fragment: Fragment<S>) {
+ fn push_fragment(&mut self, idx: &mut BindingsIdx, var: &SmolStr, fragment: Fragment) {
self.nodes[idx.0]
.push(LinkNode::Node(Rc::new(BindingKind::Fragment(var.clone(), fragment))));
}
@@ -227,11 +207,11 @@ impl<S: Span> BindingsBuilder<S> {
idx.0 = new_idx;
}
- fn build(self, idx: &BindingsIdx) -> Bindings<S> {
+ fn build(self, idx: &BindingsIdx) -> Bindings {
self.build_inner(&self.nodes[idx.0])
}
- fn build_inner(&self, link_nodes: &[LinkNode<Rc<BindingKind<S>>>]) -> Bindings<S> {
+ fn build_inner(&self, link_nodes: &[LinkNode<Rc<BindingKind>>]) -> Bindings {
let mut bindings = Bindings::default();
let mut nodes = Vec::new();
self.collect_nodes(link_nodes, &mut nodes);
@@ -281,7 +261,7 @@ impl<S: Span> BindingsBuilder<S> {
&'a self,
id: usize,
len: usize,
- nested_refs: &mut Vec<&'a [LinkNode<Rc<BindingKind<S>>>]>,
+ nested_refs: &mut Vec<&'a [LinkNode<Rc<BindingKind>>]>,
) {
self.nested[id].iter().take(len).for_each(|it| match it {
LinkNode::Node(id) => nested_refs.push(&self.nodes[*id]),
@@ -289,7 +269,7 @@ impl<S: Span> BindingsBuilder<S> {
});
}
- fn collect_nested(&self, idx: usize, nested_idx: usize, nested: &mut Vec<Bindings<S>>) {
+ fn collect_nested(&self, idx: usize, nested_idx: usize, nested: &mut Vec<Bindings>) {
let last = &self.nodes[idx];
let mut nested_refs: Vec<&[_]> = Vec::new();
self.nested[nested_idx].iter().for_each(|it| match *it {
@@ -300,7 +280,7 @@ impl<S: Span> BindingsBuilder<S> {
nested.extend(nested_refs.into_iter().map(|iter| self.build_inner(iter)));
}
- fn collect_nodes_ref<'a>(&'a self, id: usize, len: usize, nodes: &mut Vec<&'a BindingKind<S>>) {
+ fn collect_nodes_ref<'a>(&'a self, id: usize, len: usize, nodes: &mut Vec<&'a BindingKind>) {
self.nodes[id].iter().take(len).for_each(|it| match it {
LinkNode::Node(it) => nodes.push(it),
LinkNode::Parent { idx, len } => self.collect_nodes_ref(*idx, *len, nodes),
@@ -309,8 +289,8 @@ impl<S: Span> BindingsBuilder<S> {
fn collect_nodes<'a>(
&'a self,
- link_nodes: &'a [LinkNode<Rc<BindingKind<S>>>],
- nodes: &mut Vec<&'a BindingKind<S>>,
+ link_nodes: &'a [LinkNode<Rc<BindingKind>>],
+ nodes: &mut Vec<&'a BindingKind>,
) {
link_nodes.iter().for_each(|it| match it {
LinkNode::Node(it) => nodes.push(it),
@@ -320,22 +300,22 @@ impl<S: Span> BindingsBuilder<S> {
}
#[derive(Debug, Clone)]
-struct MatchState<'t, S> {
+struct MatchState<'t> {
/// The position of the "dot" in this matcher
- dot: OpDelimitedIter<'t, S>,
+ dot: OpDelimitedIter<'t>,
/// Token subtree stack
/// When matching against matchers with nested delimited submatchers (e.g., `pat ( pat ( .. )
/// pat ) pat`), we need to keep track of the matchers we are descending into. This stack does
/// that where the bottom of the stack is the outermost matcher.
- stack: SmallVec<[OpDelimitedIter<'t, S>; 4]>,
+ stack: SmallVec<[OpDelimitedIter<'t>; 4]>,
/// The "parent" matcher position if we are in a repetition. That is, the matcher position just
/// before we enter the repetition.
- up: Option<Box<MatchState<'t, S>>>,
+ up: Option<Box<MatchState<'t>>>,
/// The separator if we are in a repetition.
- sep: Option<Separator<S>>,
+ sep: Option<Separator>,
/// The KleeneOp of this sequence if we are in a repetition.
sep_kind: Option<RepeatKind>,
@@ -347,7 +327,7 @@ struct MatchState<'t, S> {
bindings: BindingsIdx,
/// Cached result of meta variable parsing
- meta_result: Option<(TtIter<'t, S>, ExpandResult<Option<Fragment<S>>>)>,
+ meta_result: Option<(TtIter<'t, Span>, ExpandResult<Option<Fragment>>)>,
/// Is error occurred in this state, will `poised` to "parent"
is_error: bool,
@@ -372,18 +352,17 @@ struct MatchState<'t, S> {
/// - `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, S: Span>(
- src: TtIter<'t, S>,
- stack: &[TtIter<'t, S>],
- res: &mut Match<S>,
- bindings_builder: &mut BindingsBuilder<S>,
- cur_items: &mut SmallVec<[MatchState<'t, S>; 1]>,
- bb_items: &mut SmallVec<[MatchState<'t, S>; 1]>,
- next_items: &mut Vec<MatchState<'t, S>>,
- eof_items: &mut SmallVec<[MatchState<'t, S>; 1]>,
- error_items: &mut SmallVec<[MatchState<'t, S>; 1]>,
- is_2021: bool,
- delim_span: tt::DelimSpan<S>,
+fn match_loop_inner<'t>(
+ src: TtIter<'t, Span>,
+ stack: &[TtIter<'t, Span>],
+ res: &mut Match,
+ bindings_builder: &mut BindingsBuilder,
+ cur_items: &mut SmallVec<[MatchState<'t>; 1]>,
+ bb_items: &mut SmallVec<[MatchState<'t>; 1]>,
+ 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>,
) {
macro_rules! try_push {
($items: expr, $it:expr) => {
@@ -494,7 +473,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, delim_span);
+ let match_res = match_meta_var(kind, &mut fork, delim_span);
match match_res.err {
None => {
// Some meta variables are optional (e.g. vis)
@@ -607,10 +586,10 @@ fn match_loop_inner<'t, S: Span>(
}
}
-fn match_loop<S: Span>(pattern: &MetaTemplate<S>, src: &tt::Subtree<S>, is_2021: bool) -> Match<S> {
+fn match_loop(pattern: &MetaTemplate, src: &tt::Subtree<Span>) -> Match {
let span = src.delimiter.delim_span();
let mut src = TtIter::new(src);
- let mut stack: SmallVec<[TtIter<'_, S>; 1]> = SmallVec::new();
+ let mut stack: SmallVec<[TtIter<'_, Span>; 1]> = SmallVec::new();
let mut res = Match::default();
let mut error_recover_item = None;
@@ -647,7 +626,6 @@ fn match_loop<S: Span>(pattern: &MetaTemplate<S>, src: &tt::Subtree<S>, is_2021:
&mut next_items,
&mut eof_items,
&mut error_items,
- is_2021,
span,
);
stdx::always!(cur_items.is_empty());
@@ -758,12 +736,11 @@ fn match_loop<S: Span>(pattern: &MetaTemplate<S>, src: &tt::Subtree<S>, is_2021:
}
}
-fn match_meta_var<S: Span>(
+fn match_meta_var(
kind: MetaVarKind,
- input: &mut TtIter<'_, S>,
- is_2021: bool,
- delim_span: DelimSpan<S>,
-) -> ExpandResult<Option<Fragment<S>>> {
+ input: &mut TtIter<'_, Span>,
+ delim_span: DelimSpan<Span>,
+) -> ExpandResult<Option<Fragment>> {
let fragment = match kind {
MetaVarKind::Path => {
return input.expect_fragment(parser::PrefixEntryPoint::Path).map(|it| {
@@ -771,8 +748,7 @@ fn match_meta_var<S: Span>(
});
}
MetaVarKind::Ty => parser::PrefixEntryPoint::Ty,
- MetaVarKind::Pat if is_2021 => parser::PrefixEntryPoint::PatTop,
- MetaVarKind::Pat => parser::PrefixEntryPoint::Pat,
+ MetaVarKind::Pat => parser::PrefixEntryPoint::PatTop,
MetaVarKind::PatParam => parser::PrefixEntryPoint::Pat,
MetaVarKind::Stmt => parser::PrefixEntryPoint::Stmt,
MetaVarKind::Block => parser::PrefixEntryPoint::Block,
@@ -846,7 +822,7 @@ fn match_meta_var<S: Span>(
input.expect_fragment(fragment).map(|it| it.map(Fragment::Tokens))
}
-fn collect_vars<S: Span>(collector_fun: &mut impl FnMut(SmolStr), pattern: &MetaTemplate<S>) {
+fn collect_vars(collector_fun: &mut impl FnMut(SmolStr), pattern: &MetaTemplate) {
for op in pattern.iter() {
match op {
Op::Var { name, .. } => collector_fun(name.clone()),
@@ -859,11 +835,11 @@ fn collect_vars<S: Span>(collector_fun: &mut impl FnMut(SmolStr), pattern: &Meta
}
}
}
-impl<S: Span> MetaTemplate<S> {
- fn iter_delimited_with(&self, delimiter: tt::Delimiter<S>) -> OpDelimitedIter<'_, S> {
+impl MetaTemplate {
+ fn iter_delimited_with(&self, delimiter: tt::Delimiter<Span>) -> OpDelimitedIter<'_> {
OpDelimitedIter { inner: &self.0, idx: 0, delimited: delimiter }
}
- fn iter_delimited(&self, span: tt::DelimSpan<S>) -> OpDelimitedIter<'_, S> {
+ fn iter_delimited(&self, span: tt::DelimSpan<Span>) -> OpDelimitedIter<'_> {
OpDelimitedIter {
inner: &self.0,
idx: 0,
@@ -873,27 +849,27 @@ impl<S: Span> MetaTemplate<S> {
}
#[derive(Debug, Clone, Copy)]
-enum OpDelimited<'a, S> {
- Op(&'a Op<S>),
+enum OpDelimited<'a> {
+ Op(&'a Op),
Open,
Close,
}
#[derive(Debug, Clone, Copy)]
-struct OpDelimitedIter<'a, S> {
- inner: &'a [Op<S>],
- delimited: tt::Delimiter<S>,
+struct OpDelimitedIter<'a> {
+ inner: &'a [Op],
+ delimited: tt::Delimiter<Span>,
idx: usize,
}
-impl<'a, S: Span> OpDelimitedIter<'a, S> {
+impl<'a> OpDelimitedIter<'a> {
fn is_eof(&self) -> bool {
let len = self.inner.len()
+ if self.delimited.kind != tt::DelimiterKind::Invisible { 2 } else { 0 };
self.idx >= len
}
- fn peek(&self) -> Option<OpDelimited<'a, S>> {
+ fn peek(&self) -> Option<OpDelimited<'a>> {
match self.delimited.kind {
tt::DelimiterKind::Invisible => self.inner.get(self.idx).map(OpDelimited::Op),
_ => match self.idx {
@@ -909,8 +885,8 @@ impl<'a, S: Span> OpDelimitedIter<'a, S> {
}
}
-impl<'a, S: Span> Iterator for OpDelimitedIter<'a, S> {
- type Item = OpDelimited<'a, S>;
+impl<'a> Iterator for OpDelimitedIter<'a> {
+ type Item = OpDelimited<'a>;
fn next(&mut self) -> Option<Self::Item> {
let res = self.peek();
@@ -926,8 +902,8 @@ impl<'a, S: Span> Iterator for OpDelimitedIter<'a, S> {
}
}
-impl<S: Span> TtIter<'_, S> {
- fn expect_separator(&mut self, separator: &Separator<S>) -> bool {
+impl TtIter<'_, Span> {
+ fn expect_separator(&mut self, separator: &Separator) -> bool {
let mut fork = self.clone();
let ok = match separator {
Separator::Ident(lhs) => match fork.expect_ident_or_underscore() {
@@ -957,7 +933,7 @@ impl<S: Span> TtIter<'_, S> {
ok
}
- fn expect_tt(&mut self) -> Result<tt::TokenTree<S>, ()> {
+ fn expect_tt(&mut self) -> Result<tt::TokenTree<Span>, ()> {
if let Some(tt::TokenTree::Leaf(tt::Leaf::Punct(punct))) = self.peek_n(0) {
if punct.char == '\'' {
self.expect_lifetime()
@@ -976,7 +952,7 @@ impl<S: Span> TtIter<'_, S> {
}
}
- fn expect_lifetime(&mut self) -> Result<tt::TokenTree<S>, ()> {
+ fn expect_lifetime(&mut self) -> Result<tt::TokenTree<Span>, ()> {
let punct = self.expect_single_punct()?;
if punct.char != '\'' {
return Err(());
@@ -997,7 +973,7 @@ impl<S: Span> TtIter<'_, S> {
.into())
}
- fn eat_char(&mut self, c: char) -> Option<tt::TokenTree<S>> {
+ fn eat_char(&mut self, c: char) -> Option<tt::TokenTree<Span>> {
let mut fork = self.clone();
match fork.expect_char(c) {
Ok(_) => {