aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--crates/ra_syntax/src/grammar/expressions.rs5
-rw-r--r--crates/ra_syntax/src/grammar/expressions/atom.rs21
-rw-r--r--crates/ra_syntax/tests/data/parser/inline/0119_break_ambiguity.rs6
-rw-r--r--crates/ra_syntax/tests/data/parser/inline/0119_break_ambiguity.txt65
4 files changed, 92 insertions, 5 deletions
diff --git a/crates/ra_syntax/src/grammar/expressions.rs b/crates/ra_syntax/src/grammar/expressions.rs
index 4f8c46ab3..79de0add0 100644
--- a/crates/ra_syntax/src/grammar/expressions.rs
+++ b/crates/ra_syntax/src/grammar/expressions.rs
@@ -5,6 +5,7 @@ pub(super) use self::atom::{literal, LITERAL_FIRST};
5use super::*; 5use super::*;
6 6
7const EXPR_FIRST: TokenSet = LHS_FIRST; 7const EXPR_FIRST: TokenSet = LHS_FIRST;
8const EXPR_FIRST_NO_BLOCK: TokenSet = LHS_FIRST_NO_BLOCK;
8 9
9pub(super) fn expr(p: &mut Parser) -> BlockLike { 10pub(super) fn expr(p: &mut Parser) -> BlockLike {
10 let r = Restrictions { 11 let r = Restrictions {
@@ -209,6 +210,10 @@ const LHS_FIRST: TokenSet = token_set_union![
209 token_set![AMP, STAR, EXCL, DOTDOT, MINUS], 210 token_set![AMP, STAR, EXCL, DOTDOT, MINUS],
210 atom::ATOM_EXPR_FIRST, 211 atom::ATOM_EXPR_FIRST,
211]; 212];
213const LHS_FIRST_NO_BLOCK: TokenSet = token_set_union![
214 token_set![AMP, STAR, EXCL, DOTDOT, MINUS],
215 atom::ATOM_EXPR_FIRST_NO_BLOCK,
216];
212 217
213fn lhs(p: &mut Parser, r: Restrictions) -> Option<(CompletedMarker, BlockLike)> { 218fn lhs(p: &mut Parser, r: Restrictions) -> Option<(CompletedMarker, BlockLike)> {
214 let m; 219 let m;
diff --git a/crates/ra_syntax/src/grammar/expressions/atom.rs b/crates/ra_syntax/src/grammar/expressions/atom.rs
index cd7d62aff..fcc0a4490 100644
--- a/crates/ra_syntax/src/grammar/expressions/atom.rs
+++ b/crates/ra_syntax/src/grammar/expressions/atom.rs
@@ -35,10 +35,10 @@ pub(crate) fn literal(p: &mut Parser) -> Option<CompletedMarker> {
35 Some(m.complete(p, LITERAL)) 35 Some(m.complete(p, LITERAL))
36} 36}
37 37
38pub(super) const ATOM_EXPR_FIRST: TokenSet = token_set_union![ 38// E.g. for after the break in `if break {}`, this should not match
39pub(super) const ATOM_EXPR_FIRST_NO_BLOCK: TokenSet = token_set_union![
39 LITERAL_FIRST, 40 LITERAL_FIRST,
40 token_set![ 41 token_set![
41 L_CURLY,
42 L_PAREN, 42 L_PAREN,
43 L_BRACK, 43 L_BRACK,
44 PIPE, 44 PIPE,
@@ -59,6 +59,9 @@ pub(super) const ATOM_EXPR_FIRST: TokenSet = token_set_union![
59 ], 59 ],
60]; 60];
61 61
62pub(super) const ATOM_EXPR_FIRST: TokenSet =
63 token_set_union![ATOM_EXPR_FIRST_NO_BLOCK, token_set![L_CURLY],];
64
62const EXPR_RECOVERY_SET: TokenSet = token_set![LET_KW]; 65const EXPR_RECOVERY_SET: TokenSet = token_set![LET_KW];
63 66
64pub(super) fn atom_expr(p: &mut Parser, r: Restrictions) -> Option<(CompletedMarker, BlockLike)> { 67pub(super) fn atom_expr(p: &mut Parser, r: Restrictions) -> Option<(CompletedMarker, BlockLike)> {
@@ -108,7 +111,7 @@ pub(super) fn atom_expr(p: &mut Parser, r: Restrictions) -> Option<(CompletedMar
108 L_CURLY => block_expr(p, None), 111 L_CURLY => block_expr(p, None),
109 RETURN_KW => return_expr(p), 112 RETURN_KW => return_expr(p),
110 CONTINUE_KW => continue_expr(p), 113 CONTINUE_KW => continue_expr(p),
111 BREAK_KW => break_expr(p), 114 BREAK_KW => break_expr(p, r),
112 _ => { 115 _ => {
113 p.err_recover("expected expression", EXPR_RECOVERY_SET); 116 p.err_recover("expected expression", EXPR_RECOVERY_SET);
114 return None; 117 return None;
@@ -427,12 +430,20 @@ fn continue_expr(p: &mut Parser) -> CompletedMarker {
427// break 'l 92; 430// break 'l 92;
428// } 431// }
429// } 432// }
430fn break_expr(p: &mut Parser) -> CompletedMarker { 433fn break_expr(p: &mut Parser, r: Restrictions) -> CompletedMarker {
431 assert!(p.at(BREAK_KW)); 434 assert!(p.at(BREAK_KW));
432 let m = p.start(); 435 let m = p.start();
433 p.bump(); 436 p.bump();
434 p.eat(LIFETIME); 437 p.eat(LIFETIME);
435 if p.at_ts(EXPR_FIRST) { 438 // test break_ambiguity
439 // fn foo(){
440 // if break {}
441 // while break {}
442 // for i in break {}
443 // match break {}
444 // }
445 if r.forbid_structs && p.at_ts(EXPR_FIRST_NO_BLOCK) || !r.forbid_structs && p.at_ts(EXPR_FIRST)
446 {
436 expr(p); 447 expr(p);
437 } 448 }
438 m.complete(p, BREAK_EXPR) 449 m.complete(p, BREAK_EXPR)
diff --git a/crates/ra_syntax/tests/data/parser/inline/0119_break_ambiguity.rs b/crates/ra_syntax/tests/data/parser/inline/0119_break_ambiguity.rs
new file mode 100644
index 000000000..560eb05b9
--- /dev/null
+++ b/crates/ra_syntax/tests/data/parser/inline/0119_break_ambiguity.rs
@@ -0,0 +1,6 @@
1fn foo(){
2 if break {}
3 while break {}
4 for i in break {}
5 match break {}
6}
diff --git a/crates/ra_syntax/tests/data/parser/inline/0119_break_ambiguity.txt b/crates/ra_syntax/tests/data/parser/inline/0119_break_ambiguity.txt
new file mode 100644
index 000000000..6032a6c17
--- /dev/null
+++ b/crates/ra_syntax/tests/data/parser/inline/0119_break_ambiguity.txt
@@ -0,0 +1,65 @@
1SOURCE_FILE@[0; 88)
2 FN_DEF@[0; 87)
3 FN_KW@[0; 2)
4 WHITESPACE@[2; 3)
5 NAME@[3; 6)
6 IDENT@[3; 6) "foo"
7 PARAM_LIST@[6; 8)
8 L_PAREN@[6; 7)
9 R_PAREN@[7; 8)
10 BLOCK@[8; 87)
11 L_CURLY@[8; 9)
12 WHITESPACE@[9; 14)
13 EXPR_STMT@[14; 25)
14 IF_EXPR@[14; 25)
15 IF_KW@[14; 16)
16 WHITESPACE@[16; 17)
17 CONDITION@[17; 22)
18 BREAK_EXPR@[17; 22)
19 BREAK_KW@[17; 22)
20 WHITESPACE@[22; 23)
21 BLOCK@[23; 25)
22 L_CURLY@[23; 24)
23 R_CURLY@[24; 25)
24 WHITESPACE@[25; 30)
25 EXPR_STMT@[30; 44)
26 WHILE_EXPR@[30; 44)
27 WHILE_KW@[30; 35)
28 WHITESPACE@[35; 36)
29 CONDITION@[36; 41)
30 BREAK_EXPR@[36; 41)
31 BREAK_KW@[36; 41)
32 WHITESPACE@[41; 42)
33 BLOCK@[42; 44)
34 L_CURLY@[42; 43)
35 R_CURLY@[43; 44)
36 WHITESPACE@[44; 49)
37 EXPR_STMT@[49; 66)
38 FOR_EXPR@[49; 66)
39 FOR_KW@[49; 52)
40 WHITESPACE@[52; 53)
41 BIND_PAT@[53; 54)
42 NAME@[53; 54)
43 IDENT@[53; 54) "i"
44 WHITESPACE@[54; 55)
45 IN_KW@[55; 57)
46 WHITESPACE@[57; 58)
47 BREAK_EXPR@[58; 63)
48 BREAK_KW@[58; 63)
49 WHITESPACE@[63; 64)
50 BLOCK@[64; 66)
51 L_CURLY@[64; 65)
52 R_CURLY@[65; 66)
53 WHITESPACE@[66; 71)
54 MATCH_EXPR@[71; 85)
55 MATCH_KW@[71; 76)
56 WHITESPACE@[76; 77)
57 BREAK_EXPR@[77; 82)
58 BREAK_KW@[77; 82)
59 WHITESPACE@[82; 83)
60 MATCH_ARM_LIST@[83; 85)
61 L_CURLY@[83; 84)
62 R_CURLY@[84; 85)
63 WHITESPACE@[85; 86)
64 R_CURLY@[86; 87)
65 WHITESPACE@[87; 88)