diff options
author | bors[bot] <26634292+bors[bot]@users.noreply.github.com> | 2019-09-02 20:20:24 +0100 |
---|---|---|
committer | GitHub <[email protected]> | 2019-09-02 20:20:24 +0100 |
commit | 7faec1c30046769d4ae490e15cf5405bcfbdeef8 (patch) | |
tree | 6d268b721027a5350928a6c5a0ec227b5fde8ebc /crates/ra_hir | |
parent | a8397deab914240aca8f015fb3736689919c0a5b (diff) | |
parent | e94587e3153b52684fd3f6b82c8e7efc09ff5c8d (diff) |
Merge #1752
1752: Always wrap blocks into block expressions r=flodiebold a=matklad
This way, things like function bodies are expressions, and we don't have to single them out
Co-authored-by: Aleksey Kladov <[email protected]>
Diffstat (limited to 'crates/ra_hir')
-rw-r--r-- | crates/ra_hir/src/code_model/src.rs | 6 | ||||
-rw-r--r-- | crates/ra_hir/src/expr.rs | 52 | ||||
-rw-r--r-- | crates/ra_hir/src/expr/scope.rs | 5 | ||||
-rw-r--r-- | crates/ra_hir/src/expr/validation.rs | 13 | ||||
-rw-r--r-- | crates/ra_hir/src/source_binder.rs | 14 | ||||
-rw-r--r-- | crates/ra_hir/src/ty/tests.rs | 2 |
6 files changed, 50 insertions, 42 deletions
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 | }; |
14 | use test_utils::tested_by; | 14 | use 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)] |
58 | pub struct BodySourceMap { | 58 | pub 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 | ||
66 | type ExprPtr = Either<AstPtr<ast::Expr>, AstPtr<ast::RecordField>>; | ||
66 | type PatPtr = Either<AstPtr<ast::Pat>, AstPtr<ast::SelfParam>>; | 67 | type PatPtr = Either<AstPtr<ast::Pat>, AstPtr<ast::SelfParam>>; |
67 | 68 | ||
68 | impl Body { | 69 | impl Body { |
@@ -128,16 +129,12 @@ impl Index<PatId> for Body { | |||
128 | } | 129 | } |
129 | 130 | ||
130 | impl BodySourceMap { | 131 | impl 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)] |
173 | mod tests { | 173 | mod 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 @@ | |||
1 | use rustc_hash::FxHashSet; | ||
2 | use std::sync::Arc; | 1 | use std::sync::Arc; |
3 | 2 | ||
4 | use ra_syntax::ast::{AstNode, RecordLit}; | 3 | use ra_syntax::ast::{self, AstNode}; |
4 | use rustc_hash::FxHashSet; | ||
5 | 5 | ||
6 | use super::{Expr, ExprId, RecordLitField}; | 6 | use super::{Expr, ExprId, RecordLitField}; |
7 | use crate::{ | 7 | use 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 | }; |
16 | use ra_syntax::ast; | ||
17 | 16 | ||
18 | pub(crate) struct ExprValidator<'a, 'b: 'a> { | 17 | pub(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)); |