diff options
Diffstat (limited to 'crates/parser/src/grammar')
-rw-r--r-- | crates/parser/src/grammar/params.rs | 29 |
1 files changed, 22 insertions, 7 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 | ||
79 | const PARAM_FIRST: TokenSet = patterns::PATTERN_FIRST.union(types::TYPE_FIRST); | 93 | const 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 | // } |
156 | fn opt_self_param(p: &mut Parser, m: Marker) { | 170 | fn 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 | ||
194 | fn self_as_name(p: &mut Parser) { | 209 | fn self_as_name(p: &mut Parser) { |