aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_parser/src/grammar
diff options
context:
space:
mode:
Diffstat (limited to 'crates/ra_parser/src/grammar')
-rw-r--r--crates/ra_parser/src/grammar/expressions.rs25
-rw-r--r--crates/ra_parser/src/grammar/expressions/atom.rs10
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// }
265fn if_expr(p: &mut Parser) -> CompletedMarker { 262fn 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// }
313fn while_expr(p: &mut Parser, m: Option<Marker>) -> CompletedMarker { 311fn 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// }
360fn match_expr(p: &mut Parser) -> CompletedMarker { 360fn match_expr(p: &mut Parser) -> CompletedMarker {
361 assert!(p.at(T![match])); 361 assert!(p.at(T![match]));