diff options
Diffstat (limited to 'crates/ra_hir/src/expr.rs')
-rw-r--r-- | crates/ra_hir/src/expr.rs | 29 |
1 files changed, 19 insertions, 10 deletions
diff --git a/crates/ra_hir/src/expr.rs b/crates/ra_hir/src/expr.rs index 5f6a4b320..fc21e269f 100644 --- a/crates/ra_hir/src/expr.rs +++ b/crates/ra_hir/src/expr.rs | |||
@@ -12,7 +12,7 @@ use crate::{ | |||
12 | path::GenericArgs, | 12 | path::GenericArgs, |
13 | ty::primitive::{UncertainFloatTy, UncertainIntTy}, | 13 | ty::primitive::{UncertainFloatTy, UncertainIntTy}, |
14 | type_ref::{Mutability, TypeRef}, | 14 | type_ref::{Mutability, TypeRef}, |
15 | DefWithBody, Either, HasSource, HirDatabase, Name, Path, Resolver, | 15 | DefWithBody, Either, HasSource, HirDatabase, Name, Path, Resolver, Source, |
16 | }; | 16 | }; |
17 | 17 | ||
18 | pub use self::scope::ExprScopes; | 18 | pub use self::scope::ExprScopes; |
@@ -43,23 +43,32 @@ pub struct Body { | |||
43 | body_expr: ExprId, | 43 | body_expr: ExprId, |
44 | } | 44 | } |
45 | 45 | ||
46 | type ExprPtr = Either<AstPtr<ast::Expr>, AstPtr<ast::RecordField>>; | ||
47 | type ExprSource = Source<ExprPtr>; | ||
48 | |||
49 | type PatPtr = Either<AstPtr<ast::Pat>, AstPtr<ast::SelfParam>>; | ||
50 | type PatSource = Source<PatPtr>; | ||
51 | |||
46 | /// An item body together with the mapping from syntax nodes to HIR expression | 52 | /// An item body together with the mapping from syntax nodes to HIR expression |
47 | /// IDs. This is needed to go from e.g. a position in a file to the HIR | 53 | /// IDs. This is needed to go from e.g. a position in a file to the HIR |
48 | /// expression containing it; but for type inference etc., we want to operate on | 54 | /// expression containing it; but for type inference etc., we want to operate on |
49 | /// a structure that is agnostic to the actual positions of expressions in the | 55 | /// a structure that is agnostic to the actual positions of expressions in the |
50 | /// 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 | /// | ||
58 | /// One complication here is that, due to macro expansion, a single `Body` might | ||
59 | /// be spread across several files. So, for each ExprId and PatId, we record | ||
60 | /// both the HirFileId and the position inside the file. However, we only store | ||
61 | /// AST -> ExprId mapping for non-macro files, as it is not clear how to handle | ||
62 | /// this properly for macros. | ||
51 | #[derive(Default, Debug, Eq, PartialEq)] | 63 | #[derive(Default, Debug, Eq, PartialEq)] |
52 | pub struct BodySourceMap { | 64 | pub struct BodySourceMap { |
53 | expr_map: FxHashMap<ExprPtr, ExprId>, | 65 | expr_map: FxHashMap<ExprPtr, ExprId>, |
54 | expr_map_back: ArenaMap<ExprId, ExprPtr>, | 66 | expr_map_back: ArenaMap<ExprId, ExprSource>, |
55 | pat_map: FxHashMap<PatPtr, PatId>, | 67 | pat_map: FxHashMap<PatPtr, PatId>, |
56 | pat_map_back: ArenaMap<PatId, PatPtr>, | 68 | pat_map_back: ArenaMap<PatId, PatSource>, |
57 | field_map: FxHashMap<(ExprId, usize), AstPtr<ast::RecordField>>, | 69 | field_map: FxHashMap<(ExprId, usize), AstPtr<ast::RecordField>>, |
58 | } | 70 | } |
59 | 71 | ||
60 | type ExprPtr = Either<AstPtr<ast::Expr>, AstPtr<ast::RecordField>>; | ||
61 | type PatPtr = Either<AstPtr<ast::Pat>, AstPtr<ast::SelfParam>>; | ||
62 | |||
63 | impl Body { | 72 | impl Body { |
64 | pub fn params(&self) -> &[PatId] { | 73 | pub fn params(&self) -> &[PatId] { |
65 | &self.params | 74 | &self.params |
@@ -123,16 +132,16 @@ impl Index<PatId> for Body { | |||
123 | } | 132 | } |
124 | 133 | ||
125 | impl BodySourceMap { | 134 | impl BodySourceMap { |
126 | pub(crate) fn expr_syntax(&self, expr: ExprId) -> Option<ExprPtr> { | 135 | pub(crate) fn expr_syntax(&self, expr: ExprId) -> Option<ExprSource> { |
127 | self.expr_map_back.get(expr).cloned() | 136 | self.expr_map_back.get(expr).copied() |
128 | } | 137 | } |
129 | 138 | ||
130 | pub(crate) fn node_expr(&self, node: &ast::Expr) -> Option<ExprId> { | 139 | pub(crate) fn node_expr(&self, node: &ast::Expr) -> Option<ExprId> { |
131 | self.expr_map.get(&Either::A(AstPtr::new(node))).cloned() | 140 | self.expr_map.get(&Either::A(AstPtr::new(node))).cloned() |
132 | } | 141 | } |
133 | 142 | ||
134 | pub(crate) fn pat_syntax(&self, pat: PatId) -> Option<PatPtr> { | 143 | pub(crate) fn pat_syntax(&self, pat: PatId) -> Option<PatSource> { |
135 | self.pat_map_back.get(pat).cloned() | 144 | self.pat_map_back.get(pat).copied() |
136 | } | 145 | } |
137 | 146 | ||
138 | pub(crate) fn node_pat(&self, node: &ast::Pat) -> Option<PatId> { | 147 | pub(crate) fn node_pat(&self, node: &ast::Pat) -> Option<PatId> { |