diff options
Diffstat (limited to 'crates/ra_parser/src/grammar/expressions.rs')
-rw-r--r-- | crates/ra_parser/src/grammar/expressions.rs | 25 |
1 files changed, 20 insertions, 5 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); |