diff options
Diffstat (limited to 'crates/ra_hir_def/src/body.rs')
-rw-r--r-- | crates/ra_hir_def/src/body.rs | 43 |
1 files changed, 27 insertions, 16 deletions
diff --git a/crates/ra_hir_def/src/body.rs b/crates/ra_hir_def/src/body.rs index 332c509e1..92c32b080 100644 --- a/crates/ra_hir_def/src/body.rs +++ b/crates/ra_hir_def/src/body.rs | |||
@@ -3,10 +3,13 @@ | |||
3 | mod lower; | 3 | mod lower; |
4 | pub mod scope; | 4 | pub mod scope; |
5 | 5 | ||
6 | use std::{ops::Index, sync::Arc}; | 6 | use std::{mem, ops::Index, sync::Arc}; |
7 | 7 | ||
8 | use drop_bomb::DropBomb; | ||
8 | use either::Either; | 9 | use either::Either; |
9 | use hir_expand::{hygiene::Hygiene, AstId, HirFileId, InFile, MacroCallKind, MacroDefId}; | 10 | use hir_expand::{ |
11 | ast_id_map::AstIdMap, hygiene::Hygiene, AstId, HirFileId, InFile, MacroCallKind, MacroDefId, | ||
12 | }; | ||
10 | use ra_arena::{map::ArenaMap, Arena}; | 13 | use ra_arena::{map::ArenaMap, Arena}; |
11 | use ra_syntax::{ast, AstNode, AstPtr}; | 14 | use ra_syntax::{ast, AstNode, AstPtr}; |
12 | use rustc_hash::FxHashMap; | 15 | use rustc_hash::FxHashMap; |
@@ -24,6 +27,7 @@ struct Expander { | |||
24 | crate_def_map: Arc<CrateDefMap>, | 27 | crate_def_map: Arc<CrateDefMap>, |
25 | current_file_id: HirFileId, | 28 | current_file_id: HirFileId, |
26 | hygiene: Hygiene, | 29 | hygiene: Hygiene, |
30 | ast_id_map: Arc<AstIdMap>, | ||
27 | module: ModuleId, | 31 | module: ModuleId, |
28 | } | 32 | } |
29 | 33 | ||
@@ -31,7 +35,8 @@ impl Expander { | |||
31 | fn new(db: &impl DefDatabase, current_file_id: HirFileId, module: ModuleId) -> Expander { | 35 | fn new(db: &impl DefDatabase, current_file_id: HirFileId, module: ModuleId) -> Expander { |
32 | let crate_def_map = db.crate_def_map(module.krate); | 36 | let crate_def_map = db.crate_def_map(module.krate); |
33 | let hygiene = Hygiene::new(db, current_file_id); | 37 | let hygiene = Hygiene::new(db, current_file_id); |
34 | Expander { crate_def_map, current_file_id, hygiene, module } | 38 | let ast_id_map = db.ast_id_map(current_file_id); |
39 | Expander { crate_def_map, current_file_id, hygiene, ast_id_map, module } | ||
35 | } | 40 | } |
36 | 41 | ||
37 | fn enter_expand( | 42 | fn enter_expand( |
@@ -52,9 +57,14 @@ impl Expander { | |||
52 | if let Some(expr) = ast::Expr::cast(node) { | 57 | if let Some(expr) = ast::Expr::cast(node) { |
53 | log::debug!("macro expansion {:#?}", expr.syntax()); | 58 | log::debug!("macro expansion {:#?}", expr.syntax()); |
54 | 59 | ||
55 | let mark = Mark { file_id: self.current_file_id }; | 60 | let mark = Mark { |
61 | file_id: self.current_file_id, | ||
62 | ast_id_map: mem::take(&mut self.ast_id_map), | ||
63 | bomb: DropBomb::new("expansion mark dropped"), | ||
64 | }; | ||
56 | self.hygiene = Hygiene::new(db, file_id); | 65 | self.hygiene = Hygiene::new(db, file_id); |
57 | self.current_file_id = file_id; | 66 | self.current_file_id = file_id; |
67 | self.ast_id_map = db.ast_id_map(file_id); | ||
58 | 68 | ||
59 | return Some((mark, expr)); | 69 | return Some((mark, expr)); |
60 | } | 70 | } |
@@ -67,10 +77,11 @@ impl Expander { | |||
67 | None | 77 | None |
68 | } | 78 | } |
69 | 79 | ||
70 | fn exit(&mut self, db: &impl DefDatabase, mark: Mark) { | 80 | fn exit(&mut self, db: &impl DefDatabase, mut mark: Mark) { |
71 | self.hygiene = Hygiene::new(db, mark.file_id); | 81 | self.hygiene = Hygiene::new(db, mark.file_id); |
72 | self.current_file_id = mark.file_id; | 82 | self.current_file_id = mark.file_id; |
73 | std::mem::forget(mark); | 83 | self.ast_id_map = mem::take(&mut mark.ast_id_map); |
84 | mark.bomb.defuse(); | ||
74 | } | 85 | } |
75 | 86 | ||
76 | fn to_source<T>(&self, value: T) -> InFile<T> { | 87 | fn to_source<T>(&self, value: T) -> InFile<T> { |
@@ -91,18 +102,17 @@ impl Expander { | |||
91 | .0 | 102 | .0 |
92 | .take_macros() | 103 | .take_macros() |
93 | } | 104 | } |
105 | |||
106 | fn ast_id<N: AstNode>(&self, item: &N) -> AstId<N> { | ||
107 | let file_local_id = self.ast_id_map.ast_id(item); | ||
108 | AstId::new(self.current_file_id, file_local_id) | ||
109 | } | ||
94 | } | 110 | } |
95 | 111 | ||
96 | struct Mark { | 112 | struct Mark { |
97 | file_id: HirFileId, | 113 | file_id: HirFileId, |
98 | } | 114 | ast_id_map: Arc<AstIdMap>, |
99 | 115 | bomb: DropBomb, | |
100 | impl Drop for Mark { | ||
101 | fn drop(&mut self) { | ||
102 | if !std::thread::panicking() { | ||
103 | panic!("dropped mark") | ||
104 | } | ||
105 | } | ||
106 | } | 116 | } |
107 | 117 | ||
108 | /// The body of an item (function, const etc.). | 118 | /// The body of an item (function, const etc.). |
@@ -174,7 +184,7 @@ impl Body { | |||
174 | } | 184 | } |
175 | }; | 185 | }; |
176 | let expander = Expander::new(db, file_id, module); | 186 | let expander = Expander::new(db, file_id, module); |
177 | let (body, source_map) = Body::new(db, expander, params, body); | 187 | let (body, source_map) = Body::new(db, def, expander, params, body); |
178 | (Arc::new(body), Arc::new(source_map)) | 188 | (Arc::new(body), Arc::new(source_map)) |
179 | } | 189 | } |
180 | 190 | ||
@@ -184,11 +194,12 @@ impl Body { | |||
184 | 194 | ||
185 | fn new( | 195 | fn new( |
186 | db: &impl DefDatabase, | 196 | db: &impl DefDatabase, |
197 | def: DefWithBodyId, | ||
187 | expander: Expander, | 198 | expander: Expander, |
188 | params: Option<ast::ParamList>, | 199 | params: Option<ast::ParamList>, |
189 | body: Option<ast::Expr>, | 200 | body: Option<ast::Expr>, |
190 | ) -> (Body, BodySourceMap) { | 201 | ) -> (Body, BodySourceMap) { |
191 | lower::lower(db, expander, params, body) | 202 | lower::lower(db, def, expander, params, body) |
192 | } | 203 | } |
193 | } | 204 | } |
194 | 205 | ||