diff options
author | bors[bot] <26634292+bors[bot]@users.noreply.github.com> | 2019-10-03 16:03:29 +0100 |
---|---|---|
committer | GitHub <[email protected]> | 2019-10-03 16:03:29 +0100 |
commit | 7d1bb35fb179b7e55ceb9c5354d9d74bffb8ca63 (patch) | |
tree | 9a6b2a477a371499f7a9012b26bf639acd801cb6 /crates/ra_parser/src/grammar/expressions.rs | |
parent | e1c367595139f109fb6f53811bed7d67a384793e (diff) | |
parent | 9638adaa40d22adcf9b4002d95a13977c0f1436f (diff) |
Merge #1950
1950: Fix parsing of block expressions in "forbid_structs" contexts. r=kjeremy a=goffrie
Forbidding block expressions entirely is too strict; instead, we should only
forbid them in contexts where we are parsing an optional RHS (i.e. the RHS of a
range expression).
Fixes #1773.
Co-authored-by: Geoffry Song <[email protected]>
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 413ecb278..74b23e2f7 100644 --- a/crates/ra_parser/src/grammar/expressions.rs +++ b/crates/ra_parser/src/grammar/expressions.rs | |||
@@ -335,7 +335,13 @@ fn lhs(p: &mut Parser, r: Restrictions) -> Option<(CompletedMarker, BlockLike)> | |||
335 | // } | 335 | // } |
336 | // | 336 | // |
337 | let (lhs, blocklike) = atom::atom_expr(p, r)?; | 337 | let (lhs, blocklike) = atom::atom_expr(p, r)?; |
338 | return Some(postfix_expr(p, lhs, blocklike, !(r.prefer_stmt && blocklike.is_block()))); | 338 | return Some(postfix_expr( |
339 | p, | ||
340 | lhs, | ||
341 | blocklike, | ||
342 | !(r.prefer_stmt && blocklike.is_block()), | ||
343 | r.forbid_structs, | ||
344 | )); | ||
339 | } | 345 | } |
340 | }; | 346 | }; |
341 | expr_bp(p, r, 255); | 347 | expr_bp(p, r, 255); |
@@ -350,6 +356,7 @@ fn postfix_expr( | |||
350 | // `while true {break}; ();` | 356 | // `while true {break}; ();` |
351 | mut block_like: BlockLike, | 357 | mut block_like: BlockLike, |
352 | mut allow_calls: bool, | 358 | mut allow_calls: bool, |
359 | forbid_structs: bool, | ||
353 | ) -> (CompletedMarker, BlockLike) { | 360 | ) -> (CompletedMarker, BlockLike) { |
354 | loop { | 361 | loop { |
355 | lhs = match p.current() { | 362 | lhs = match p.current() { |
@@ -363,7 +370,7 @@ fn postfix_expr( | |||
363 | // } | 370 | // } |
364 | T!['('] if allow_calls => call_expr(p, lhs), | 371 | T!['('] if allow_calls => call_expr(p, lhs), |
365 | T!['['] if allow_calls => index_expr(p, lhs), | 372 | T!['['] if allow_calls => index_expr(p, lhs), |
366 | T![.] => match postfix_dot_expr(p, lhs) { | 373 | T![.] => match postfix_dot_expr(p, lhs, forbid_structs) { |
367 | Ok(it) => it, | 374 | Ok(it) => it, |
368 | Err(it) => { | 375 | Err(it) => { |
369 | lhs = it; | 376 | lhs = it; |
@@ -382,6 +389,7 @@ fn postfix_expr( | |||
382 | fn postfix_dot_expr( | 389 | fn postfix_dot_expr( |
383 | p: &mut Parser, | 390 | p: &mut Parser, |
384 | lhs: CompletedMarker, | 391 | lhs: CompletedMarker, |
392 | forbid_structs: bool, | ||
385 | ) -> Result<CompletedMarker, CompletedMarker> { | 393 | ) -> Result<CompletedMarker, CompletedMarker> { |
386 | assert!(p.at(T![.])); | 394 | assert!(p.at(T![.])); |
387 | if p.nth(1) == IDENT && (p.nth(2) == T!['('] || p.nth_at(2, T![::])) { | 395 | if p.nth(1) == IDENT && (p.nth(2) == T!['('] || p.nth_at(2, T![::])) { |
@@ -402,10 +410,17 @@ fn postfix_expr( | |||
402 | } | 410 | } |
403 | 411 | ||
404 | // test postfix_range | 412 | // test postfix_range |
405 | // fn foo() { let x = 1..; } | 413 | // fn foo() { |
406 | for &(op, la) in [(T![..=], 3), (T![..], 2)].iter() { | 414 | // let x = 1..; |
415 | // match 1.. { _ => () }; | ||
416 | // match a.b()..S { _ => () }; | ||
417 | // } | ||
418 | for &(op, la) in &[(T![..=], 3), (T![..], 2)] { | ||
407 | if p.at(op) { | 419 | if p.at(op) { |
408 | return if EXPR_FIRST.contains(p.nth(la)) { | 420 | let next_token = p.nth(la); |
421 | let has_trailing_expression = | ||
422 | !(forbid_structs && next_token == T!['{']) && EXPR_FIRST.contains(next_token); | ||
423 | return if has_trailing_expression { | ||
409 | Err(lhs) | 424 | Err(lhs) |
410 | } else { | 425 | } else { |
411 | let m = lhs.precede(p); | 426 | let m = lhs.precede(p); |