aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAleksey Kladov <[email protected]>2019-09-02 19:23:19 +0100
committerAleksey Kladov <[email protected]>2019-09-02 19:23:19 +0100
commit5e3f291195b580580be7ce5622f54ebca75fb9f0 (patch)
tree772693eb44bde1fac1b9292456e1fa6e056bdb1f
parentdcf8e895038a7677711b8168ee12e1d47f6018bc (diff)
fix hir for new block syntax
-rw-r--r--crates/ra_assists/src/move_guard.rs4
-rw-r--r--crates/ra_assists/src/replace_if_let_with_match.rs16
-rw-r--r--crates/ra_fmt/src/lib.rs3
-rw-r--r--crates/ra_hir/src/code_model/src.rs6
-rw-r--r--crates/ra_hir/src/expr.rs52
-rw-r--r--crates/ra_hir/src/expr/scope.rs5
-rw-r--r--crates/ra_hir/src/expr/validation.rs13
-rw-r--r--crates/ra_hir/src/source_binder.rs14
-rw-r--r--crates/ra_hir/src/ty/tests.rs2
-rw-r--r--crates/ra_ide_api/src/join_lines.rs2
-rw-r--r--crates/ra_syntax/src/ast/expr_extensions.rs6
-rw-r--r--crates/ra_syntax/src/ast/generated.rs2
-rw-r--r--crates/ra_syntax/src/ast/traits.rs2
-rw-r--r--crates/ra_syntax/src/grammar.ron2
14 files changed, 72 insertions, 57 deletions
diff --git a/crates/ra_assists/src/move_guard.rs b/crates/ra_assists/src/move_guard.rs
index 127c9e068..699221e33 100644
--- a/crates/ra_assists/src/move_guard.rs
+++ b/crates/ra_assists/src/move_guard.rs
@@ -65,9 +65,9 @@ pub(crate) fn move_arm_cond_to_match_guard(mut ctx: AssistCtx<impl HirDatabase>)
65 "move condition to match guard", 65 "move condition to match guard",
66 |edit| { 66 |edit| {
67 edit.target(if_expr.syntax().text_range()); 67 edit.target(if_expr.syntax().text_range());
68 let then_only_expr = then_block.statements().next().is_none(); 68 let then_only_expr = then_block.block().and_then(|it| it.statements().next()).is_none();
69 69
70 match &then_block.expr() { 70 match &then_block.block().and_then(|it| it.expr()) {
71 Some(then_expr) if then_only_expr => { 71 Some(then_expr) if then_only_expr => {
72 edit.replace(if_expr.syntax().text_range(), then_expr.syntax().text()) 72 edit.replace(if_expr.syntax().text_range(), then_expr.syntax().text())
73 } 73 }
diff --git a/crates/ra_assists/src/replace_if_let_with_match.rs b/crates/ra_assists/src/replace_if_let_with_match.rs
index c0bf6d235..401835c57 100644
--- a/crates/ra_assists/src/replace_if_let_with_match.rs
+++ b/crates/ra_assists/src/replace_if_let_with_match.rs
@@ -1,3 +1,4 @@
1use format_buf::format;
1use hir::db::HirDatabase; 2use hir::db::HirDatabase;
2use ra_fmt::extract_trivial_expression; 3use ra_fmt::extract_trivial_expression;
3use ra_syntax::{ast, AstNode}; 4use ra_syntax::{ast, AstNode};
@@ -25,16 +26,21 @@ pub(crate) fn replace_if_let_with_match(mut ctx: AssistCtx<impl HirDatabase>) ->
25 ctx.build() 26 ctx.build()
26} 27}
27 28
28fn build_match_expr(expr: ast::Expr, pat1: ast::Pat, arm1: ast::Block, arm2: ast::Block) -> String { 29fn build_match_expr(
30 expr: ast::Expr,
31 pat1: ast::Pat,
32 arm1: ast::BlockExpr,
33 arm2: ast::BlockExpr,
34) -> String {
29 let mut buf = String::new(); 35 let mut buf = String::new();
30 buf.push_str(&format!("match {} {{\n", expr.syntax().text())); 36 format!(buf, "match {} {{\n", expr.syntax().text());
31 buf.push_str(&format!(" {} => {}\n", pat1.syntax().text(), format_arm(&arm1))); 37 format!(buf, " {} => {}\n", pat1.syntax().text(), format_arm(&arm1));
32 buf.push_str(&format!(" _ => {}\n", format_arm(&arm2))); 38 format!(buf, " _ => {}\n", format_arm(&arm2));
33 buf.push_str("}"); 39 buf.push_str("}");
34 buf 40 buf
35} 41}
36 42
37fn format_arm(block: &ast::Block) -> String { 43fn format_arm(block: &ast::BlockExpr) -> String {
38 match extract_trivial_expression(block) { 44 match extract_trivial_expression(block) {
39 None => block.syntax().text().to_string(), 45 None => block.syntax().text().to_string(),
40 Some(e) => format!("{},", e.syntax().text()), 46 Some(e) => format!("{},", e.syntax().text()),
diff --git a/crates/ra_fmt/src/lib.rs b/crates/ra_fmt/src/lib.rs
index b09478d7a..e22ac9753 100644
--- a/crates/ra_fmt/src/lib.rs
+++ b/crates/ra_fmt/src/lib.rs
@@ -34,7 +34,8 @@ fn prev_tokens(token: SyntaxToken) -> impl Iterator<Item = SyntaxToken> {
34 successors(token.prev_token(), |token| token.prev_token()) 34 successors(token.prev_token(), |token| token.prev_token())
35} 35}
36 36
37pub fn extract_trivial_expression(block: &ast::Block) -> Option<ast::Expr> { 37pub fn extract_trivial_expression(expr: &ast::BlockExpr) -> Option<ast::Expr> {
38 let block = expr.block()?;
38 let expr = block.expr()?; 39 let expr = block.expr()?;
39 if expr.syntax().text().contains_char('\n') { 40 if expr.syntax().text().contains_char('\n') {
40 return None; 41 return None;
diff --git a/crates/ra_hir/src/code_model/src.rs b/crates/ra_hir/src/code_model/src.rs
index e5bae16ab..7c9454c0b 100644
--- a/crates/ra_hir/src/code_model/src.rs
+++ b/crates/ra_hir/src/code_model/src.rs
@@ -119,10 +119,10 @@ where
119 expr_id: crate::expr::ExprId, 119 expr_id: crate::expr::ExprId,
120 ) -> Option<Source<ast::Expr>> { 120 ) -> Option<Source<ast::Expr>> {
121 let source_map = self.body_source_map(db); 121 let source_map = self.body_source_map(db);
122 let expr_syntax = source_map.expr_syntax(expr_id)?; 122 let expr_syntax = source_map.expr_syntax(expr_id)?.a()?;
123 let source = self.source(db); 123 let source = self.source(db);
124 let node = expr_syntax.to_node(&source.ast.syntax()); 124 let ast = expr_syntax.to_node(&source.ast.syntax());
125 ast::Expr::cast(node).map(|ast| Source { file_id: source.file_id, ast }) 125 Some(Source { file_id: source.file_id, ast })
126 } 126 }
127} 127}
128 128
diff --git a/crates/ra_hir/src/expr.rs b/crates/ra_hir/src/expr.rs
index c7530849b..5c95bed40 100644
--- a/crates/ra_hir/src/expr.rs
+++ b/crates/ra_hir/src/expr.rs
@@ -9,7 +9,7 @@ use ra_syntax::{
9 self, ArgListOwner, ArrayExprKind, LiteralKind, LoopBodyOwner, NameOwner, 9 self, ArgListOwner, ArrayExprKind, LiteralKind, LoopBodyOwner, NameOwner,
10 TypeAscriptionOwner, 10 TypeAscriptionOwner,
11 }, 11 },
12 AstNode, AstPtr, SyntaxNodePtr, 12 AstNode, AstPtr,
13}; 13};
14use test_utils::tested_by; 14use test_utils::tested_by;
15 15
@@ -56,13 +56,14 @@ pub struct Body {
56/// file, so that we don't recompute types whenever some whitespace is typed. 56/// file, so that we don't recompute types whenever some whitespace is typed.
57#[derive(Default, Debug, Eq, PartialEq)] 57#[derive(Default, Debug, Eq, PartialEq)]
58pub struct BodySourceMap { 58pub struct BodySourceMap {
59 expr_map: FxHashMap<SyntaxNodePtr, ExprId>, 59 expr_map: FxHashMap<ExprPtr, ExprId>,
60 expr_map_back: ArenaMap<ExprId, SyntaxNodePtr>, 60 expr_map_back: ArenaMap<ExprId, ExprPtr>,
61 pat_map: FxHashMap<PatPtr, PatId>, 61 pat_map: FxHashMap<PatPtr, PatId>,
62 pat_map_back: ArenaMap<PatId, PatPtr>, 62 pat_map_back: ArenaMap<PatId, PatPtr>,
63 field_map: FxHashMap<(ExprId, usize), AstPtr<ast::RecordField>>, 63 field_map: FxHashMap<(ExprId, usize), AstPtr<ast::RecordField>>,
64} 64}
65 65
66type ExprPtr = Either<AstPtr<ast::Expr>, AstPtr<ast::RecordField>>;
66type PatPtr = Either<AstPtr<ast::Pat>, AstPtr<ast::SelfParam>>; 67type PatPtr = Either<AstPtr<ast::Pat>, AstPtr<ast::SelfParam>>;
67 68
68impl Body { 69impl Body {
@@ -128,16 +129,12 @@ impl Index<PatId> for Body {
128} 129}
129 130
130impl BodySourceMap { 131impl BodySourceMap {
131 pub(crate) fn expr_syntax(&self, expr: ExprId) -> Option<SyntaxNodePtr> { 132 pub(crate) fn expr_syntax(&self, expr: ExprId) -> Option<ExprPtr> {
132 self.expr_map_back.get(expr).cloned() 133 self.expr_map_back.get(expr).cloned()
133 } 134 }
134 135
135 pub(crate) fn syntax_expr(&self, ptr: SyntaxNodePtr) -> Option<ExprId> {
136 self.expr_map.get(&ptr).cloned()
137 }
138
139 pub(crate) fn node_expr(&self, node: &ast::Expr) -> Option<ExprId> { 136 pub(crate) fn node_expr(&self, node: &ast::Expr) -> Option<ExprId> {
140 self.expr_map.get(&SyntaxNodePtr::new(node.syntax())).cloned() 137 self.expr_map.get(&Either::A(AstPtr::new(node))).cloned()
141 } 138 }
142 139
143 pub(crate) fn pat_syntax(&self, pat: PatId) -> Option<PatPtr> { 140 pub(crate) fn pat_syntax(&self, pat: PatId) -> Option<PatPtr> {
@@ -575,11 +572,12 @@ where
575 current_file_id: file_id, 572 current_file_id: file_id,
576 } 573 }
577 } 574 }
578 fn alloc_expr(&mut self, expr: Expr, syntax_ptr: SyntaxNodePtr) -> ExprId { 575 fn alloc_expr(&mut self, expr: Expr, ptr: AstPtr<ast::Expr>) -> ExprId {
576 let ptr = Either::A(ptr);
579 let id = self.exprs.alloc(expr); 577 let id = self.exprs.alloc(expr);
580 if self.current_file_id == self.original_file_id { 578 if self.current_file_id == self.original_file_id {
581 self.source_map.expr_map.insert(syntax_ptr, id); 579 self.source_map.expr_map.insert(ptr, id);
582 self.source_map.expr_map_back.insert(id, syntax_ptr); 580 self.source_map.expr_map_back.insert(id, ptr);
583 } 581 }
584 id 582 id
585 } 583 }
@@ -601,7 +599,7 @@ where
601 } 599 }
602 600
603 fn collect_expr(&mut self, expr: ast::Expr) -> ExprId { 601 fn collect_expr(&mut self, expr: ast::Expr) -> ExprId {
604 let syntax_ptr = SyntaxNodePtr::new(expr.syntax()); 602 let syntax_ptr = AstPtr::new(&expr);
605 match expr { 603 match expr {
606 ast::Expr::IfExpr(e) => { 604 ast::Expr::IfExpr(e) => {
607 let then_branch = self.collect_block_opt(e.then_branch()); 605 let then_branch = self.collect_block_opt(e.then_branch());
@@ -640,10 +638,10 @@ where
640 self.alloc_expr(Expr::If { condition, then_branch, else_branch }, syntax_ptr) 638 self.alloc_expr(Expr::If { condition, then_branch, else_branch }, syntax_ptr)
641 } 639 }
642 ast::Expr::TryBlockExpr(e) => { 640 ast::Expr::TryBlockExpr(e) => {
643 let body = self.collect_block_opt(e.block()); 641 let body = self.collect_block_opt(e.body());
644 self.alloc_expr(Expr::TryBlock { body }, syntax_ptr) 642 self.alloc_expr(Expr::TryBlock { body }, syntax_ptr)
645 } 643 }
646 ast::Expr::BlockExpr(e) => self.collect_block_opt(e.block()), 644 ast::Expr::BlockExpr(e) => self.collect_block(e),
647 ast::Expr::LoopExpr(e) => { 645 ast::Expr::LoopExpr(e) => {
648 let body = self.collect_block_opt(e.loop_body()); 646 let body = self.collect_block_opt(e.loop_body());
649 self.alloc_expr(Expr::Loop { body }, syntax_ptr) 647 self.alloc_expr(Expr::Loop { body }, syntax_ptr)
@@ -739,7 +737,7 @@ where
739 ast::Expr::ParenExpr(e) => { 737 ast::Expr::ParenExpr(e) => {
740 let inner = self.collect_expr_opt(e.expr()); 738 let inner = self.collect_expr_opt(e.expr());
741 // make the paren expr point to the inner expression as well 739 // make the paren expr point to the inner expression as well
742 self.source_map.expr_map.insert(syntax_ptr, inner); 740 self.source_map.expr_map.insert(Either::A(syntax_ptr), inner);
743 inner 741 inner
744 } 742 }
745 ast::Expr::ReturnExpr(e) => { 743 ast::Expr::ReturnExpr(e) => {
@@ -763,12 +761,9 @@ where
763 } else if let Some(nr) = field.name_ref() { 761 } else if let Some(nr) = field.name_ref() {
764 // field shorthand 762 // field shorthand
765 let id = self.exprs.alloc(Expr::Path(Path::from_name_ref(&nr))); 763 let id = self.exprs.alloc(Expr::Path(Path::from_name_ref(&nr)));
766 self.source_map 764 let ptr = Either::B(AstPtr::new(&field));
767 .expr_map 765 self.source_map.expr_map.insert(ptr, id);
768 .insert(SyntaxNodePtr::new(nr.syntax()), id); 766 self.source_map.expr_map_back.insert(id, ptr);
769 self.source_map
770 .expr_map_back
771 .insert(id, SyntaxNodePtr::new(nr.syntax()));
772 id 767 id
773 } else { 768 } else {
774 self.exprs.alloc(Expr::Missing) 769 self.exprs.alloc(Expr::Missing)
@@ -942,7 +937,12 @@ where
942 } 937 }
943 } 938 }
944 939
945 fn collect_block(&mut self, block: ast::Block) -> ExprId { 940 fn collect_block(&mut self, expr: ast::BlockExpr) -> ExprId {
941 let syntax_node_ptr = AstPtr::new(&expr.clone().into());
942 let block = match expr.block() {
943 Some(block) => block,
944 None => return self.alloc_expr(Expr::Missing, syntax_node_ptr),
945 };
946 let statements = block 946 let statements = block
947 .statements() 947 .statements()
948 .map(|s| match s { 948 .map(|s| match s {
@@ -956,11 +956,11 @@ where
956 }) 956 })
957 .collect(); 957 .collect();
958 let tail = block.expr().map(|e| self.collect_expr(e)); 958 let tail = block.expr().map(|e| self.collect_expr(e));
959 self.alloc_expr(Expr::Block { statements, tail }, SyntaxNodePtr::new(block.syntax())) 959 self.alloc_expr(Expr::Block { statements, tail }, syntax_node_ptr)
960 } 960 }
961 961
962 fn collect_block_opt(&mut self, block: Option<ast::Block>) -> ExprId { 962 fn collect_block_opt(&mut self, expr: Option<ast::BlockExpr>) -> ExprId {
963 if let Some(block) = block { 963 if let Some(block) = expr {
964 self.collect_block(block) 964 self.collect_block(block)
965 } else { 965 } else {
966 self.exprs.alloc(Expr::Missing) 966 self.exprs.alloc(Expr::Missing)
diff --git a/crates/ra_hir/src/expr/scope.rs b/crates/ra_hir/src/expr/scope.rs
index 79e1857f9..b6d7f3fc1 100644
--- a/crates/ra_hir/src/expr/scope.rs
+++ b/crates/ra_hir/src/expr/scope.rs
@@ -172,7 +172,7 @@ fn compute_expr_scopes(expr: ExprId, body: &Body, scopes: &mut ExprScopes, scope
172#[cfg(test)] 172#[cfg(test)]
173mod tests { 173mod tests {
174 use ra_db::SourceDatabase; 174 use ra_db::SourceDatabase;
175 use ra_syntax::{algo::find_node_at_offset, ast, AstNode, SyntaxNodePtr}; 175 use ra_syntax::{algo::find_node_at_offset, ast, AstNode};
176 use test_utils::{assert_eq_text, extract_offset}; 176 use test_utils::{assert_eq_text, extract_offset};
177 177
178 use crate::{mock::MockDatabase, source_binder::SourceAnalyzer}; 178 use crate::{mock::MockDatabase, source_binder::SourceAnalyzer};
@@ -194,8 +194,7 @@ mod tests {
194 let analyzer = SourceAnalyzer::new(&db, file_id, marker.syntax(), None); 194 let analyzer = SourceAnalyzer::new(&db, file_id, marker.syntax(), None);
195 195
196 let scopes = analyzer.scopes(); 196 let scopes = analyzer.scopes();
197 let expr_id = 197 let expr_id = analyzer.body_source_map().node_expr(&marker.into()).unwrap();
198 analyzer.body_source_map().syntax_expr(SyntaxNodePtr::new(marker.syntax())).unwrap();
199 let scope = scopes.scope_for(expr_id); 198 let scope = scopes.scope_for(expr_id);
200 199
201 let actual = scopes 200 let actual = scopes
diff --git a/crates/ra_hir/src/expr/validation.rs b/crates/ra_hir/src/expr/validation.rs
index c8ae19869..6fdaf1fce 100644
--- a/crates/ra_hir/src/expr/validation.rs
+++ b/crates/ra_hir/src/expr/validation.rs
@@ -1,7 +1,7 @@
1use rustc_hash::FxHashSet;
2use std::sync::Arc; 1use std::sync::Arc;
3 2
4use ra_syntax::ast::{AstNode, RecordLit}; 3use ra_syntax::ast::{self, AstNode};
4use rustc_hash::FxHashSet;
5 5
6use super::{Expr, ExprId, RecordLitField}; 6use super::{Expr, ExprId, RecordLitField};
7use crate::{ 7use crate::{
@@ -13,7 +13,6 @@ use crate::{
13 ty::{ApplicationTy, InferenceResult, Ty, TypeCtor}, 13 ty::{ApplicationTy, InferenceResult, Ty, TypeCtor},
14 Function, HasSource, HirDatabase, ModuleDef, Name, Path, PerNs, Resolution, 14 Function, HasSource, HirDatabase, ModuleDef, Name, Path, PerNs, Resolution,
15}; 15};
16use ra_syntax::ast;
17 16
18pub(crate) struct ExprValidator<'a, 'b: 'a> { 17pub(crate) struct ExprValidator<'a, 'b: 'a> {
19 func: Function, 18 func: Function,
@@ -84,8 +83,12 @@ impl<'a, 'b> ExprValidator<'a, 'b> {
84 let source_file = parse.tree(); 83 let source_file = parse.tree();
85 if let Some(field_list_node) = source_map 84 if let Some(field_list_node) = source_map
86 .expr_syntax(id) 85 .expr_syntax(id)
86 .and_then(|ptr| ptr.a())
87 .map(|ptr| ptr.to_node(source_file.syntax())) 87 .map(|ptr| ptr.to_node(source_file.syntax()))
88 .and_then(RecordLit::cast) 88 .and_then(|expr| match expr {
89 ast::Expr::RecordLit(it) => Some(it),
90 _ => None,
91 })
89 .and_then(|lit| lit.record_field_list()) 92 .and_then(|lit| lit.record_field_list())
90 { 93 {
91 let field_list_ptr = AstPtr::new(&field_list_node); 94 let field_list_ptr = AstPtr::new(&field_list_node);
@@ -135,7 +138,7 @@ impl<'a, 'b> ExprValidator<'a, 'b> {
135 let source_map = self.func.body_source_map(db); 138 let source_map = self.func.body_source_map(db);
136 let file_id = self.func.source(db).file_id; 139 let file_id = self.func.source(db).file_id;
137 140
138 if let Some(expr) = source_map.expr_syntax(id).and_then(|n| n.cast::<ast::Expr>()) { 141 if let Some(expr) = source_map.expr_syntax(id).and_then(|n| n.a()) {
139 self.sink.push(MissingOkInTailExpr { file: file_id, expr }); 142 self.sink.push(MissingOkInTailExpr { file: file_id, expr });
140 } 143 }
141 } 144 }
diff --git a/crates/ra_hir/src/source_binder.rs b/crates/ra_hir/src/source_binder.rs
index 43aec201a..e5f4d11a6 100644
--- a/crates/ra_hir/src/source_binder.rs
+++ b/crates/ra_hir/src/source_binder.rs
@@ -462,8 +462,8 @@ fn scope_for(
462 node: &SyntaxNode, 462 node: &SyntaxNode,
463) -> Option<ScopeId> { 463) -> Option<ScopeId> {
464 node.ancestors() 464 node.ancestors()
465 .map(|it| SyntaxNodePtr::new(&it)) 465 .filter_map(ast::Expr::cast)
466 .filter_map(|ptr| source_map.syntax_expr(ptr)) 466 .filter_map(|it| source_map.node_expr(&it))
467 .find_map(|it| scopes.scope_for(it)) 467 .find_map(|it| scopes.scope_for(it))
468} 468}
469 469
@@ -475,7 +475,10 @@ fn scope_for_offset(
475 scopes 475 scopes
476 .scope_by_expr() 476 .scope_by_expr()
477 .iter() 477 .iter()
478 .filter_map(|(id, scope)| Some((source_map.expr_syntax(*id)?, scope))) 478 .filter_map(|(id, scope)| {
479 let ast_ptr = source_map.expr_syntax(*id)?.a()?;
480 Some((ast_ptr.syntax_node_ptr(), scope))
481 })
479 // find containing scope 482 // find containing scope
480 .min_by_key(|(ptr, _scope)| { 483 .min_by_key(|(ptr, _scope)| {
481 (!(ptr.range().start() <= offset && offset <= ptr.range().end()), ptr.range().len()) 484 (!(ptr.range().start() <= offset && offset <= ptr.range().end()), ptr.range().len())
@@ -495,7 +498,10 @@ fn adjust(
495 let child_scopes = scopes 498 let child_scopes = scopes
496 .scope_by_expr() 499 .scope_by_expr()
497 .iter() 500 .iter()
498 .filter_map(|(id, scope)| Some((source_map.expr_syntax(*id)?, scope))) 501 .filter_map(|(id, scope)| {
502 let ast_ptr = source_map.expr_syntax(*id)?.a()?;
503 Some((ast_ptr.syntax_node_ptr(), scope))
504 })
499 .map(|(ptr, scope)| (ptr.range(), scope)) 505 .map(|(ptr, scope)| (ptr.range(), scope))
500 .filter(|(range, _)| range.start() <= offset && range.is_subrange(&r) && *range != r); 506 .filter(|(range, _)| range.start() <= offset && range.is_subrange(&r) && *range != r);
501 507
diff --git a/crates/ra_hir/src/ty/tests.rs b/crates/ra_hir/src/ty/tests.rs
index b034fd59e..d344ab12e 100644
--- a/crates/ra_hir/src/ty/tests.rs
+++ b/crates/ra_hir/src/ty/tests.rs
@@ -3582,7 +3582,7 @@ fn infer(content: &str) -> String {
3582 3582
3583 for (expr, ty) in inference_result.type_of_expr.iter() { 3583 for (expr, ty) in inference_result.type_of_expr.iter() {
3584 let syntax_ptr = match body_source_map.expr_syntax(expr) { 3584 let syntax_ptr = match body_source_map.expr_syntax(expr) {
3585 Some(sp) => sp, 3585 Some(sp) => sp.either(|it| it.syntax_node_ptr(), |it| it.syntax_node_ptr()),
3586 None => continue, 3586 None => continue,
3587 }; 3587 };
3588 types.push((syntax_ptr, ty)); 3588 types.push((syntax_ptr, ty));
diff --git a/crates/ra_ide_api/src/join_lines.rs b/crates/ra_ide_api/src/join_lines.rs
index a2e4b6f3c..a71e4ed7d 100644
--- a/crates/ra_ide_api/src/join_lines.rs
+++ b/crates/ra_ide_api/src/join_lines.rs
@@ -123,7 +123,7 @@ fn has_comma_after(node: &SyntaxNode) -> bool {
123fn join_single_expr_block(edit: &mut TextEditBuilder, token: &SyntaxToken) -> Option<()> { 123fn join_single_expr_block(edit: &mut TextEditBuilder, token: &SyntaxToken) -> Option<()> {
124 let block = ast::Block::cast(token.parent())?; 124 let block = ast::Block::cast(token.parent())?;
125 let block_expr = ast::BlockExpr::cast(block.syntax().parent()?)?; 125 let block_expr = ast::BlockExpr::cast(block.syntax().parent()?)?;
126 let expr = extract_trivial_expression(&block)?; 126 let expr = extract_trivial_expression(&block_expr)?;
127 127
128 let block_range = block_expr.syntax().text_range(); 128 let block_range = block_expr.syntax().text_range();
129 let mut buf = expr.syntax().text().to_string(); 129 let mut buf = expr.syntax().text().to_string();
diff --git a/crates/ra_syntax/src/ast/expr_extensions.rs b/crates/ra_syntax/src/ast/expr_extensions.rs
index d7ea4354d..1324965cf 100644
--- a/crates/ra_syntax/src/ast/expr_extensions.rs
+++ b/crates/ra_syntax/src/ast/expr_extensions.rs
@@ -9,12 +9,12 @@ use crate::{
9 9
10#[derive(Debug, Clone, PartialEq, Eq)] 10#[derive(Debug, Clone, PartialEq, Eq)]
11pub enum ElseBranch { 11pub enum ElseBranch {
12 Block(ast::Block), 12 Block(ast::BlockExpr),
13 IfExpr(ast::IfExpr), 13 IfExpr(ast::IfExpr),
14} 14}
15 15
16impl ast::IfExpr { 16impl ast::IfExpr {
17 pub fn then_branch(&self) -> Option<ast::Block> { 17 pub fn then_branch(&self) -> Option<ast::BlockExpr> {
18 self.blocks().nth(0) 18 self.blocks().nth(0)
19 } 19 }
20 pub fn else_branch(&self) -> Option<ElseBranch> { 20 pub fn else_branch(&self) -> Option<ElseBranch> {
@@ -28,7 +28,7 @@ impl ast::IfExpr {
28 Some(res) 28 Some(res)
29 } 29 }
30 30
31 fn blocks(&self) -> AstChildren<ast::Block> { 31 fn blocks(&self) -> AstChildren<ast::BlockExpr> {
32 children(self) 32 children(self)
33 } 33 }
34} 34}
diff --git a/crates/ra_syntax/src/ast/generated.rs b/crates/ra_syntax/src/ast/generated.rs
index fd85a3231..e2a92ae60 100644
--- a/crates/ra_syntax/src/ast/generated.rs
+++ b/crates/ra_syntax/src/ast/generated.rs
@@ -3135,7 +3135,7 @@ impl AstNode for TryBlockExpr {
3135 } 3135 }
3136} 3136}
3137impl TryBlockExpr { 3137impl TryBlockExpr {
3138 pub fn block(&self) -> Option<Block> { 3138 pub fn body(&self) -> Option<BlockExpr> {
3139 AstChildren::new(&self.syntax).next() 3139 AstChildren::new(&self.syntax).next()
3140 } 3140 }
3141} 3141}
diff --git a/crates/ra_syntax/src/ast/traits.rs b/crates/ra_syntax/src/ast/traits.rs
index 20c251fba..c3e676d4c 100644
--- a/crates/ra_syntax/src/ast/traits.rs
+++ b/crates/ra_syntax/src/ast/traits.rs
@@ -28,7 +28,7 @@ pub trait VisibilityOwner: AstNode {
28} 28}
29 29
30pub trait LoopBodyOwner: AstNode { 30pub trait LoopBodyOwner: AstNode {
31 fn loop_body(&self) -> Option<ast::Block> { 31 fn loop_body(&self) -> Option<ast::BlockExpr> {
32 child_opt(self) 32 child_opt(self)
33 } 33 }
34} 34}
diff --git a/crates/ra_syntax/src/grammar.ron b/crates/ra_syntax/src/grammar.ron
index 37166182f..c14ee0e85 100644
--- a/crates/ra_syntax/src/grammar.ron
+++ b/crates/ra_syntax/src/grammar.ron
@@ -426,7 +426,7 @@ Grammar(
426 traits: ["LoopBodyOwner"], 426 traits: ["LoopBodyOwner"],
427 ), 427 ),
428 "TryBlockExpr": ( 428 "TryBlockExpr": (
429 options: ["Block"], 429 options: [["body", "BlockExpr"]],
430 ), 430 ),
431 "ForExpr": ( 431 "ForExpr": (
432 traits: ["LoopBodyOwner"], 432 traits: ["LoopBodyOwner"],