aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--crates/ra_syntax/src/grammar/expressions/atom.rs16
-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
3 files changed, 83 insertions, 4 deletions
diff --git a/crates/ra_syntax/src/grammar/expressions/atom.rs b/crates/ra_syntax/src/grammar/expressions/atom.rs
index cd7d62aff..3b5749318 100644
--- a/crates/ra_syntax/src/grammar/expressions/atom.rs
+++ b/crates/ra_syntax/src/grammar/expressions/atom.rs
@@ -35,11 +35,12 @@ 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
38// E.g. for after the break in `if break {}`, this should not match
38pub(super) const ATOM_EXPR_FIRST: TokenSet = token_set_union![ 39pub(super) const ATOM_EXPR_FIRST: 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_CURLY,
43 L_BRACK, 44 L_BRACK,
44 PIPE, 45 PIPE,
45 MOVE_KW, 46 MOVE_KW,
@@ -108,7 +109,7 @@ pub(super) fn atom_expr(p: &mut Parser, r: Restrictions) -> Option<(CompletedMar
108 L_CURLY => block_expr(p, None), 109 L_CURLY => block_expr(p, None),
109 RETURN_KW => return_expr(p), 110 RETURN_KW => return_expr(p),
110 CONTINUE_KW => continue_expr(p), 111 CONTINUE_KW => continue_expr(p),
111 BREAK_KW => break_expr(p), 112 BREAK_KW => break_expr(p, r),
112 _ => { 113 _ => {
113 p.err_recover("expected expression", EXPR_RECOVERY_SET); 114 p.err_recover("expected expression", EXPR_RECOVERY_SET);
114 return None; 115 return None;
@@ -427,12 +428,19 @@ fn continue_expr(p: &mut Parser) -> CompletedMarker {
427// break 'l 92; 428// break 'l 92;
428// } 429// }
429// } 430// }
430fn break_expr(p: &mut Parser) -> CompletedMarker { 431fn break_expr(p: &mut Parser, r: Restrictions) -> CompletedMarker {
431 assert!(p.at(BREAK_KW)); 432 assert!(p.at(BREAK_KW));
432 let m = p.start(); 433 let m = p.start();
433 p.bump(); 434 p.bump();
434 p.eat(LIFETIME); 435 p.eat(LIFETIME);
435 if p.at_ts(EXPR_FIRST) { 436 // test break_ambiguity
437 // fn foo(){
438 // if break {}
439 // while break {}
440 // for i in break {}
441 // match break {}
442 // }
443 if p.at_ts(EXPR_FIRST) && !(r.forbid_structs && p.at(L_CURLY)) {
436 expr(p); 444 expr(p);
437 } 445 }
438 m.complete(p, BREAK_EXPR) 446 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)