Merge #8550
8550: Handle extended key value attributes in mbe r=edwin0cheng a=edwin0cheng fixes #8544 bors r+ Co-authored-by: Edwin Cheng <edwin0cheng@gmail.com>
This commit is contained in:
commit
c9ca6a1434
@ -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(
|
||||
|
@ -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) {
|
||||
|
@ -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 `]`");
|
||||
|
Loading…
Reference in New Issue
Block a user