diff options
Diffstat (limited to 'crates/ra_parser')
-rw-r--r-- | crates/ra_parser/src/grammar.rs | 2 | ||||
-rw-r--r-- | crates/ra_parser/src/grammar/expressions.rs | 4 | ||||
-rw-r--r-- | crates/ra_parser/src/grammar/expressions/atom.rs | 57 |
3 files changed, 30 insertions, 33 deletions
diff --git a/crates/ra_parser/src/grammar.rs b/crates/ra_parser/src/grammar.rs index 22f64a9f4..a46e11e1d 100644 --- a/crates/ra_parser/src/grammar.rs +++ b/crates/ra_parser/src/grammar.rs | |||
@@ -1,7 +1,7 @@ | |||
1 | //! This is the actual "grammar" of the Rust language. | 1 | //! This is the actual "grammar" of the Rust language. |
2 | //! | 2 | //! |
3 | //! Each function in this module and its children corresponds | 3 | //! Each function in this module and its children corresponds |
4 | //! to a production of the format grammar. Submodules roughly | 4 | //! to a production of the formal grammar. Submodules roughly |
5 | //! correspond to different *areas* of the grammar. By convention, | 5 | //! correspond to different *areas* of the grammar. By convention, |
6 | //! each submodule starts with `use super::*` import and exports | 6 | //! each submodule starts with `use super::*` import and exports |
7 | //! "public" productions via `pub(super)`. | 7 | //! "public" productions via `pub(super)`. |
diff --git a/crates/ra_parser/src/grammar/expressions.rs b/crates/ra_parser/src/grammar/expressions.rs index 95564b602..a31a7a08d 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..a98a2a3ef 100644 --- a/crates/ra_parser/src/grammar/expressions/atom.rs +++ b/crates/ra_parser/src/grammar/expressions/atom.rs | |||
@@ -181,45 +181,42 @@ fn tuple_expr(p: &mut Parser) -> CompletedMarker { | |||
181 | fn array_expr(p: &mut Parser) -> CompletedMarker { | 181 | fn array_expr(p: &mut Parser) -> CompletedMarker { |
182 | assert!(p.at(T!['['])); | 182 | assert!(p.at(T!['['])); |
183 | let m = p.start(); | 183 | let m = p.start(); |
184 | p.bump(T!['[']); | ||
185 | if p.eat(T![']']) { | ||
186 | return m.complete(p, ARRAY_EXPR); | ||
187 | } | ||
188 | 184 | ||
189 | // test first_array_member_attributes | 185 | let mut n_exprs = 0u32; |
190 | // pub const A: &[i64] = &[ | 186 | let mut has_semi = false; |
191 | // #[cfg(test)] | ||
192 | // 1, | ||
193 | // 2, | ||
194 | // ]; | ||
195 | attributes::outer_attributes(p); | ||
196 | 187 | ||
197 | expr(p); | 188 | p.bump(T!['[']); |
198 | if p.eat(T![;]) { | ||
199 | expr(p); | ||
200 | p.expect(T![']']); | ||
201 | return m.complete(p, ARRAY_EXPR); | ||
202 | } | ||
203 | while !p.at(EOF) && !p.at(T![']']) { | 189 | while !p.at(EOF) && !p.at(T![']']) { |
204 | p.expect(T![,]); | 190 | n_exprs += 1; |
205 | if p.at(T![']']) { | ||
206 | break; | ||
207 | } | ||
208 | 191 | ||
209 | // test subsequent_array_member_attributes | 192 | // test array_attrs |
210 | // pub const A: &[i64] = &[ | 193 | // const A: &[i64] = &[1, #[cfg(test)] 2]; |
211 | // 1, | 194 | let m = p.start(); |
212 | // #[cfg(test)] | 195 | let has_attrs = p.at(T![#]); |
213 | // 2, | ||
214 | // ]; | ||
215 | attributes::outer_attributes(p); | 196 | attributes::outer_attributes(p); |
216 | if !p.at_ts(EXPR_FIRST) { | 197 | |
217 | p.error("expected expression"); | 198 | let cm = expr(p).0; |
199 | |||
200 | match (has_attrs, cm) { | ||
201 | (true, Some(cm)) => { | ||
202 | let kind = cm.kind(); | ||
203 | cm.undo_completion(p).abandon(p); | ||
204 | m.complete(p, kind); | ||
205 | } | ||
206 | _ => m.abandon(p), | ||
207 | } | ||
208 | |||
209 | if n_exprs == 1 && p.eat(T![;]) { | ||
210 | has_semi = true; | ||
211 | continue; | ||
212 | } | ||
213 | |||
214 | if has_semi || !p.at(T![']']) && !p.expect(T![,]) { | ||
218 | break; | 215 | break; |
219 | } | 216 | } |
220 | expr(p); | ||
221 | } | 217 | } |
222 | p.expect(T![']']); | 218 | p.expect(T![']']); |
219 | |||
223 | m.complete(p, ARRAY_EXPR) | 220 | m.complete(p, ARRAY_EXPR) |
224 | } | 221 | } |
225 | 222 | ||