diff options
Diffstat (limited to 'crates/parser/src')
-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/patterns.rs | 6 | ||||
-rw-r--r-- | crates/parser/src/grammar/type_args.rs | 41 | ||||
-rw-r--r-- | crates/parser/src/grammar/type_params.rs | 10 | ||||
-rw-r--r-- | crates/parser/src/grammar/types.rs | 10 |
6 files changed, 79 insertions, 53 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/patterns.rs b/crates/parser/src/grammar/patterns.rs index da71498a8..3ab347834 100644 --- a/crates/parser/src/grammar/patterns.rs +++ b/crates/parser/src/grammar/patterns.rs | |||
@@ -206,13 +206,15 @@ fn record_pat_field_list(p: &mut Parser) { | |||
206 | T![.] if p.at(T![..]) => p.bump(T![..]), | 206 | T![.] if p.at(T![..]) => p.bump(T![..]), |
207 | T!['{'] => error_block(p, "expected ident"), | 207 | T!['{'] => error_block(p, "expected ident"), |
208 | 208 | ||
209 | c => { | 209 | _ => { |
210 | let m = p.start(); | 210 | let m = p.start(); |
211 | match c { | 211 | attributes::outer_attrs(p); |
212 | match p.current() { | ||
212 | // test record_pat_field | 213 | // test record_pat_field |
213 | // fn foo() { | 214 | // fn foo() { |
214 | // let S { 0: 1 } = (); | 215 | // let S { 0: 1 } = (); |
215 | // let S { x: 1 } = (); | 216 | // let S { x: 1 } = (); |
217 | // let S { #[cfg(any())] x: 1 } = (); | ||
216 | // } | 218 | // } |
217 | IDENT | INT_NUMBER if p.nth(1) == T![:] => { | 219 | IDENT | INT_NUMBER if p.nth(1) == T![:] => { |
218 | name_ref_or_index(p); | 220 | name_ref_or_index(p); |
diff --git a/crates/parser/src/grammar/type_args.rs b/crates/parser/src/grammar/type_args.rs index 42cd426bd..be36cad17 100644 --- a/crates/parser/src/grammar/type_args.rs +++ b/crates/parser/src/grammar/type_args.rs | |||
@@ -25,6 +25,38 @@ pub(super) fn opt_generic_arg_list(p: &mut Parser, colon_colon_required: bool) { | |||
25 | m.complete(p, GENERIC_ARG_LIST); | 25 | m.complete(p, GENERIC_ARG_LIST); |
26 | } | 26 | } |
27 | 27 | ||
28 | pub(super) fn const_arg(p: &mut Parser) { | ||
29 | let m = p.start(); | ||
30 | // FIXME: duplicates the code below | ||
31 | match p.current() { | ||
32 | T!['{'] => { | ||
33 | expressions::block_expr(p); | ||
34 | m.complete(p, CONST_ARG); | ||
35 | } | ||
36 | k if k.is_literal() => { | ||
37 | expressions::literal(p); | ||
38 | m.complete(p, CONST_ARG); | ||
39 | } | ||
40 | T![true] | T![false] => { | ||
41 | expressions::literal(p); | ||
42 | m.complete(p, CONST_ARG); | ||
43 | } | ||
44 | T![-] => { | ||
45 | let lm = p.start(); | ||
46 | p.bump(T![-]); | ||
47 | expressions::literal(p); | ||
48 | lm.complete(p, PREFIX_EXPR); | ||
49 | m.complete(p, CONST_ARG); | ||
50 | } | ||
51 | _ => { | ||
52 | let lm = p.start(); | ||
53 | paths::use_path(p); | ||
54 | lm.complete(p, PATH_EXPR); | ||
55 | m.complete(p, CONST_ARG); | ||
56 | } | ||
57 | } | ||
58 | } | ||
59 | |||
28 | // test type_arg | 60 | // test type_arg |
29 | // type A = B<'static, i32, 1, { 2 }, Item=u64, true, false>; | 61 | // type A = B<'static, i32, 1, { 2 }, Item=u64, true, false>; |
30 | fn generic_arg(p: &mut Parser) { | 62 | fn generic_arg(p: &mut Parser) { |
@@ -59,6 +91,15 @@ fn generic_arg(p: &mut Parser) { | |||
59 | expressions::literal(p); | 91 | expressions::literal(p); |
60 | m.complete(p, CONST_ARG); | 92 | m.complete(p, CONST_ARG); |
61 | } | 93 | } |
94 | // test const_generic_negated_literal | ||
95 | // fn f() { S::<-1> } | ||
96 | T![-] => { | ||
97 | let lm = p.start(); | ||
98 | p.bump(T![-]); | ||
99 | expressions::literal(p); | ||
100 | lm.complete(p, PREFIX_EXPR); | ||
101 | m.complete(p, CONST_ARG); | ||
102 | } | ||
62 | _ => { | 103 | _ => { |
63 | types::type_(p); | 104 | types::type_(p); |
64 | m.complete(p, TYPE_ARG); | 105 | m.complete(p, TYPE_ARG); |
diff --git a/crates/parser/src/grammar/type_params.rs b/crates/parser/src/grammar/type_params.rs index 3de5248da..b1f979281 100644 --- a/crates/parser/src/grammar/type_params.rs +++ b/crates/parser/src/grammar/type_params.rs | |||
@@ -70,6 +70,16 @@ fn const_param(p: &mut Parser, m: Marker) { | |||
70 | p.bump(T![const]); | 70 | p.bump(T![const]); |
71 | name(p); | 71 | name(p); |
72 | types::ascription(p); | 72 | types::ascription(p); |
73 | |||
74 | // test const_param_defaults | ||
75 | // struct A<const N: i32 = -1>; | ||
76 | // struct B<const N: i32 = {}>; | ||
77 | // struct C<const N: i32 = some::CONST>; | ||
78 | if p.at(T![=]) { | ||
79 | p.bump(T![=]); | ||
80 | type_args::const_arg(p); | ||
81 | } | ||
82 | |||
73 | m.complete(p, CONST_PARAM); | 83 | m.complete(p, CONST_PARAM); |
74 | } | 84 | } |
75 | 85 | ||
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; |