diff options
Diffstat (limited to 'crates/ra_parser/src')
-rw-r--r-- | crates/ra_parser/src/grammar/attributes.rs | 22 | ||||
-rw-r--r-- | crates/ra_parser/src/grammar/expressions.rs | 4 | ||||
-rw-r--r-- | crates/ra_parser/src/grammar/expressions/atom.rs | 14 |
3 files changed, 32 insertions, 8 deletions
diff --git a/crates/ra_parser/src/grammar/attributes.rs b/crates/ra_parser/src/grammar/attributes.rs index f3158ade3..eeae37aef 100644 --- a/crates/ra_parser/src/grammar/attributes.rs +++ b/crates/ra_parser/src/grammar/attributes.rs | |||
@@ -8,6 +8,28 @@ pub(super) fn inner_attributes(p: &mut Parser) { | |||
8 | } | 8 | } |
9 | } | 9 | } |
10 | 10 | ||
11 | pub(super) fn with_outer_attributes( | ||
12 | p: &mut Parser, | ||
13 | f: impl Fn(&mut Parser) -> Option<CompletedMarker>, | ||
14 | ) -> bool { | ||
15 | let am = p.start(); | ||
16 | let has_attrs = p.at(T![#]); | ||
17 | attributes::outer_attributes(p); | ||
18 | let cm = f(p); | ||
19 | let success = cm.is_some(); | ||
20 | |||
21 | match (has_attrs, cm) { | ||
22 | (true, Some(cm)) => { | ||
23 | let kind = cm.kind(); | ||
24 | cm.undo_completion(p).abandon(p); | ||
25 | am.complete(p, kind); | ||
26 | } | ||
27 | _ => am.abandon(p), | ||
28 | } | ||
29 | |||
30 | success | ||
31 | } | ||
32 | |||
11 | pub(super) fn outer_attributes(p: &mut Parser) { | 33 | pub(super) fn outer_attributes(p: &mut Parser) { |
12 | while p.at(T![#]) { | 34 | while p.at(T![#]) { |
13 | attribute(p, false) | 35 | attribute(p, false) |
diff --git a/crates/ra_parser/src/grammar/expressions.rs b/crates/ra_parser/src/grammar/expressions.rs index 81d4f75f9..d733499d1 100644 --- a/crates/ra_parser/src/grammar/expressions.rs +++ b/crates/ra_parser/src/grammar/expressions.rs | |||
@@ -14,9 +14,9 @@ pub(super) enum StmtWithSemi { | |||
14 | 14 | ||
15 | const EXPR_FIRST: TokenSet = LHS_FIRST; | 15 | const EXPR_FIRST: TokenSet = LHS_FIRST; |
16 | 16 | ||
17 | pub(super) fn expr(p: &mut Parser) -> BlockLike { | 17 | pub(super) fn expr(p: &mut Parser) -> (Option<CompletedMarker>, BlockLike) { |
18 | let r = Restrictions { forbid_structs: false, prefer_stmt: false }; | 18 | let r = Restrictions { forbid_structs: false, prefer_stmt: false }; |
19 | expr_bp(p, r, 1).1 | 19 | expr_bp(p, r, 1) |
20 | } | 20 | } |
21 | 21 | ||
22 | pub(super) fn expr_stmt(p: &mut Parser) -> (Option<CompletedMarker>, BlockLike) { | 22 | pub(super) fn expr_stmt(p: &mut Parser) -> (Option<CompletedMarker>, BlockLike) { |
diff --git a/crates/ra_parser/src/grammar/expressions/atom.rs b/crates/ra_parser/src/grammar/expressions/atom.rs index 4ac1d6334..700994e80 100644 --- a/crates/ra_parser/src/grammar/expressions/atom.rs +++ b/crates/ra_parser/src/grammar/expressions/atom.rs | |||
@@ -192,9 +192,8 @@ fn array_expr(p: &mut Parser) -> CompletedMarker { | |||
192 | // 1, | 192 | // 1, |
193 | // 2, | 193 | // 2, |
194 | // ]; | 194 | // ]; |
195 | attributes::outer_attributes(p); | 195 | attributes::with_outer_attributes(p, |p| expr(p).0); |
196 | 196 | ||
197 | expr(p); | ||
198 | if p.eat(T![;]) { | 197 | if p.eat(T![;]) { |
199 | expr(p); | 198 | expr(p); |
200 | p.expect(T![']']); | 199 | p.expect(T![']']); |
@@ -212,12 +211,15 @@ fn array_expr(p: &mut Parser) -> CompletedMarker { | |||
212 | // #[cfg(test)] | 211 | // #[cfg(test)] |
213 | // 2, | 212 | // 2, |
214 | // ]; | 213 | // ]; |
215 | attributes::outer_attributes(p); | 214 | if !attributes::with_outer_attributes(p, |p| { |
216 | if !p.at_ts(EXPR_FIRST) { | 215 | if !p.at_ts(EXPR_FIRST) { |
217 | p.error("expected expression"); | 216 | p.error("expected expression"); |
217 | return None; | ||
218 | } | ||
219 | expr(p).0 | ||
220 | }) { | ||
218 | break; | 221 | break; |
219 | } | 222 | } |
220 | expr(p); | ||
221 | } | 223 | } |
222 | p.expect(T![']']); | 224 | p.expect(T![']']); |
223 | m.complete(p, ARRAY_EXPR) | 225 | m.complete(p, ARRAY_EXPR) |