Unnamed repository; edit this file 'description' to name the repository.
Diffstat (limited to 'crates/mbe/src/lib.rs')
-rw-r--r--crates/mbe/src/lib.rs64
1 files changed, 31 insertions, 33 deletions
diff --git a/crates/mbe/src/lib.rs b/crates/mbe/src/lib.rs
index 62fdce3689..3a85351266 100644
--- a/crates/mbe/src/lib.rs
+++ b/crates/mbe/src/lib.rs
@@ -17,8 +17,8 @@ mod tt_iter;
#[cfg(test)]
mod benchmark;
+use span::{Edition, Span, SyntaxContextId};
use stdx::impl_from;
-use tt::Span;
use std::fmt;
@@ -127,32 +127,29 @@ impl fmt::Display for CountError {
/// `tt::TokenTree`, but there's a crucial difference: in macro rules, `$ident`
/// and `$()*` have special meaning (see `Var` and `Repeat` data structures)
#[derive(Clone, Debug, PartialEq, Eq)]
-pub struct DeclarativeMacro<S> {
- rules: Box<[Rule<S>]>,
- // This is used for correctly determining the behavior of the pat fragment
- // FIXME: This should be tracked by hygiene of the fragment identifier!
- is_2021: bool,
+pub struct DeclarativeMacro {
+ rules: Box<[Rule]>,
err: Option<Box<ParseError>>,
}
#[derive(Clone, Debug, PartialEq, Eq)]
-struct Rule<S> {
- lhs: MetaTemplate<S>,
- rhs: MetaTemplate<S>,
+struct Rule {
+ lhs: MetaTemplate,
+ rhs: MetaTemplate,
}
-impl<S: Span> DeclarativeMacro<S> {
- pub fn from_err(err: ParseError, is_2021: bool) -> DeclarativeMacro<S> {
- DeclarativeMacro { rules: Box::default(), is_2021, err: Some(Box::new(err)) }
+impl DeclarativeMacro {
+ pub fn from_err(err: ParseError) -> DeclarativeMacro {
+ DeclarativeMacro { rules: Box::default(), err: Some(Box::new(err)) }
}
/// The old, `macro_rules! m {}` flavor.
pub fn parse_macro_rules(
- tt: &tt::Subtree<S>,
- is_2021: bool,
+ tt: &tt::Subtree<Span>,
+ edition: impl Copy + Fn(SyntaxContextId) -> Edition,
// FIXME: Remove this once we drop support for rust 1.76 (defaults to true then)
new_meta_vars: bool,
- ) -> DeclarativeMacro<S> {
+ ) -> DeclarativeMacro {
// Note: this parsing can be implemented using mbe machinery itself, by
// matching against `$($lhs:tt => $rhs:tt);*` pattern, but implementing
// manually seems easier.
@@ -161,7 +158,7 @@ impl<S: Span> DeclarativeMacro<S> {
let mut err = None;
while src.len() > 0 {
- let rule = match Rule::parse(&mut src, true, new_meta_vars) {
+ let rule = match Rule::parse(edition, &mut src, true, new_meta_vars) {
Ok(it) => it,
Err(e) => {
err = Some(Box::new(e));
@@ -184,16 +181,16 @@ impl<S: Span> DeclarativeMacro<S> {
}
}
- DeclarativeMacro { rules: rules.into_boxed_slice(), is_2021, err }
+ DeclarativeMacro { rules: rules.into_boxed_slice(), err }
}
/// The new, unstable `macro m {}` flavor.
pub fn parse_macro2(
- tt: &tt::Subtree<S>,
- is_2021: bool,
+ tt: &tt::Subtree<Span>,
+ edition: impl Copy + Fn(SyntaxContextId) -> Edition,
// FIXME: Remove this once we drop support for rust 1.76 (defaults to true then)
new_meta_vars: bool,
- ) -> DeclarativeMacro<S> {
+ ) -> DeclarativeMacro {
let mut src = TtIter::new(tt);
let mut rules = Vec::new();
let mut err = None;
@@ -201,7 +198,7 @@ impl<S: Span> DeclarativeMacro<S> {
if tt::DelimiterKind::Brace == tt.delimiter.kind {
cov_mark::hit!(parse_macro_def_rules);
while src.len() > 0 {
- let rule = match Rule::parse(&mut src, true, new_meta_vars) {
+ let rule = match Rule::parse(edition, &mut src, true, new_meta_vars) {
Ok(it) => it,
Err(e) => {
err = Some(Box::new(e));
@@ -220,7 +217,7 @@ impl<S: Span> DeclarativeMacro<S> {
}
} else {
cov_mark::hit!(parse_macro_def_simple);
- match Rule::parse(&mut src, false, new_meta_vars) {
+ match Rule::parse(edition, &mut src, false, new_meta_vars) {
Ok(rule) => {
if src.len() != 0 {
err = Some(Box::new(ParseError::expected("remaining tokens in macro def")));
@@ -240,7 +237,7 @@ impl<S: Span> DeclarativeMacro<S> {
}
}
- DeclarativeMacro { rules: rules.into_boxed_slice(), is_2021, err }
+ DeclarativeMacro { rules: rules.into_boxed_slice(), err }
}
pub fn err(&self) -> Option<&ParseError> {
@@ -249,18 +246,19 @@ impl<S: Span> DeclarativeMacro<S> {
pub fn expand(
&self,
- tt: &tt::Subtree<S>,
- marker: impl Fn(&mut S) + Copy,
+ tt: &tt::Subtree<Span>,
+ marker: impl Fn(&mut Span) + Copy,
new_meta_vars: bool,
- call_site: S,
- ) -> ExpandResult<tt::Subtree<S>> {
- expander::expand_rules(&self.rules, tt, marker, self.is_2021, new_meta_vars, call_site)
+ call_site: Span,
+ ) -> ExpandResult<tt::Subtree<Span>> {
+ expander::expand_rules(&self.rules, tt, marker, new_meta_vars, call_site)
}
}
-impl<S: Span> Rule<S> {
+impl Rule {
fn parse(
- src: &mut TtIter<'_, S>,
+ edition: impl Copy + Fn(SyntaxContextId) -> Edition,
+ src: &mut TtIter<'_, Span>,
expect_arrow: bool,
new_meta_vars: bool,
) -> Result<Self, ParseError> {
@@ -271,14 +269,14 @@ impl<S: Span> Rule<S> {
}
let rhs = src.expect_subtree().map_err(|()| ParseError::expected("expected subtree"))?;
- let lhs = MetaTemplate::parse_pattern(lhs)?;
- let rhs = MetaTemplate::parse_template(rhs, new_meta_vars)?;
+ let lhs = MetaTemplate::parse_pattern(edition, lhs)?;
+ let rhs = MetaTemplate::parse_template(edition, rhs, new_meta_vars)?;
Ok(crate::Rule { lhs, rhs })
}
}
-fn validate<S: Span>(pattern: &MetaTemplate<S>) -> Result<(), ParseError> {
+fn validate(pattern: &MetaTemplate) -> Result<(), ParseError> {
for op in pattern.iter() {
match op {
Op::Subtree { tokens, .. } => validate(tokens)?,