aboutsummaryrefslogtreecommitdiff
path: root/crates/parser/src
diff options
context:
space:
mode:
Diffstat (limited to 'crates/parser/src')
-rw-r--r--crates/parser/src/grammar.rs37
-rw-r--r--crates/parser/src/grammar/attributes.rs28
-rw-r--r--crates/parser/src/grammar/patterns.rs6
-rw-r--r--crates/parser/src/grammar/type_args.rs41
-rw-r--r--crates/parser/src/grammar/type_params.rs10
-rw-r--r--crates/parser/src/grammar/types.rs10
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
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 `]`");
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
28pub(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>;
30fn generic_arg(p: &mut Parser) { 62fn 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!();
284fn path_or_macro_type_(p: &mut Parser, allow_bounds: bool) { 284fn 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) {
319fn opt_type_bounds_as_dyn_trait_type(p: &mut Parser, type_marker: CompletedMarker) { 323fn 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;