aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_hir/src/expr.rs
diff options
context:
space:
mode:
authorbors[bot] <26634292+bors[bot]@users.noreply.github.com>2019-09-03 11:38:47 +0100
committerGitHub <[email protected]>2019-09-03 11:38:47 +0100
commit1c0672b7f802c7e7814ba9a1b3b21ecf866343d6 (patch)
treedf19e2603745c348e2e5d8289be80c2f511b0b0d /crates/ra_hir/src/expr.rs
parentf5b60a53f68100937d561acae51e06b5ebb6bd18 (diff)
parent9c3b25177e3c8d609dd24d2c2e01cbb82cab665f (diff)
Merge #1756
1756: Correctly build BodySourceMap for macro-expanded expressions r=flodiebold a=matklad r? @flodiebold Co-authored-by: Aleksey Kladov <[email protected]>
Diffstat (limited to 'crates/ra_hir/src/expr.rs')
-rw-r--r--crates/ra_hir/src/expr.rs29
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
18pub use self::scope::ExprScopes; 18pub use self::scope::ExprScopes;
@@ -43,23 +43,32 @@ pub struct Body {
43 body_expr: ExprId, 43 body_expr: ExprId,
44} 44}
45 45
46type ExprPtr = Either<AstPtr<ast::Expr>, AstPtr<ast::RecordField>>;
47type ExprSource = Source<ExprPtr>;
48
49type PatPtr = Either<AstPtr<ast::Pat>, AstPtr<ast::SelfParam>>;
50type 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)]
52pub struct BodySourceMap { 64pub 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
60type ExprPtr = Either<AstPtr<ast::Expr>, AstPtr<ast::RecordField>>;
61type PatPtr = Either<AstPtr<ast::Pat>, AstPtr<ast::SelfParam>>;
62
63impl Body { 72impl 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
125impl BodySourceMap { 134impl 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> {