Skip to content

Commit c9ca6a1

Browse files
Merge #8550
8550: Handle extended key value attributes in mbe r=edwin0cheng a=edwin0cheng fixes #8544 bors r+ Co-authored-by: Edwin Cheng <[email protected]>
2 parents df5b6f7 + c4173bb commit c9ca6a1

File tree

3 files changed

+35
-48
lines changed

3 files changed

+35
-48
lines changed

crates/mbe/src/tests/expand.rs

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -940,6 +940,24 @@ fn test_meta_doc_comments() {
940940
);
941941
}
942942

943+
#[test]
944+
fn test_meta_extended_key_value_attributes() {
945+
parse_macro(
946+
r#"
947+
macro_rules! foo {
948+
(#[$i:meta]) => (
949+
#[$ i]
950+
fn bar() {}
951+
)
952+
}
953+
"#,
954+
)
955+
.assert_expand_items(
956+
r#"foo! { #[doc = concat!("The `", "bla", "` lang item.")] }"#,
957+
r#"# [doc = concat ! ("The `" , "bla" , "` lang item.")] fn bar () {}"#,
958+
);
959+
}
960+
943961
#[test]
944962
fn test_meta_doc_comments_non_latin() {
945963
parse_macro(

crates/parser/src/grammar.rs

Lines changed: 1 addition & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -76,42 +76,7 @@ pub(crate) mod fragments {
7676

7777
// Parse a meta item , which excluded [], e.g : #[ MetaItem ]
7878
pub(crate) fn meta_item(p: &mut Parser) {
79-
fn is_delimiter(p: &mut Parser) -> bool {
80-
matches!(p.current(), T!['{'] | T!['('] | T!['['])
81-
}
82-
83-
if is_delimiter(p) {
84-
items::token_tree(p);
85-
return;
86-
}
87-
88-
let m = p.start();
89-
while !p.at(EOF) {
90-
if is_delimiter(p) {
91-
items::token_tree(p);
92-
break;
93-
} else {
94-
// https://doc.rust-lang.org/reference/attributes.html
95-
// https://doc.rust-lang.org/reference/paths.html#simple-paths
96-
// The start of an meta must be a simple path
97-
match p.current() {
98-
IDENT | T![super] | T![self] | T![crate] => p.bump_any(),
99-
T![=] => {
100-
p.bump_any();
101-
match p.current() {
102-
c if c.is_literal() => p.bump_any(),
103-
T![true] | T![false] => p.bump_any(),
104-
_ => {}
105-
}
106-
break;
107-
}
108-
_ if p.at(T![::]) => p.bump(T![::]),
109-
_ => break,
110-
}
111-
}
112-
}
113-
114-
m.complete(p, TOKEN_TREE);
79+
attributes::meta(p);
11580
}
11681

11782
pub(crate) fn item(p: &mut Parser) {

crates/parser/src/grammar/attributes.rs

Lines changed: 16 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,21 @@ pub(super) fn outer_attrs(p: &mut Parser) {
1414
}
1515
}
1616

17+
pub(super) fn meta(p: &mut Parser) {
18+
paths::use_path(p);
19+
20+
match p.current() {
21+
T![=] => {
22+
p.bump(T![=]);
23+
if expressions::expr(p).0.is_none() {
24+
p.error("expected expression");
25+
}
26+
}
27+
T!['('] | T!['['] | T!['{'] => items::token_tree(p),
28+
_ => {}
29+
}
30+
}
31+
1732
fn attr(p: &mut Parser, inner: bool) {
1833
let attr = p.start();
1934
assert!(p.at(T![#]));
@@ -25,18 +40,7 @@ fn attr(p: &mut Parser, inner: bool) {
2540
}
2641

2742
if p.eat(T!['[']) {
28-
paths::use_path(p);
29-
30-
match p.current() {
31-
T![=] => {
32-
p.bump(T![=]);
33-
if expressions::expr(p).0.is_none() {
34-
p.error("expected expression");
35-
}
36-
}
37-
T!['('] | T!['['] | T!['{'] => items::token_tree(p),
38-
_ => {}
39-
}
43+
meta(p);
4044

4145
if !p.eat(T![']']) {
4246
p.error("expected `]`");

0 commit comments

Comments
 (0)