diff options
Diffstat (limited to 'crates/ra_syntax')
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 | ||
38 | pub(super) const ATOM_EXPR_FIRST: TokenSet = token_set_union![ | 39 | pub(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 | // } |
430 | fn break_expr(p: &mut Parser) -> CompletedMarker { | 431 | fn 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 @@ | |||
1 | fn 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 @@ | |||
1 | SOURCE_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) | ||