aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_parser/src/grammar/expressions.rs
diff options
context:
space:
mode:
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 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);