diff options
Diffstat (limited to 'crates/ra_parser/src')
-rw-r--r-- | crates/ra_parser/src/grammar/expressions.rs | 25 | ||||
-rw-r--r-- | crates/ra_parser/src/grammar/expressions/atom.rs | 10 |
2 files changed, 25 insertions, 10 deletions
diff --git a/crates/ra_parser/src/grammar/expressions.rs b/crates/ra_parser/src/grammar/expressions.rs index c2a2060eb..45f2e3de4 100644 --- a/crates/ra_parser/src/grammar/expressions.rs +++ b/crates/ra_parser/src/grammar/expressions.rs | |||
@@ -344,7 +344,13 @@ fn lhs(p: &mut Parser, r: Restrictions) -> Option<(CompletedMarker, BlockLike)> | |||
344 | // } | 344 | // } |
345 | // | 345 | // |
346 | let (lhs, blocklike) = atom::atom_expr(p, r)?; | 346 | let (lhs, blocklike) = atom::atom_expr(p, r)?; |
347 | return Some(postfix_expr(p, lhs, blocklike, !(r.prefer_stmt && blocklike.is_block()))); | 347 | return Some(postfix_expr( |
348 | p, | ||
349 | lhs, | ||
350 | blocklike, | ||
351 | !(r.prefer_stmt && blocklike.is_block()), | ||
352 | r.forbid_structs, | ||
353 | )); | ||
348 | } | 354 | } |
349 | }; | 355 | }; |
350 | // parse the interior of the unary expression | 356 | // parse the interior of the unary expression |
@@ -360,6 +366,7 @@ fn postfix_expr( | |||
360 | // `while true {break}; ();` | 366 | // `while true {break}; ();` |
361 | mut block_like: BlockLike, | 367 | mut block_like: BlockLike, |
362 | mut allow_calls: bool, | 368 | mut allow_calls: bool, |
369 | forbid_structs: bool, | ||
363 | ) -> (CompletedMarker, BlockLike) { | 370 | ) -> (CompletedMarker, BlockLike) { |
364 | loop { | 371 | loop { |
365 | lhs = match p.current() { | 372 | lhs = match p.current() { |
@@ -373,7 +380,7 @@ fn postfix_expr( | |||
373 | // } | 380 | // } |
374 | T!['('] if allow_calls => call_expr(p, lhs), | 381 | T!['('] if allow_calls => call_expr(p, lhs), |
375 | T!['['] if allow_calls => index_expr(p, lhs), | 382 | T!['['] if allow_calls => index_expr(p, lhs), |
376 | T![.] => match postfix_dot_expr(p, lhs) { | 383 | T![.] => match postfix_dot_expr(p, lhs, forbid_structs) { |
377 | Ok(it) => it, | 384 | Ok(it) => it, |
378 | Err(it) => { | 385 | Err(it) => { |
379 | lhs = it; | 386 | lhs = it; |
@@ -391,6 +398,7 @@ fn postfix_expr( | |||
391 | fn postfix_dot_expr( | 398 | fn postfix_dot_expr( |
392 | p: &mut Parser, | 399 | p: &mut Parser, |
393 | lhs: CompletedMarker, | 400 | lhs: CompletedMarker, |
401 | forbid_structs: bool, | ||
394 | ) -> Result<CompletedMarker, CompletedMarker> { | 402 | ) -> Result<CompletedMarker, CompletedMarker> { |
395 | assert!(p.at(T![.])); | 403 | assert!(p.at(T![.])); |
396 | if p.nth(1) == IDENT && (p.nth(2) == T!['('] || p.nth_at(2, T![::])) { | 404 | if p.nth(1) == IDENT && (p.nth(2) == T!['('] || p.nth_at(2, T![::])) { |
@@ -411,10 +419,17 @@ fn postfix_expr( | |||
411 | } | 419 | } |
412 | 420 | ||
413 | // test postfix_range | 421 | // test postfix_range |
414 | // fn foo() { let x = 1..; } | 422 | // fn foo() { |
415 | for &(op, la) in [(T![..=], 3), (T![..], 2)].iter() { | 423 | // let x = 1..; |
424 | // match 1.. { _ => () }; | ||
425 | // match a.b()..S { _ => () }; | ||
426 | // } | ||
427 | for &(op, la) in &[(T![..=], 3), (T![..], 2)] { | ||
416 | if p.at(op) { | 428 | if p.at(op) { |
417 | return if EXPR_FIRST.contains(p.nth(la)) { | 429 | let next_token = p.nth(la); |
430 | let has_trailing_expression = | ||
431 | !(forbid_structs && next_token == T!['{']) && EXPR_FIRST.contains(next_token); | ||
432 | return if has_trailing_expression { | ||
418 | Err(lhs) | 433 | Err(lhs) |
419 | } else { | 434 | } else { |
420 | let m = lhs.precede(p); | 435 | let m = lhs.precede(p); |
diff --git a/crates/ra_parser/src/grammar/expressions/atom.rs b/crates/ra_parser/src/grammar/expressions/atom.rs index a52bdb3ea..7454005c4 100644 --- a/crates/ra_parser/src/grammar/expressions/atom.rs +++ b/crates/ra_parser/src/grammar/expressions/atom.rs | |||
@@ -121,11 +121,7 @@ pub(super) fn atom_expr(p: &mut Parser, r: Restrictions) -> Option<(CompletedMar | |||
121 | // break; | 121 | // break; |
122 | // } | 122 | // } |
123 | // } | 123 | // } |
124 | if r.forbid_structs { | 124 | block_expr(p, None) |
125 | return None; | ||
126 | } else { | ||
127 | block_expr(p, None) | ||
128 | } | ||
129 | } | 125 | } |
130 | T![return] => return_expr(p), | 126 | T![return] => return_expr(p), |
131 | T![continue] => continue_expr(p), | 127 | T![continue] => continue_expr(p), |
@@ -261,6 +257,7 @@ fn lambda_expr(p: &mut Parser) -> CompletedMarker { | |||
261 | // if true {} else {}; | 257 | // if true {} else {}; |
262 | // if true {} else if false {} else {}; | 258 | // if true {} else if false {} else {}; |
263 | // if S {}; | 259 | // if S {}; |
260 | // if { true } { } else { }; | ||
264 | // } | 261 | // } |
265 | fn if_expr(p: &mut Parser) -> CompletedMarker { | 262 | fn if_expr(p: &mut Parser) -> CompletedMarker { |
266 | assert!(p.at(T![if])); | 263 | assert!(p.at(T![if])); |
@@ -309,6 +306,7 @@ fn loop_expr(p: &mut Parser, m: Option<Marker>) -> CompletedMarker { | |||
309 | // fn foo() { | 306 | // fn foo() { |
310 | // while true {}; | 307 | // while true {}; |
311 | // while let Some(x) = it.next() {}; | 308 | // while let Some(x) = it.next() {}; |
309 | // while { true } {}; | ||
312 | // } | 310 | // } |
313 | fn while_expr(p: &mut Parser, m: Option<Marker>) -> CompletedMarker { | 311 | fn while_expr(p: &mut Parser, m: Option<Marker>) -> CompletedMarker { |
314 | assert!(p.at(T![while])); | 312 | assert!(p.at(T![while])); |
@@ -356,6 +354,8 @@ fn cond(p: &mut Parser) { | |||
356 | // fn foo() { | 354 | // fn foo() { |
357 | // match () { }; | 355 | // match () { }; |
358 | // match S {}; | 356 | // match S {}; |
357 | // match { } { _ => () }; | ||
358 | // match { S {} } {}; | ||
359 | // } | 359 | // } |
360 | fn match_expr(p: &mut Parser) -> CompletedMarker { | 360 | fn match_expr(p: &mut Parser) -> CompletedMarker { |
361 | assert!(p.at(T![match])); | 361 | assert!(p.at(T![match])); |