mirror of
https://github.com/rust-lang/rust.git
synced 2024-11-28 17:53:56 +00:00
Handle extended key value attr in mbe
This commit is contained in:
parent
df5b6f7d45
commit
c4173bb468
@ -940,6 +940,24 @@ fn test_meta_doc_comments() {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[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]
|
#[test]
|
||||||
fn test_meta_doc_comments_non_latin() {
|
fn test_meta_doc_comments_non_latin() {
|
||||||
parse_macro(
|
parse_macro(
|
||||||
|
@ -76,42 +76,7 @@ pub(crate) mod fragments {
|
|||||||
|
|
||||||
// Parse a meta item , which excluded [], e.g : #[ MetaItem ]
|
// Parse a meta item , which excluded [], e.g : #[ MetaItem ]
|
||||||
pub(crate) fn meta_item(p: &mut Parser) {
|
pub(crate) fn meta_item(p: &mut Parser) {
|
||||||
fn is_delimiter(p: &mut Parser) -> bool {
|
attributes::meta(p);
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn item(p: &mut Parser) {
|
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) {
|
fn attr(p: &mut Parser, inner: bool) {
|
||||||
let attr = p.start();
|
let attr = p.start();
|
||||||
assert!(p.at(T![#]));
|
assert!(p.at(T![#]));
|
||||||
@ -25,18 +40,7 @@ fn attr(p: &mut Parser, inner: bool) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if p.eat(T!['[']) {
|
if p.eat(T!['[']) {
|
||||||
paths::use_path(p);
|
meta(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),
|
|
||||||
_ => {}
|
|
||||||
}
|
|
||||||
|
|
||||||
if !p.eat(T![']']) {
|
if !p.eat(T![']']) {
|
||||||
p.error("expected `]`");
|
p.error("expected `]`");
|
||||||
|
Loading…
Reference in New Issue
Block a user