aboutsummaryrefslogtreecommitdiff
path: root/crates
diff options
context:
space:
mode:
authorEdwin Cheng <[email protected]>2021-04-17 07:31:52 +0100
committerEdwin Cheng <[email protected]>2021-04-17 07:31:52 +0100
commitc4173bb468500f6490921e8f8627d87b2aeb7af5 (patch)
treed8f6d2d1c2d2aac12f333a7f9955a708d49bd28d /crates
parentdf5b6f7d459a367b191d5d540c7363d9e526eadf (diff)
Handle extended key value attr in mbe
Diffstat (limited to 'crates')
-rw-r--r--crates/mbe/src/tests/expand.rs18
-rw-r--r--crates/parser/src/grammar.rs37
-rw-r--r--crates/parser/src/grammar/attributes.rs28
3 files changed, 35 insertions, 48 deletions
diff --git a/crates/mbe/src/tests/expand.rs b/crates/mbe/src/tests/expand.rs
index e02d038b6..146b236e2 100644
--- a/crates/mbe/src/tests/expand.rs
+++ b/crates/mbe/src/tests/expand.rs
@@ -941,6 +941,24 @@ fn test_meta_doc_comments() {
941} 941}
942 942
943#[test] 943#[test]
944fn test_meta_extended_key_value_attributes() {
945 parse_macro(
946 r#"
947macro_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
961#[test]
944fn test_meta_doc_comments_non_latin() { 962fn test_meta_doc_comments_non_latin() {
945 parse_macro( 963 parse_macro(
946 r#" 964 r#"
diff --git a/crates/parser/src/grammar.rs b/crates/parser/src/grammar.rs
index cebb8f400..9bdf0b5fa 100644
--- a/crates/parser/src/grammar.rs
+++ b/crates/parser/src/grammar.rs
@@ -76,42 +76,7 @@ pub(crate) mod fragments {
76 76
77 // Parse a meta item , which excluded [], e.g : #[ MetaItem ] 77 // Parse a meta item , which excluded [], e.g : #[ MetaItem ]
78 pub(crate) fn meta_item(p: &mut Parser) { 78 pub(crate) fn meta_item(p: &mut Parser) {
79 fn is_delimiter(p: &mut Parser) -> bool { 79 attributes::meta(p);
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);
115 } 80 }
116 81
117 pub(crate) fn item(p: &mut Parser) { 82 pub(crate) fn item(p: &mut Parser) {
diff --git a/crates/parser/src/grammar/attributes.rs b/crates/parser/src/grammar/attributes.rs
index 96791ffc2..124a10eb2 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) {
14 } 14 }
15} 15}
16 16
17pub(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
17fn attr(p: &mut Parser, inner: bool) { 32fn attr(p: &mut Parser, inner: bool) {
18 let attr = p.start(); 33 let attr = p.start();
19 assert!(p.at(T![#])); 34 assert!(p.at(T![#]));
@@ -25,18 +40,7 @@ fn attr(p: &mut Parser, inner: bool) {
25 } 40 }
26 41
27 if p.eat(T!['[']) { 42 if p.eat(T!['[']) {
28 paths::use_path(p); 43 meta(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 }
40 44
41 if !p.eat(T![']']) { 45 if !p.eat(T![']']) {
42 p.error("expected `]`"); 46 p.error("expected `]`");