aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_parser/src/grammar/expressions.rs
diff options
context:
space:
mode:
authorbors[bot] <26634292+bors[bot]@users.noreply.github.com>2019-10-03 16:03:29 +0100
committerGitHub <[email protected]>2019-10-03 16:03:29 +0100
commit7d1bb35fb179b7e55ceb9c5354d9d74bffb8ca63 (patch)
tree9a6b2a477a371499f7a9012b26bf639acd801cb6 /crates/ra_parser/src/grammar/expressions.rs
parente1c367595139f109fb6f53811bed7d67a384793e (diff)
parent9638adaa40d22adcf9b4002d95a13977c0f1436f (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.rs25
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);