Unnamed repository; edit this file 'description' to name the repository.
Diffstat (limited to 'crates/mbe/src/parser.rs')
-rw-r--r--crates/mbe/src/parser.rs29
1 files changed, 28 insertions, 1 deletions
diff --git a/crates/mbe/src/parser.rs b/crates/mbe/src/parser.rs
index 711101260a..e1cb98abae 100644
--- a/crates/mbe/src/parser.rs
+++ b/crates/mbe/src/parser.rs
@@ -11,7 +11,34 @@ use tt::{
iter::{TtElement, TtIter},
};
-use crate::ParseError;
+use crate::{MacroCallStyle, ParseError};
+
+pub(crate) fn parse_rule_style(src: &mut TtIter<'_, Span>) -> Result<MacroCallStyle, ParseError> {
+ // Skip an optional `unsafe`. This is only actually allowed for `attr`
+ // rules, but we'll let rustc worry about that.
+ if let Some(TtElement::Leaf(tt::Leaf::Ident(ident))) = src.peek()
+ && ident.sym == sym::unsafe_
+ {
+ src.next().expect("already peeked");
+ }
+
+ let kind = match src.peek() {
+ Some(TtElement::Leaf(tt::Leaf::Ident(ident))) if ident.sym == sym::attr => {
+ src.next().expect("already peeked");
+ // FIXME: Add support for `attr(..)` rules with attribute arguments,
+ // which would be inside these parens.
+ src.expect_subtree().map_err(|_| ParseError::expected("expected `()`"))?;
+ MacroCallStyle::Attr
+ }
+ Some(TtElement::Leaf(tt::Leaf::Ident(ident))) if ident.sym == sym::derive => {
+ src.next().expect("already peeked");
+ src.expect_subtree().map_err(|_| ParseError::expected("expected `()`"))?;
+ MacroCallStyle::Derive
+ }
+ _ => MacroCallStyle::FnLike,
+ };
+ Ok(kind)
+}
/// Consider
///