aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJonas Schievink <[email protected]>2021-03-17 17:20:32 +0000
committerJonas Schievink <[email protected]>2021-03-17 17:28:27 +0000
commit022a0f061e887bd27f54c028f9a23018b8eb2b8b (patch)
tree6f1f7c1c7ba6300c87350946f0033d73c02f9546
parent0a6471384529bd8861c628756695c52be4c6837f (diff)
Correctly parse attributes on fn parameters
-rw-r--r--crates/parser/src/grammar/params.rs29
-rw-r--r--crates/syntax/test_data/parser/inline/ok/0139_param_outer_arg.rast20
-rw-r--r--crates/syntax/test_data/parser/ok/0051_parameter_attrs.rast78
3 files changed, 71 insertions, 56 deletions
diff --git a/crates/parser/src/grammar/params.rs b/crates/parser/src/grammar/params.rs
index e313f6fb7..9e2f02d43 100644
--- a/crates/parser/src/grammar/params.rs
+++ b/crates/parser/src/grammar/params.rs
@@ -41,22 +41,32 @@ fn list_(p: &mut Parser, flavor: Flavor) {
41 FnDef | FnTrait | FnPointer => (T!['('], T![')']), 41 FnDef | FnTrait | FnPointer => (T!['('], T![')']),
42 }; 42 };
43 43
44 let m = p.start(); 44 let list_marker = p.start();
45 p.bump(bra); 45 p.bump(bra);
46 46
47 let mut param_marker = None;
47 if let FnDef = flavor { 48 if let FnDef = flavor {
48 // test self_param_outer_attr 49 // test self_param_outer_attr
49 // fn f(#[must_use] self) {} 50 // fn f(#[must_use] self) {}
50 let m = p.start(); 51 let m = p.start();
51 attributes::outer_attrs(p); 52 attributes::outer_attrs(p);
52 opt_self_param(p, m); 53 match opt_self_param(p, m) {
54 Ok(()) => {}
55 Err(m) => param_marker = Some(m),
56 }
53 } 57 }
54 58
55 while !p.at(EOF) && !p.at(ket) { 59 while !p.at(EOF) && !p.at(ket) {
56 // test param_outer_arg 60 // test param_outer_arg
57 // fn f(#[attr1] pat: Type) {} 61 // fn f(#[attr1] pat: Type) {}
58 let m = p.start(); 62 let m = match param_marker.take() {
59 attributes::outer_attrs(p); 63 Some(m) => m,
64 None => {
65 let m = p.start();
66 attributes::outer_attrs(p);
67 m
68 }
69 };
60 70
61 if !p.at_ts(PARAM_FIRST) { 71 if !p.at_ts(PARAM_FIRST) {
62 p.error("expected value parameter"); 72 p.error("expected value parameter");
@@ -72,8 +82,12 @@ fn list_(p: &mut Parser, flavor: Flavor) {
72 } 82 }
73 } 83 }
74 84
85 if let Some(m) = param_marker {
86 m.abandon(p);
87 }
88
75 p.expect(ket); 89 p.expect(ket);
76 m.complete(p, PARAM_LIST); 90 list_marker.complete(p, PARAM_LIST);
77} 91}
78 92
79const PARAM_FIRST: TokenSet = patterns::PATTERN_FIRST.union(types::TYPE_FIRST); 93const PARAM_FIRST: TokenSet = patterns::PATTERN_FIRST.union(types::TYPE_FIRST);
@@ -153,7 +167,7 @@ fn variadic_param(p: &mut Parser) -> bool {
153// fn d(&'a mut self, x: i32) {} 167// fn d(&'a mut self, x: i32) {}
154// fn e(mut self) {} 168// fn e(mut self) {}
155// } 169// }
156fn opt_self_param(p: &mut Parser, m: Marker) { 170fn opt_self_param(p: &mut Parser, m: Marker) -> Result<(), Marker> {
157 if p.at(T![self]) || p.at(T![mut]) && p.nth(1) == T![self] { 171 if p.at(T![self]) || p.at(T![mut]) && p.nth(1) == T![self] {
158 p.eat(T![mut]); 172 p.eat(T![mut]);
159 self_as_name(p); 173 self_as_name(p);
@@ -176,7 +190,7 @@ fn opt_self_param(p: &mut Parser, m: Marker) {
176 | (T![&], LIFETIME_IDENT, T![self], _) 190 | (T![&], LIFETIME_IDENT, T![self], _)
177 | (T![&], LIFETIME_IDENT, T![mut], T![self]) 191 | (T![&], LIFETIME_IDENT, T![mut], T![self])
178 ) { 192 ) {
179 return m.abandon(p); 193 return Err(m);
180 } 194 }
181 p.bump(T![&]); 195 p.bump(T![&]);
182 if p.at(LIFETIME_IDENT) { 196 if p.at(LIFETIME_IDENT) {
@@ -189,6 +203,7 @@ fn opt_self_param(p: &mut Parser, m: Marker) {
189 if !p.at(T![')']) { 203 if !p.at(T![')']) {
190 p.expect(T![,]); 204 p.expect(T![,]);
191 } 205 }
206 Ok(())
192} 207}
193 208
194fn self_as_name(p: &mut Parser) { 209fn self_as_name(p: &mut Parser) {
diff --git a/crates/syntax/test_data/parser/inline/ok/0139_param_outer_arg.rast b/crates/syntax/test_data/parser/inline/ok/0139_param_outer_arg.rast
index 495e4c51b..a84088bf3 100644
--- a/crates/syntax/test_data/parser/inline/ok/0139_param_outer_arg.rast
+++ b/crates/syntax/test_data/parser/inline/ok/0139_param_outer_arg.rast
@@ -6,16 +6,16 @@ [email protected]
6 [email protected] "f" 6 [email protected] "f"
7 [email protected] 7 [email protected]
8 [email protected] "(" 8 [email protected] "("
9 ATTR@5..13 9 PARAM@5..23
10 POUND@5..6 "#" 10 ATTR@5..13
11 L_BRACK@6..7 "[" 11 POUND@5..6 "#"
12 PATH@7..12 12 L_BRACK@6..7 "["
13 PATH_SEGMENT@7..12 13 [email protected]
14 NAME_REF@7..12 14 PATH_SEGMENT@7..12
15 IDENT@7..12 "attr1" 15 NAME_REF@7..12
16 R_BRACK@12..13 "]" 16 IDENT@7..12 "attr1"
17 WHITESPACE@13..14 " " 17 R_BRACK@12..13 "]"
18 PARAM@14..23 18 WHITESPACE@13..14 " "
19 [email protected] 19 [email protected]
20 [email protected] 20 [email protected]
21 [email protected] "pat" 21 [email protected] "pat"
diff --git a/crates/syntax/test_data/parser/ok/0051_parameter_attrs.rast b/crates/syntax/test_data/parser/ok/0051_parameter_attrs.rast
index e10521d85..88470c41c 100644
--- a/crates/syntax/test_data/parser/ok/0051_parameter_attrs.rast
+++ b/crates/syntax/test_data/parser/ok/0051_parameter_attrs.rast
@@ -6,25 +6,25 @@ [email protected]
6 [email protected] "g1" 6 [email protected] "g1"
7 [email protected] 7 [email protected]
8 [email protected] "(" 8 [email protected] "("
9 ATTR@6..14 9 PARAM@6..33
10 POUND@6..7 "#" 10 ATTR@6..14
11 L_BRACK@7..8 "[" 11 POUND@6..7 "#"
12 PATH@8..13 12 L_BRACK@7..8 "["
13 PATH_SEGMENT@8..13 13 [email protected]
14 NAME_REF@8..13 14 PATH_SEGMENT@8..13
15 IDENT@8..13 "attr1" 15 NAME_REF@8..13
16 R_BRACK@13..14 "]" 16 IDENT@8..13 "attr1"
17 WHITESPACE@14..15 " " 17 R_BRACK@13..14 "]"
18 ATTR@15..23 18 WHITESPACE@14..15 " "
19 POUND@15..16 "#" 19 ATTR@15..23
20 L_BRACK@16..17 "[" 20 POUND@15..16 "#"
21 PATH@17..22 21 L_BRACK@16..17 "["
22 PATH_SEGMENT@17..22 22 [email protected]
23 NAME_REF@17..22 23 PATH_SEGMENT@17..22
24 IDENT@17..22 "attr2" 24 NAME_REF@17..22
25 R_BRACK@22..23 "]" 25 IDENT@17..22 "attr2"
26 WHITESPACE@23..24 " " 26 R_BRACK@22..23 "]"
27 PARAM@24..33 27 WHITESPACE@23..24 " "
28 [email protected] 28 [email protected]
29 [email protected] 29 [email protected]
30 [email protected] "pat" 30 [email protected] "pat"
@@ -48,16 +48,16 @@ [email protected]
48 [email protected] "g2" 48 [email protected] "g2"
49 [email protected] 49 [email protected]
50 [email protected] "(" 50 [email protected] "("
51 ATT[email protected]2 51 PARAM@44..58
52 POUND@44..45 "#" 52 ATTR@44..52
53 L_BRACK@45..46 "[" 53 POUND@44..45 "#"
54 PATH@46..51 54 L_BRACK@45..46 "["
55 PATH_SEGMENT@46..51 55 [email protected]
56 NAME_REF@46..51 56 PATH_SEGMENT@46..51
57 IDENT@46..51 "attr1" 57 NAME_REF@46..51
58 R_BRACK@51..52 "]" 58 IDENT@46..51 "attr1"
59 WHITESPACE@52..53 " " 59 R_BRACK@51..52 "]"
60 PARAM@53..58 60 WHITESPACE@52..53 " "
61 [email protected] 61 [email protected]
62 [email protected] 62 [email protected]
63 [email protected] "x" 63 [email protected] "x"
@@ -203,16 +203,16 @@ [email protected]
203 [email protected] "bar" 203 [email protected] "bar"
204 [email protected] 204 [email protected]
205 [email protected] "(" 205 [email protected] "("
206 ATT[email protected]04 206 PARAM@197..211
207 POUND@197..198 "#" 207 ATTR@197..204
208 L_BRACK@198..199 "[" 208 POUND@197..198 "#"
209 PATH@199..203 209 L_BRACK@198..199 "["
210 PATH_SEGMENT@199..203 210 [email protected]
211 NAME_REF@199..203 211 PATH_SEGMENT@199..203
212 IDENT@199..203 "attr" 212 NAME_REF@199..203
213 R_BRACK@203..204 "]" 213 IDENT@199..203 "attr"
214 WHITESPACE@204..205 " " 214 R_BRACK@203..204 "]"
215 PARAM@205..211 215 WHITESPACE@204..205 " "
216 [email protected] 216 [email protected]
217 [email protected] "_" 217 [email protected] "_"
218 [email protected] ":" 218 [email protected] ":"