diff options
Diffstat (limited to 'crates/parser')
-rw-r--r-- | crates/parser/src/grammar.rs | 37 | ||||
-rw-r--r-- | crates/parser/src/grammar/attributes.rs | 28 | ||||
-rw-r--r-- | crates/parser/src/grammar/types.rs | 10 |
3 files changed, 24 insertions, 51 deletions
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 | ||
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 | |||
17 | fn attr(p: &mut Parser, inner: bool) { | 32 | fn 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 `]`"); |
diff --git a/crates/parser/src/grammar/types.rs b/crates/parser/src/grammar/types.rs index 94cbf7d85..6ae3e734f 100644 --- a/crates/parser/src/grammar/types.rs +++ b/crates/parser/src/grammar/types.rs | |||
@@ -283,17 +283,21 @@ pub(super) fn path_type(p: &mut Parser) { | |||
283 | // type B = crate::foo!(); | 283 | // type B = crate::foo!(); |
284 | fn path_or_macro_type_(p: &mut Parser, allow_bounds: bool) { | 284 | fn path_or_macro_type_(p: &mut Parser, allow_bounds: bool) { |
285 | assert!(paths::is_path_start(p)); | 285 | assert!(paths::is_path_start(p)); |
286 | let r = p.start(); | ||
286 | let m = p.start(); | 287 | let m = p.start(); |
288 | |||
287 | paths::type_path(p); | 289 | paths::type_path(p); |
288 | 290 | ||
289 | let kind = if p.at(T![!]) && !p.at(T![!=]) { | 291 | let kind = if p.at(T![!]) && !p.at(T![!=]) { |
290 | items::macro_call_after_excl(p); | 292 | items::macro_call_after_excl(p); |
291 | MACRO_CALL | 293 | m.complete(p, MACRO_CALL); |
294 | MACRO_TYPE | ||
292 | } else { | 295 | } else { |
296 | m.abandon(p); | ||
293 | PATH_TYPE | 297 | PATH_TYPE |
294 | }; | 298 | }; |
295 | 299 | ||
296 | let path = m.complete(p, kind); | 300 | let path = r.complete(p, kind); |
297 | 301 | ||
298 | if allow_bounds { | 302 | if allow_bounds { |
299 | opt_type_bounds_as_dyn_trait_type(p, path); | 303 | opt_type_bounds_as_dyn_trait_type(p, path); |
@@ -319,7 +323,7 @@ pub(super) fn path_type_(p: &mut Parser, allow_bounds: bool) { | |||
319 | fn opt_type_bounds_as_dyn_trait_type(p: &mut Parser, type_marker: CompletedMarker) { | 323 | fn opt_type_bounds_as_dyn_trait_type(p: &mut Parser, type_marker: CompletedMarker) { |
320 | assert!(matches!( | 324 | assert!(matches!( |
321 | type_marker.kind(), | 325 | type_marker.kind(), |
322 | SyntaxKind::PATH_TYPE | SyntaxKind::FOR_TYPE | SyntaxKind::MACRO_CALL | 326 | SyntaxKind::PATH_TYPE | SyntaxKind::FOR_TYPE | SyntaxKind::MACRO_TYPE |
323 | )); | 327 | )); |
324 | if !p.at(T![+]) { | 328 | if !p.at(T![+]) { |
325 | return; | 329 | return; |