From 359d3be308cab2415218200f5799c5031213c250 Mon Sep 17 00:00:00 2001
From: Aleksey Kladov <aleksey.kladov@gmail.com>
Date: Sat, 2 May 2020 14:34:39 +0200
Subject: Fix parsing of blocks without `{`

---
 crates/ra_parser/src/grammar/expressions.rs      | 15 +--------
 crates/ra_parser/src/grammar/expressions/atom.rs | 41 +++++++++++++-----------
 crates/ra_parser/src/grammar/items.rs            |  2 +-
 crates/ra_parser/src/grammar/type_args.rs        |  2 +-
 4 files changed, 26 insertions(+), 34 deletions(-)

(limited to 'crates/ra_parser/src/grammar')

diff --git a/crates/ra_parser/src/grammar/expressions.rs b/crates/ra_parser/src/grammar/expressions.rs
index a23dbcacf..34f039768 100644
--- a/crates/ra_parser/src/grammar/expressions.rs
+++ b/crates/ra_parser/src/grammar/expressions.rs
@@ -2,7 +2,7 @@
 
 mod atom;
 
-pub(crate) use self::atom::match_arm_list;
+pub(crate) use self::atom::{block_expr, match_arm_list};
 pub(super) use self::atom::{literal, LITERAL_FIRST};
 use super::*;
 
@@ -49,19 +49,6 @@ fn expr_no_struct(p: &mut Parser) {
     expr_bp(p, r, 1);
 }
 
-// test block
-// fn a() {}
-// fn b() { let _ = 1; }
-// fn c() { 1; 2; }
-// fn d() { 1; 2 }
-pub(crate) fn block(p: &mut Parser) {
-    if !p.at(T!['{']) {
-        p.error("expected a block");
-        return;
-    }
-    atom::block_expr(p);
-}
-
 fn is_expr_stmt_attr_allowed(kind: SyntaxKind) -> bool {
     match kind {
         BIN_EXPR | RANGE_EXPR | IF_EXPR => false,
diff --git a/crates/ra_parser/src/grammar/expressions/atom.rs b/crates/ra_parser/src/grammar/expressions/atom.rs
index efb424dae..706a2f796 100644
--- a/crates/ra_parser/src/grammar/expressions/atom.rs
+++ b/crates/ra_parser/src/grammar/expressions/atom.rs
@@ -132,7 +132,7 @@ pub(super) fn atom_expr(p: &mut Parser, r: Restrictions) -> Option<(CompletedMar
             //        break;
             //    }
             // }
-            block_expr(p)
+            block_expr_unchecked(p)
         }
         T![return] => return_expr(p),
         T![continue] => continue_expr(p),
@@ -240,13 +240,9 @@ fn lambda_expr(p: &mut Parser) -> CompletedMarker {
     p.eat(T![move]);
     params::param_list_closure(p);
     if opt_fn_ret_type(p) {
-        if p.at(T!['{']) {
-            // test lambda_ret_block
-            // fn main() { || -> i32 { 92 }(); }
-            block_expr(p);
-        } else {
-            p.error("expected `{`");
-        }
+        // test lambda_ret_block
+        // fn main() { || -> i32 { 92 }(); }
+        block_expr(p);
     } else {
         if p.at_ts(EXPR_FIRST) {
             expr(p);
@@ -270,13 +266,13 @@ fn if_expr(p: &mut Parser) -> CompletedMarker {
     let m = p.start();
     p.bump(T![if]);
     cond(p);
-    block(p);
+    block_expr(p);
     if p.at(T![else]) {
         p.bump(T![else]);
         if p.at(T![if]) {
             if_expr(p);
         } else {
-            block(p);
+            block_expr(p);
         }
     }
     m.complete(p, IF_EXPR)
@@ -304,7 +300,7 @@ fn loop_expr(p: &mut Parser, m: Option<Marker>) -> CompletedMarker {
     assert!(p.at(T![loop]));
     let m = m.unwrap_or_else(|| p.start());
     p.bump(T![loop]);
-    block(p);
+    block_expr(p);
     m.complete(p, LOOP_EXPR)
 }
 
@@ -319,7 +315,7 @@ fn while_expr(p: &mut Parser, m: Option<Marker>) -> CompletedMarker {
     let m = m.unwrap_or_else(|| p.start());
     p.bump(T![while]);
     cond(p);
-    block(p);
+    block_expr(p);
     m.complete(p, WHILE_EXPR)
 }
 
@@ -334,7 +330,7 @@ fn for_expr(p: &mut Parser, m: Option<Marker>) -> CompletedMarker {
     patterns::pattern(p);
     p.expect(T![in]);
     expr_no_struct(p);
-    block(p);
+    block_expr(p);
     m.complete(p, FOR_EXPR)
 }
 
@@ -467,11 +463,20 @@ fn match_guard(p: &mut Parser) -> CompletedMarker {
     m.complete(p, MATCH_GUARD)
 }
 
-// test block_expr
-// fn foo() {
-//     {};
-// }
-pub(super) fn block_expr(p: &mut Parser) -> CompletedMarker {
+// test block
+// fn a() {}
+// fn b() { let _ = 1; }
+// fn c() { 1; 2; }
+// fn d() { 1; 2 }
+pub(crate) fn block_expr(p: &mut Parser) {
+    if !p.at(T!['{']) {
+        p.error("expected a block");
+        return;
+    }
+    block_expr_unchecked(p);
+}
+
+fn block_expr_unchecked(p: &mut Parser) -> CompletedMarker {
     assert!(p.at(T!['{']));
     let m = p.start();
     p.bump(T!['{']);
diff --git a/crates/ra_parser/src/grammar/items.rs b/crates/ra_parser/src/grammar/items.rs
index 1503a8730..67a924de5 100644
--- a/crates/ra_parser/src/grammar/items.rs
+++ b/crates/ra_parser/src/grammar/items.rs
@@ -329,7 +329,7 @@ fn fn_def(p: &mut Parser) {
     if p.at(T![;]) {
         p.bump(T![;]);
     } else {
-        expressions::block(p)
+        expressions::block_expr(p)
     }
 }
 
diff --git a/crates/ra_parser/src/grammar/type_args.rs b/crates/ra_parser/src/grammar/type_args.rs
index 33d9973e9..2d61f9d80 100644
--- a/crates/ra_parser/src/grammar/type_args.rs
+++ b/crates/ra_parser/src/grammar/type_args.rs
@@ -48,7 +48,7 @@ fn type_arg(p: &mut Parser) {
             m.complete(p, ASSOC_TYPE_ARG);
         }
         T!['{'] => {
-            expressions::block(p);
+            expressions::block_expr(p);
             m.complete(p, CONST_ARG);
         }
         k if k.is_literal() => {
-- 
cgit v1.2.3