From c4173bb468500f6490921e8f8627d87b2aeb7af5 Mon Sep 17 00:00:00 2001 From: Edwin Cheng Date: Sat, 17 Apr 2021 14:31:52 +0800 Subject: [PATCH] Handle extended key value attr in mbe --- crates/mbe/src/tests/expand.rs | 18 ++++++++++++ crates/parser/src/grammar.rs | 37 +------------------------ crates/parser/src/grammar/attributes.rs | 28 +++++++++++-------- 3 files changed, 35 insertions(+), 48 deletions(-) diff --git a/crates/mbe/src/tests/expand.rs b/crates/mbe/src/tests/expand.rs index e02d038b657..146b236e26f 100644 --- a/crates/mbe/src/tests/expand.rs +++ b/crates/mbe/src/tests/expand.rs @@ -940,6 +940,24 @@ fn bar() {} ); } +#[test] +fn test_meta_extended_key_value_attributes() { + parse_macro( + r#" +macro_rules! foo { + (#[$i:meta]) => ( + #[$ i] + fn bar() {} + ) +} +"#, + ) + .assert_expand_items( + r#"foo! { #[doc = concat!("The `", "bla", "` lang item.")] }"#, + r#"# [doc = concat ! ("The `" , "bla" , "` lang item.")] fn bar () {}"#, + ); +} + #[test] fn test_meta_doc_comments_non_latin() { parse_macro( diff --git a/crates/parser/src/grammar.rs b/crates/parser/src/grammar.rs index cebb8f40080..9bdf0b5fa24 100644 --- a/crates/parser/src/grammar.rs +++ b/crates/parser/src/grammar.rs @@ -76,42 +76,7 @@ pub(crate) fn opt_visibility(p: &mut Parser) { // Parse a meta item , which excluded [], e.g : #[ MetaItem ] pub(crate) fn meta_item(p: &mut Parser) { - fn is_delimiter(p: &mut Parser) -> bool { - matches!(p.current(), T!['{'] | T!['('] | T!['[']) - } - - if is_delimiter(p) { - items::token_tree(p); - return; - } - - let m = p.start(); - while !p.at(EOF) { - if is_delimiter(p) { - items::token_tree(p); - break; - } else { - // https://doc.rust-lang.org/reference/attributes.html - // https://doc.rust-lang.org/reference/paths.html#simple-paths - // The start of an meta must be a simple path - match p.current() { - IDENT | T![super] | T![self] | T![crate] => p.bump_any(), - T![=] => { - p.bump_any(); - match p.current() { - c if c.is_literal() => p.bump_any(), - T![true] | T![false] => p.bump_any(), - _ => {} - } - break; - } - _ if p.at(T![::]) => p.bump(T![::]), - _ => break, - } - } - } - - m.complete(p, TOKEN_TREE); + attributes::meta(p); } pub(crate) fn item(p: &mut Parser) { diff --git a/crates/parser/src/grammar/attributes.rs b/crates/parser/src/grammar/attributes.rs index 96791ffc2a4..124a10eb264 100644 --- a/crates/parser/src/grammar/attributes.rs +++ b/crates/parser/src/grammar/attributes.rs @@ -14,6 +14,21 @@ pub(super) fn outer_attrs(p: &mut Parser) { } } +pub(super) fn meta(p: &mut Parser) { + paths::use_path(p); + + match p.current() { + T![=] => { + p.bump(T![=]); + if expressions::expr(p).0.is_none() { + p.error("expected expression"); + } + } + T!['('] | T!['['] | T!['{'] => items::token_tree(p), + _ => {} + } +} + fn attr(p: &mut Parser, inner: bool) { let attr = p.start(); assert!(p.at(T![#])); @@ -25,18 +40,7 @@ fn attr(p: &mut Parser, inner: bool) { } if p.eat(T!['[']) { - paths::use_path(p); - - match p.current() { - T![=] => { - p.bump(T![=]); - if expressions::expr(p).0.is_none() { - p.error("expected expression"); - } - } - T!['('] | T!['['] | T!['{'] => items::token_tree(p), - _ => {} - } + meta(p); if !p.eat(T![']']) { p.error("expected `]`");