Unnamed repository; edit this file 'description' to name the repository.
Diffstat (limited to 'crates/mbe/src/expander.rs')
| -rw-r--r-- | crates/mbe/src/expander.rs | 42 |
1 files changed, 30 insertions, 12 deletions
diff --git a/crates/mbe/src/expander.rs b/crates/mbe/src/expander.rs index f910f9f9d7..25e05df7b7 100644 --- a/crates/mbe/src/expander.rs +++ b/crates/mbe/src/expander.rs @@ -7,20 +7,29 @@ mod transcriber; use intern::Symbol; use rustc_hash::FxHashMap; -use span::{Edition, Span}; +use span::Span; -use crate::{ExpandError, ExpandErrorKind, ExpandResult, MatchedArmIndex, parser::MetaVarKind}; +use crate::{ + ExpandError, ExpandErrorKind, ExpandResult, MacroCallStyle, MatchedArmIndex, + parser::MetaVarKind, +}; pub(crate) fn expand_rules( + db: &dyn salsa::Database, rules: &[crate::Rule], - input: &tt::TopSubtree<Span>, + input: &tt::TopSubtree, marker: impl Fn(&mut Span) + Copy, + call_style: MacroCallStyle, call_site: Span, - def_site_edition: Edition, -) -> ExpandResult<(tt::TopSubtree<Span>, MatchedArmIndex)> { +) -> ExpandResult<(tt::TopSubtree, MatchedArmIndex)> { let mut match_: Option<(matcher::Match<'_>, &crate::Rule, usize)> = None; for (idx, rule) in rules.iter().enumerate() { - let new_match = matcher::match_(&rule.lhs, input, def_site_edition); + // Skip any rules that aren't relevant to the call style (fn-like/attr/derive). + if call_style != rule.style { + continue; + } + + let new_match = matcher::match_(db, &rule.lhs, input); if new_match.err.is_none() { // If we find a rule that applies without errors, we're done. @@ -119,7 +128,10 @@ enum Fragment<'a> { #[default] Empty, /// token fragments are just copy-pasted into the output - Tokens(tt::TokenTreesView<'a, Span>), + Tokens { + tree: tt::TokenTreesView<'a>, + origin: TokensOrigin, + }, /// Expr ast fragments are surrounded with `()` on transcription to preserve precedence. /// Note that this impl is different from the one currently in `rustc` -- /// `rustc` doesn't translate fragments into token trees at all. @@ -129,7 +141,7 @@ enum Fragment<'a> { /// tricky to handle in the parser, and rustc doesn't handle those either. /// /// The span of the outer delimiters is marked on transcription. - Expr(tt::TokenTreesView<'a, Span>), + Expr(tt::TokenTreesView<'a>), /// There are roughly two types of paths: paths in expression context, where a /// separator `::` between an identifier and its following generic argument list /// is mandatory, and paths in type context, where `::` can be omitted. @@ -139,18 +151,24 @@ enum Fragment<'a> { /// and is trasncribed as an expression-context path, verbatim transcription /// would cause a syntax error. We need to fix it up just before transcribing; /// see `transcriber::fix_up_and_push_path_tt()`. - Path(tt::TokenTreesView<'a, Span>), - TokensOwned(tt::TopSubtree<Span>), + Path(tt::TokenTreesView<'a>), + TokensOwned(tt::TopSubtree), } impl Fragment<'_> { fn is_empty(&self) -> bool { match self { Fragment::Empty => true, - Fragment::Tokens(it) => it.len() == 0, + Fragment::Tokens { tree, .. } => tree.len() == 0, Fragment::Expr(it) => it.len() == 0, Fragment::Path(it) => it.len() == 0, - Fragment::TokensOwned(it) => it.0.is_empty(), + Fragment::TokensOwned(_) => false, // A `TopSubtree` is never empty } } } + +#[derive(Debug, Clone, Copy, PartialEq, Eq)] +enum TokensOrigin { + Raw, + Ast, +} |