Repository: rust-analyzer/rust-analyzer
Pull request #301 (2018-12-20 11:35:40)

Fix break in a condition
The part of fixing #290.


Patch:
diff --git a/crates/ra_syntax/src/grammar/expressions/atom.rs b/crates/ra_syntax/src/grammar/expressions/atom.rs
index cd7d62affb..3b5749318d 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> {
     Some(m.complete(p, LITERAL))
 }
 
+// E.g. for after the break in `if break {}`, this should not match
 pub(super) const ATOM_EXPR_FIRST: TokenSet = token_set_union![
     LITERAL_FIRST,
     token_set![
-        L_CURLY,
         L_PAREN,
+        L_CURLY,
         L_BRACK,
         PIPE,
         MOVE_KW,
@@ -108,7 +109,7 @@ pub(super) fn atom_expr(p: &mut Parser, r: Restrictions) -> Option<(CompletedMar
         L_CURLY => block_expr(p, None),
         RETURN_KW => return_expr(p),
         CONTINUE_KW => continue_expr(p),
-        BREAK_KW => break_expr(p),
+        BREAK_KW => break_expr(p, r),
         _ => {
             p.err_recover("expected expression", EXPR_RECOVERY_SET);
             return None;
@@ -427,12 +428,19 @@ fn continue_expr(p: &mut Parser) -> CompletedMarker {
 //         break 'l 92;
 //     }
 // }
-fn break_expr(p: &mut Parser) -> CompletedMarker {
+fn break_expr(p: &mut Parser, r: Restrictions) -> CompletedMarker {
     assert!(p.at(BREAK_KW));
     let m = p.start();
     p.bump();
     p.eat(LIFETIME);
-    if p.at_ts(EXPR_FIRST) {
+    // test break_ambiguity
+    // fn foo(){
+    //     if break {}
+    //     while break {}
+    //     for i in break {}
+    //     match break {}
+    // }
+    if p.at_ts(EXPR_FIRST) && !(r.forbid_structs && p.at(L_CURLY)) {
         expr(p);
     }
     m.complete(p, BREAK_EXPR)


Test patch:
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 0000000000..560eb05b94
--- /dev/null
+++ b/crates/ra_syntax/tests/data/parser/inline/0119_break_ambiguity.rs
@@ -0,0 +1,6 @@
+fn foo(){
+    if break {}
+    while break {}
+    for i in break {}
+    match break {}
+}
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 0000000000..6032a6c17f
--- /dev/null
+++ b/crates/ra_syntax/tests/data/parser/inline/0119_break_ambiguity.txt
@@ -0,0 +1,65 @@
+SOURCE_FILE@[0; 88)
+  FN_DEF@[0; 87)
+    FN_KW@[0; 2)
+    WHITESPACE@[2; 3)
+    NAME@[3; 6)
+      IDENT@[3; 6) "foo"
+    PARAM_LIST@[6; 8)
+      L_PAREN@[6; 7)
+      R_PAREN@[7; 8)
+    BLOCK@[8; 87)
+      L_CURLY@[8; 9)
+      WHITESPACE@[9; 14)
+      EXPR_STMT@[14; 25)
+        IF_EXPR@[14; 25)
+          IF_KW@[14; 16)
+          WHITESPACE@[16; 17)
+          CONDITION@[17; 22)
+            BREAK_EXPR@[17; 22)
+              BREAK_KW@[17; 22)
+          WHITESPACE@[22; 23)
+          BLOCK@[23; 25)
+            L_CURLY@[23; 24)
+            R_CURLY@[24; 25)
+      WHITESPACE@[25; 30)
+      EXPR_STMT@[30; 44)
+        WHILE_EXPR@[30; 44)
+          WHILE_KW@[30; 35)
+          WHITESPACE@[35; 36)
+          CONDITION@[36; 41)
+            BREAK_EXPR@[36; 41)
+              BREAK_KW@[36; 41)
+          WHITESPACE@[41; 42)
+          BLOCK@[42; 44)
+            L_CURLY@[42; 43)
+            R_CURLY@[43; 44)
+      WHITESPACE@[44; 49)
+      EXPR_STMT@[49; 66)
+        FOR_EXPR@[49; 66)
+          FOR_KW@[49; 52)
+          WHITESPACE@[52; 53)
+          BIND_PAT@[53; 54)
+            NAME@[53; 54)
+              IDENT@[53; 54) "i"
+          WHITESPACE@[54; 55)
+          IN_KW@[55; 57)
+          WHITESPACE@[57; 58)
+          BREAK_EXPR@[58; 63)
+            BREAK_KW@[58; 63)
+          WHITESPACE@[63; 64)
+          BLOCK@[64; 66)
+            L_CURLY@[64; 65)
+            R_CURLY@[65; 66)
+      WHITESPACE@[66; 71)
+      MATCH_EXPR@[71; 85)
+        MATCH_KW@[71; 76)
+        WHITESPACE@[76; 77)
+        BREAK_EXPR@[77; 82)
+          BREAK_KW@[77; 82)
+        WHITESPACE@[82; 83)
+        MATCH_ARM_LIST@[83; 85)
+          L_CURLY@[83; 84)
+          R_CURLY@[84; 85)
+      WHITESPACE@[85; 86)
+      R_CURLY@[86; 87)
+  WHITESPACE@[87; 88)