diff options
-rw-r--r-- | crates/assists/src/handlers/add_lifetime_to_type.rs | 228 | ||||
-rw-r--r-- | crates/assists/src/lib.rs | 2 | ||||
-rw-r--r-- | crates/assists/src/tests/generated.rs | 19 | ||||
-rw-r--r-- | crates/hir/src/code_model.rs | 16 | ||||
-rw-r--r-- | crates/hir/src/has_source.rs | 6 | ||||
-rw-r--r-- | crates/hir/src/semantics/source_to_def.rs | 3 | ||||
-rw-r--r-- | crates/hir_def/src/attr.rs | 2 | ||||
-rw-r--r-- | crates/hir_def/src/body.rs | 2 | ||||
-rw-r--r-- | crates/hir_def/src/child_by_source.rs | 2 | ||||
-rw-r--r-- | crates/hir_def/src/find_path.rs | 10 | ||||
-rw-r--r-- | crates/hir_def/src/import_map.rs | 2 | ||||
-rw-r--r-- | crates/hir_def/src/lib.rs | 12 | ||||
-rw-r--r-- | crates/hir_def/src/nameres/collector.rs | 2 | ||||
-rw-r--r-- | crates/hir_def/src/nameres/path_resolution.rs | 4 | ||||
-rw-r--r-- | crates/hir_def/src/resolver.rs | 6 | ||||
-rw-r--r-- | crates/hir_def/src/visibility.rs | 2 | ||||
-rw-r--r-- | crates/hir_ty/src/tests.rs | 6 |
17 files changed, 292 insertions, 32 deletions
diff --git a/crates/assists/src/handlers/add_lifetime_to_type.rs b/crates/assists/src/handlers/add_lifetime_to_type.rs new file mode 100644 index 000000000..c1603e972 --- /dev/null +++ b/crates/assists/src/handlers/add_lifetime_to_type.rs | |||
@@ -0,0 +1,228 @@ | |||
1 | use ast::FieldList; | ||
2 | use syntax::ast::{self, AstNode, GenericParamsOwner, NameOwner, RefType, Type}; | ||
3 | |||
4 | use crate::{AssistContext, AssistId, AssistKind, Assists}; | ||
5 | |||
6 | // Assist: add_lifetime_to_type | ||
7 | // | ||
8 | // Adds a new lifetime to a struct, enum or union. | ||
9 | // | ||
10 | // ``` | ||
11 | // struct Point { | ||
12 | // x: &$0u32, | ||
13 | // y: u32, | ||
14 | // } | ||
15 | // ``` | ||
16 | // -> | ||
17 | // ``` | ||
18 | // struct Point<'a> { | ||
19 | // x: &'a u32, | ||
20 | // y: u32, | ||
21 | // } | ||
22 | // ``` | ||
23 | pub(crate) fn add_lifetime_to_type(acc: &mut Assists, ctx: &AssistContext) -> Option<()> { | ||
24 | let ref_type_focused = ctx.find_node_at_offset::<ast::RefType>()?; | ||
25 | if ref_type_focused.lifetime().is_some() { | ||
26 | return None; | ||
27 | } | ||
28 | |||
29 | let node = ctx.find_node_at_offset::<ast::AdtDef>()?; | ||
30 | let has_lifetime = node | ||
31 | .generic_param_list() | ||
32 | .map(|gen_list| gen_list.lifetime_params().count() > 0) | ||
33 | .unwrap_or_default(); | ||
34 | |||
35 | if has_lifetime { | ||
36 | return None; | ||
37 | } | ||
38 | |||
39 | let ref_types = fetch_borrowed_types(&node)?; | ||
40 | let target = node.syntax().text_range(); | ||
41 | |||
42 | acc.add( | ||
43 | AssistId("add_lifetime_to_type", AssistKind::Generate), | ||
44 | "Add lifetime`", | ||
45 | target, | ||
46 | |builder| { | ||
47 | match node.generic_param_list() { | ||
48 | Some(gen_param) => { | ||
49 | if let Some(left_angle) = gen_param.l_angle_token() { | ||
50 | builder.insert(left_angle.text_range().end(), "'a, "); | ||
51 | } | ||
52 | } | ||
53 | None => { | ||
54 | if let Some(name) = node.name() { | ||
55 | builder.insert(name.syntax().text_range().end(), "<'a>"); | ||
56 | } | ||
57 | } | ||
58 | } | ||
59 | |||
60 | for ref_type in ref_types { | ||
61 | if let Some(amp_token) = ref_type.amp_token() { | ||
62 | builder.insert(amp_token.text_range().end(), "'a "); | ||
63 | } | ||
64 | } | ||
65 | }, | ||
66 | ) | ||
67 | } | ||
68 | |||
69 | fn fetch_borrowed_types(node: &ast::AdtDef) -> Option<Vec<RefType>> { | ||
70 | let ref_types: Vec<RefType> = match node { | ||
71 | ast::AdtDef::Enum(enum_) => { | ||
72 | let variant_list = enum_.variant_list()?; | ||
73 | variant_list | ||
74 | .variants() | ||
75 | .filter_map(|variant| { | ||
76 | let field_list = variant.field_list()?; | ||
77 | |||
78 | find_ref_types_from_field_list(&field_list) | ||
79 | }) | ||
80 | .flatten() | ||
81 | .collect() | ||
82 | } | ||
83 | ast::AdtDef::Struct(strukt) => { | ||
84 | let field_list = strukt.field_list()?; | ||
85 | find_ref_types_from_field_list(&field_list)? | ||
86 | } | ||
87 | ast::AdtDef::Union(un) => { | ||
88 | let record_field_list = un.record_field_list()?; | ||
89 | record_field_list | ||
90 | .fields() | ||
91 | .filter_map(|r_field| { | ||
92 | if let Type::RefType(ref_type) = r_field.ty()? { | ||
93 | if ref_type.lifetime().is_none() { | ||
94 | return Some(ref_type); | ||
95 | } | ||
96 | } | ||
97 | |||
98 | None | ||
99 | }) | ||
100 | .collect() | ||
101 | } | ||
102 | }; | ||
103 | |||
104 | if ref_types.is_empty() { | ||
105 | None | ||
106 | } else { | ||
107 | Some(ref_types) | ||
108 | } | ||
109 | } | ||
110 | |||
111 | fn find_ref_types_from_field_list(field_list: &FieldList) -> Option<Vec<RefType>> { | ||
112 | let ref_types: Vec<RefType> = match field_list { | ||
113 | ast::FieldList::RecordFieldList(record_list) => record_list | ||
114 | .fields() | ||
115 | .filter_map(|f| { | ||
116 | if let Type::RefType(ref_type) = f.ty()? { | ||
117 | if ref_type.lifetime().is_none() { | ||
118 | return Some(ref_type); | ||
119 | } | ||
120 | } | ||
121 | |||
122 | None | ||
123 | }) | ||
124 | .collect(), | ||
125 | ast::FieldList::TupleFieldList(tuple_field_list) => tuple_field_list | ||
126 | .fields() | ||
127 | .filter_map(|f| { | ||
128 | if let Type::RefType(ref_type) = f.ty()? { | ||
129 | if ref_type.lifetime().is_none() { | ||
130 | return Some(ref_type); | ||
131 | } | ||
132 | } | ||
133 | |||
134 | None | ||
135 | }) | ||
136 | .collect(), | ||
137 | }; | ||
138 | |||
139 | if ref_types.is_empty() { | ||
140 | None | ||
141 | } else { | ||
142 | Some(ref_types) | ||
143 | } | ||
144 | } | ||
145 | |||
146 | #[cfg(test)] | ||
147 | mod tests { | ||
148 | use crate::tests::{check_assist, check_assist_not_applicable}; | ||
149 | |||
150 | use super::*; | ||
151 | |||
152 | #[test] | ||
153 | fn add_lifetime_to_struct() { | ||
154 | check_assist( | ||
155 | add_lifetime_to_type, | ||
156 | "struct Foo { a: &$0i32 }", | ||
157 | "struct Foo<'a> { a: &'a i32 }", | ||
158 | ); | ||
159 | |||
160 | check_assist( | ||
161 | add_lifetime_to_type, | ||
162 | "struct Foo { a: &$0i32, b: &usize }", | ||
163 | "struct Foo<'a> { a: &'a i32, b: &'a usize }", | ||
164 | ); | ||
165 | |||
166 | check_assist( | ||
167 | add_lifetime_to_type, | ||
168 | "struct Foo { a: &$0i32, b: usize }", | ||
169 | "struct Foo<'a> { a: &'a i32, b: usize }", | ||
170 | ); | ||
171 | |||
172 | check_assist( | ||
173 | add_lifetime_to_type, | ||
174 | "struct Foo<T> { a: &$0T, b: usize }", | ||
175 | "struct Foo<'a, T> { a: &'a T, b: usize }", | ||
176 | ); | ||
177 | |||
178 | check_assist_not_applicable(add_lifetime_to_type, "struct Foo<'a> { a: &$0'a i32 }"); | ||
179 | check_assist_not_applicable(add_lifetime_to_type, "struct Foo { a: &'a$0 i32 }"); | ||
180 | } | ||
181 | |||
182 | #[test] | ||
183 | fn add_lifetime_to_enum() { | ||
184 | check_assist( | ||
185 | add_lifetime_to_type, | ||
186 | "enum Foo { Bar { a: i32 }, Other, Tuple(u32, &$0u32)}", | ||
187 | "enum Foo<'a> { Bar { a: i32 }, Other, Tuple(u32, &'a u32)}", | ||
188 | ); | ||
189 | |||
190 | check_assist( | ||
191 | add_lifetime_to_type, | ||
192 | "enum Foo { Bar { a: &$0i32 }}", | ||
193 | "enum Foo<'a> { Bar { a: &'a i32 }}", | ||
194 | ); | ||
195 | |||
196 | check_assist( | ||
197 | add_lifetime_to_type, | ||
198 | "enum Foo<T> { Bar { a: &$0i32, b: &T }}", | ||
199 | "enum Foo<'a, T> { Bar { a: &'a i32, b: &'a T }}", | ||
200 | ); | ||
201 | |||
202 | check_assist_not_applicable(add_lifetime_to_type, "enum Foo<'a> { Bar { a: &$0'a i32 }}"); | ||
203 | check_assist_not_applicable(add_lifetime_to_type, "enum Foo { Bar, $0Misc }"); | ||
204 | } | ||
205 | |||
206 | #[test] | ||
207 | fn add_lifetime_to_union() { | ||
208 | check_assist( | ||
209 | add_lifetime_to_type, | ||
210 | "union Foo { a: &$0i32 }", | ||
211 | "union Foo<'a> { a: &'a i32 }", | ||
212 | ); | ||
213 | |||
214 | check_assist( | ||
215 | add_lifetime_to_type, | ||
216 | "union Foo { a: &$0i32, b: &usize }", | ||
217 | "union Foo<'a> { a: &'a i32, b: &'a usize }", | ||
218 | ); | ||
219 | |||
220 | check_assist( | ||
221 | add_lifetime_to_type, | ||
222 | "union Foo<T> { a: &$0T, b: usize }", | ||
223 | "union Foo<'a, T> { a: &'a T, b: usize }", | ||
224 | ); | ||
225 | |||
226 | check_assist_not_applicable(add_lifetime_to_type, "struct Foo<'a> { a: &'a $0i32 }"); | ||
227 | } | ||
228 | } | ||
diff --git a/crates/assists/src/lib.rs b/crates/assists/src/lib.rs index 14178a651..559b9651e 100644 --- a/crates/assists/src/lib.rs +++ b/crates/assists/src/lib.rs | |||
@@ -108,6 +108,7 @@ mod handlers { | |||
108 | pub(crate) type Handler = fn(&mut Assists, &AssistContext) -> Option<()>; | 108 | pub(crate) type Handler = fn(&mut Assists, &AssistContext) -> Option<()>; |
109 | 109 | ||
110 | mod add_explicit_type; | 110 | mod add_explicit_type; |
111 | mod add_lifetime_to_type; | ||
111 | mod add_missing_impl_members; | 112 | mod add_missing_impl_members; |
112 | mod add_turbo_fish; | 113 | mod add_turbo_fish; |
113 | mod apply_demorgan; | 114 | mod apply_demorgan; |
@@ -164,6 +165,7 @@ mod handlers { | |||
164 | &[ | 165 | &[ |
165 | // These are alphabetic for the foolish consistency | 166 | // These are alphabetic for the foolish consistency |
166 | add_explicit_type::add_explicit_type, | 167 | add_explicit_type::add_explicit_type, |
168 | add_lifetime_to_type::add_lifetime_to_type, | ||
167 | add_turbo_fish::add_turbo_fish, | 169 | add_turbo_fish::add_turbo_fish, |
168 | apply_demorgan::apply_demorgan, | 170 | apply_demorgan::apply_demorgan, |
169 | auto_import::auto_import, | 171 | auto_import::auto_import, |
diff --git a/crates/assists/src/tests/generated.rs b/crates/assists/src/tests/generated.rs index d48d063b4..9aa807f10 100644 --- a/crates/assists/src/tests/generated.rs +++ b/crates/assists/src/tests/generated.rs | |||
@@ -104,6 +104,25 @@ impl Trait<u32> for () { | |||
104 | } | 104 | } |
105 | 105 | ||
106 | #[test] | 106 | #[test] |
107 | fn doctest_add_lifetime_to_type() { | ||
108 | check_doc_test( | ||
109 | "add_lifetime_to_type", | ||
110 | r#####" | ||
111 | struct Point { | ||
112 | x: &$0u32, | ||
113 | y: u32, | ||
114 | } | ||
115 | "#####, | ||
116 | r#####" | ||
117 | struct Point<'a> { | ||
118 | x: &'a u32, | ||
119 | y: u32, | ||
120 | } | ||
121 | "#####, | ||
122 | ) | ||
123 | } | ||
124 | |||
125 | #[test] | ||
107 | fn doctest_add_turbo_fish() { | 126 | fn doctest_add_turbo_fish() { |
108 | check_doc_test( | 127 | check_doc_test( |
109 | "add_turbo_fish", | 128 | "add_turbo_fish", |
diff --git a/crates/hir/src/code_model.rs b/crates/hir/src/code_model.rs index aaa7013b6..c34a99d90 100644 --- a/crates/hir/src/code_model.rs +++ b/crates/hir/src/code_model.rs | |||
@@ -281,7 +281,7 @@ impl Module { | |||
281 | 281 | ||
282 | /// Name of this module. | 282 | /// Name of this module. |
283 | pub fn name(self, db: &dyn HirDatabase) -> Option<Name> { | 283 | pub fn name(self, db: &dyn HirDatabase) -> Option<Name> { |
284 | let def_map = db.crate_def_map(self.id.krate); | 284 | let def_map = self.id.def_map(db.upcast()); |
285 | let parent = def_map[self.id.local_id].parent?; | 285 | let parent = def_map[self.id.local_id].parent?; |
286 | def_map[parent].children.iter().find_map(|(name, module_id)| { | 286 | def_map[parent].children.iter().find_map(|(name, module_id)| { |
287 | if *module_id == self.id.local_id { | 287 | if *module_id == self.id.local_id { |
@@ -307,7 +307,7 @@ impl Module { | |||
307 | 307 | ||
308 | /// Iterates over all child modules. | 308 | /// Iterates over all child modules. |
309 | pub fn children(self, db: &dyn HirDatabase) -> impl Iterator<Item = Module> { | 309 | pub fn children(self, db: &dyn HirDatabase) -> impl Iterator<Item = Module> { |
310 | let def_map = db.crate_def_map(self.id.krate); | 310 | let def_map = self.id.def_map(db.upcast()); |
311 | let children = def_map[self.id.local_id] | 311 | let children = def_map[self.id.local_id] |
312 | .children | 312 | .children |
313 | .iter() | 313 | .iter() |
@@ -318,7 +318,7 @@ impl Module { | |||
318 | 318 | ||
319 | /// Finds a parent module. | 319 | /// Finds a parent module. |
320 | pub fn parent(self, db: &dyn HirDatabase) -> Option<Module> { | 320 | pub fn parent(self, db: &dyn HirDatabase) -> Option<Module> { |
321 | let def_map = db.crate_def_map(self.id.krate); | 321 | let def_map = self.id.def_map(db.upcast()); |
322 | let parent_id = def_map[self.id.local_id].parent?; | 322 | let parent_id = def_map[self.id.local_id].parent?; |
323 | Some(self.with_module_id(parent_id)) | 323 | Some(self.with_module_id(parent_id)) |
324 | } | 324 | } |
@@ -339,7 +339,7 @@ impl Module { | |||
339 | db: &dyn HirDatabase, | 339 | db: &dyn HirDatabase, |
340 | visible_from: Option<Module>, | 340 | visible_from: Option<Module>, |
341 | ) -> Vec<(Name, ScopeDef)> { | 341 | ) -> Vec<(Name, ScopeDef)> { |
342 | db.crate_def_map(self.id.krate)[self.id.local_id] | 342 | self.id.def_map(db.upcast())[self.id.local_id] |
343 | .scope | 343 | .scope |
344 | .entries() | 344 | .entries() |
345 | .filter_map(|(name, def)| { | 345 | .filter_map(|(name, def)| { |
@@ -362,14 +362,14 @@ impl Module { | |||
362 | } | 362 | } |
363 | 363 | ||
364 | pub fn visibility_of(self, db: &dyn HirDatabase, def: &ModuleDef) -> Option<Visibility> { | 364 | pub fn visibility_of(self, db: &dyn HirDatabase, def: &ModuleDef) -> Option<Visibility> { |
365 | db.crate_def_map(self.id.krate)[self.id.local_id].scope.visibility_of(def.clone().into()) | 365 | self.id.def_map(db.upcast())[self.id.local_id].scope.visibility_of(def.clone().into()) |
366 | } | 366 | } |
367 | 367 | ||
368 | pub fn diagnostics(self, db: &dyn HirDatabase, sink: &mut DiagnosticSink) { | 368 | pub fn diagnostics(self, db: &dyn HirDatabase, sink: &mut DiagnosticSink) { |
369 | let _p = profile::span("Module::diagnostics").detail(|| { | 369 | let _p = profile::span("Module::diagnostics").detail(|| { |
370 | format!("{:?}", self.name(db).map_or("<unknown>".into(), |name| name.to_string())) | 370 | format!("{:?}", self.name(db).map_or("<unknown>".into(), |name| name.to_string())) |
371 | }); | 371 | }); |
372 | let crate_def_map = db.crate_def_map(self.id.krate); | 372 | let crate_def_map = self.id.def_map(db.upcast()); |
373 | crate_def_map.add_diagnostics(db.upcast(), self.id.local_id, sink); | 373 | crate_def_map.add_diagnostics(db.upcast(), self.id.local_id, sink); |
374 | for decl in self.declarations(db) { | 374 | for decl in self.declarations(db) { |
375 | match decl { | 375 | match decl { |
@@ -396,12 +396,12 @@ impl Module { | |||
396 | } | 396 | } |
397 | 397 | ||
398 | pub fn declarations(self, db: &dyn HirDatabase) -> Vec<ModuleDef> { | 398 | pub fn declarations(self, db: &dyn HirDatabase) -> Vec<ModuleDef> { |
399 | let def_map = db.crate_def_map(self.id.krate); | 399 | let def_map = self.id.def_map(db.upcast()); |
400 | def_map[self.id.local_id].scope.declarations().map(ModuleDef::from).collect() | 400 | def_map[self.id.local_id].scope.declarations().map(ModuleDef::from).collect() |
401 | } | 401 | } |
402 | 402 | ||
403 | pub fn impl_defs(self, db: &dyn HirDatabase) -> Vec<Impl> { | 403 | pub fn impl_defs(self, db: &dyn HirDatabase) -> Vec<Impl> { |
404 | let def_map = db.crate_def_map(self.id.krate); | 404 | let def_map = self.id.def_map(db.upcast()); |
405 | def_map[self.id.local_id].scope.impls().map(Impl::from).collect() | 405 | def_map[self.id.local_id].scope.impls().map(Impl::from).collect() |
406 | } | 406 | } |
407 | 407 | ||
diff --git a/crates/hir/src/has_source.rs b/crates/hir/src/has_source.rs index 7c57d8378..262002671 100644 --- a/crates/hir/src/has_source.rs +++ b/crates/hir/src/has_source.rs | |||
@@ -24,12 +24,12 @@ pub trait HasSource { | |||
24 | impl Module { | 24 | impl Module { |
25 | /// Returns a node which defines this module. That is, a file or a `mod foo {}` with items. | 25 | /// Returns a node which defines this module. That is, a file or a `mod foo {}` with items. |
26 | pub fn definition_source(self, db: &dyn HirDatabase) -> InFile<ModuleSource> { | 26 | pub fn definition_source(self, db: &dyn HirDatabase) -> InFile<ModuleSource> { |
27 | let def_map = db.crate_def_map(self.id.krate); | 27 | let def_map = self.id.def_map(db.upcast()); |
28 | def_map[self.id.local_id].definition_source(db.upcast()) | 28 | def_map[self.id.local_id].definition_source(db.upcast()) |
29 | } | 29 | } |
30 | 30 | ||
31 | pub fn is_mod_rs(self, db: &dyn HirDatabase) -> bool { | 31 | pub fn is_mod_rs(self, db: &dyn HirDatabase) -> bool { |
32 | let def_map = db.crate_def_map(self.id.krate); | 32 | let def_map = self.id.def_map(db.upcast()); |
33 | match def_map[self.id.local_id].origin { | 33 | match def_map[self.id.local_id].origin { |
34 | ModuleOrigin::File { is_mod_rs, .. } => is_mod_rs, | 34 | ModuleOrigin::File { is_mod_rs, .. } => is_mod_rs, |
35 | _ => false, | 35 | _ => false, |
@@ -39,7 +39,7 @@ impl Module { | |||
39 | /// Returns a node which declares this module, either a `mod foo;` or a `mod foo {}`. | 39 | /// Returns a node which declares this module, either a `mod foo;` or a `mod foo {}`. |
40 | /// `None` for the crate root. | 40 | /// `None` for the crate root. |
41 | pub fn declaration_source(self, db: &dyn HirDatabase) -> Option<InFile<ast::Module>> { | 41 | pub fn declaration_source(self, db: &dyn HirDatabase) -> Option<InFile<ast::Module>> { |
42 | let def_map = db.crate_def_map(self.id.krate); | 42 | let def_map = self.id.def_map(db.upcast()); |
43 | def_map[self.id.local_id].declaration_source(db.upcast()) | 43 | def_map[self.id.local_id].declaration_source(db.upcast()) |
44 | } | 44 | } |
45 | } | 45 | } |
diff --git a/crates/hir/src/semantics/source_to_def.rs b/crates/hir/src/semantics/source_to_def.rs index 9bf60c72a..775f7ec8b 100644 --- a/crates/hir/src/semantics/source_to_def.rs +++ b/crates/hir/src/semantics/source_to_def.rs | |||
@@ -31,6 +31,7 @@ impl SourceToDefCtx<'_, '_> { | |||
31 | pub(super) fn file_to_def(&mut self, file: FileId) -> Option<ModuleId> { | 31 | pub(super) fn file_to_def(&mut self, file: FileId) -> Option<ModuleId> { |
32 | let _p = profile::span("SourceBinder::to_module_def"); | 32 | let _p = profile::span("SourceBinder::to_module_def"); |
33 | let (krate, local_id) = self.db.relevant_crates(file).iter().find_map(|&crate_id| { | 33 | let (krate, local_id) = self.db.relevant_crates(file).iter().find_map(|&crate_id| { |
34 | // FIXME: inner items | ||
34 | let crate_def_map = self.db.crate_def_map(crate_id); | 35 | let crate_def_map = self.db.crate_def_map(crate_id); |
35 | let local_id = crate_def_map.modules_for_file(file).next()?; | 36 | let local_id = crate_def_map.modules_for_file(file).next()?; |
36 | Some((crate_id, local_id)) | 37 | Some((crate_id, local_id)) |
@@ -60,7 +61,7 @@ impl SourceToDefCtx<'_, '_> { | |||
60 | }?; | 61 | }?; |
61 | 62 | ||
62 | let child_name = src.value.name()?.as_name(); | 63 | let child_name = src.value.name()?.as_name(); |
63 | let def_map = self.db.crate_def_map(parent_module.krate); | 64 | let def_map = parent_module.def_map(self.db.upcast()); |
64 | let child_id = *def_map[parent_module.local_id].children.get(&child_name)?; | 65 | let child_id = *def_map[parent_module.local_id].children.get(&child_name)?; |
65 | Some(ModuleId { krate: parent_module.krate, local_id: child_id }) | 66 | Some(ModuleId { krate: parent_module.krate, local_id: child_id }) |
66 | } | 67 | } |
diff --git a/crates/hir_def/src/attr.rs b/crates/hir_def/src/attr.rs index c72649c41..6513daec8 100644 --- a/crates/hir_def/src/attr.rs +++ b/crates/hir_def/src/attr.rs | |||
@@ -196,7 +196,7 @@ impl Attrs { | |||
196 | pub(crate) fn attrs_query(db: &dyn DefDatabase, def: AttrDefId) -> Attrs { | 196 | pub(crate) fn attrs_query(db: &dyn DefDatabase, def: AttrDefId) -> Attrs { |
197 | let raw_attrs = match def { | 197 | let raw_attrs = match def { |
198 | AttrDefId::ModuleId(module) => { | 198 | AttrDefId::ModuleId(module) => { |
199 | let def_map = db.crate_def_map(module.krate); | 199 | let def_map = module.def_map(db); |
200 | let mod_data = &def_map[module.local_id]; | 200 | let mod_data = &def_map[module.local_id]; |
201 | match mod_data.declaration_source(db) { | 201 | match mod_data.declaration_source(db) { |
202 | Some(it) => { | 202 | Some(it) => { |
diff --git a/crates/hir_def/src/body.rs b/crates/hir_def/src/body.rs index 2c2c999dd..d0c84ab0b 100644 --- a/crates/hir_def/src/body.rs +++ b/crates/hir_def/src/body.rs | |||
@@ -86,7 +86,7 @@ impl Expander { | |||
86 | module: ModuleId, | 86 | module: ModuleId, |
87 | ) -> Expander { | 87 | ) -> Expander { |
88 | let cfg_expander = CfgExpander::new(db, current_file_id, module.krate); | 88 | let cfg_expander = CfgExpander::new(db, current_file_id, module.krate); |
89 | let crate_def_map = db.crate_def_map(module.krate); | 89 | let crate_def_map = module.def_map(db); |
90 | let ast_id_map = db.ast_id_map(current_file_id); | 90 | let ast_id_map = db.ast_id_map(current_file_id); |
91 | Expander { | 91 | Expander { |
92 | cfg_expander, | 92 | cfg_expander, |
diff --git a/crates/hir_def/src/child_by_source.rs b/crates/hir_def/src/child_by_source.rs index dcb00a1d9..65d85c86a 100644 --- a/crates/hir_def/src/child_by_source.rs +++ b/crates/hir_def/src/child_by_source.rs | |||
@@ -74,7 +74,7 @@ impl ChildBySource for ImplId { | |||
74 | 74 | ||
75 | impl ChildBySource for ModuleId { | 75 | impl ChildBySource for ModuleId { |
76 | fn child_by_source(&self, db: &dyn DefDatabase) -> DynMap { | 76 | fn child_by_source(&self, db: &dyn DefDatabase) -> DynMap { |
77 | let crate_def_map = db.crate_def_map(self.krate); | 77 | let crate_def_map = self.def_map(db); |
78 | let module_data = &crate_def_map[self.local_id]; | 78 | let module_data = &crate_def_map[self.local_id]; |
79 | module_data.scope.child_by_source(db) | 79 | module_data.scope.child_by_source(db) |
80 | } | 80 | } |
diff --git a/crates/hir_def/src/find_path.rs b/crates/hir_def/src/find_path.rs index db2d125ae..c01b6daf2 100644 --- a/crates/hir_def/src/find_path.rs +++ b/crates/hir_def/src/find_path.rs | |||
@@ -110,7 +110,7 @@ fn find_path_inner( | |||
110 | // Base cases: | 110 | // Base cases: |
111 | 111 | ||
112 | // - if the item is already in scope, return the name under which it is | 112 | // - if the item is already in scope, return the name under which it is |
113 | let def_map = db.crate_def_map(from.krate); | 113 | let def_map = from.def_map(db); |
114 | let from_scope: &crate::item_scope::ItemScope = &def_map[from.local_id].scope; | 114 | let from_scope: &crate::item_scope::ItemScope = &def_map[from.local_id].scope; |
115 | let scope_name = | 115 | let scope_name = |
116 | if let Some((name, _)) = from_scope.name_of(item) { Some(name.clone()) } else { None }; | 116 | if let Some((name, _)) = from_scope.name_of(item) { Some(name.clone()) } else { None }; |
@@ -145,7 +145,7 @@ fn find_path_inner( | |||
145 | 145 | ||
146 | // - if the item is in the prelude, return the name from there | 146 | // - if the item is in the prelude, return the name from there |
147 | if let Some(prelude_module) = def_map.prelude() { | 147 | if let Some(prelude_module) = def_map.prelude() { |
148 | let prelude_def_map = db.crate_def_map(prelude_module.krate); | 148 | let prelude_def_map = prelude_module.def_map(db); |
149 | let prelude_scope: &crate::item_scope::ItemScope = | 149 | let prelude_scope: &crate::item_scope::ItemScope = |
150 | &prelude_def_map[prelude_module.local_id].scope; | 150 | &prelude_def_map[prelude_module.local_id].scope; |
151 | if let Some((name, vis)) = prelude_scope.name_of(item) { | 151 | if let Some((name, vis)) = prelude_scope.name_of(item) { |
@@ -283,7 +283,7 @@ fn find_local_import_locations( | |||
283 | // above `from` with any visibility. That means we do not need to descend into private siblings | 283 | // above `from` with any visibility. That means we do not need to descend into private siblings |
284 | // of `from` (and similar). | 284 | // of `from` (and similar). |
285 | 285 | ||
286 | let def_map = db.crate_def_map(from.krate); | 286 | let def_map = from.def_map(db); |
287 | 287 | ||
288 | // Compute the initial worklist. We start with all direct child modules of `from` as well as all | 288 | // Compute the initial worklist. We start with all direct child modules of `from` as well as all |
289 | // of its (recursive) parent modules. | 289 | // of its (recursive) parent modules. |
@@ -312,7 +312,7 @@ fn find_local_import_locations( | |||
312 | &def_map[module.local_id] | 312 | &def_map[module.local_id] |
313 | } else { | 313 | } else { |
314 | // The crate might reexport a module defined in another crate. | 314 | // The crate might reexport a module defined in another crate. |
315 | ext_def_map = db.crate_def_map(module.krate); | 315 | ext_def_map = module.def_map(db); |
316 | &ext_def_map[module.local_id] | 316 | &ext_def_map[module.local_id] |
317 | }; | 317 | }; |
318 | 318 | ||
@@ -375,7 +375,7 @@ mod tests { | |||
375 | parsed_path_file.syntax_node().descendants().find_map(syntax::ast::Path::cast).unwrap(); | 375 | parsed_path_file.syntax_node().descendants().find_map(syntax::ast::Path::cast).unwrap(); |
376 | let mod_path = ModPath::from_src(ast_path, &Hygiene::new_unhygienic()).unwrap(); | 376 | let mod_path = ModPath::from_src(ast_path, &Hygiene::new_unhygienic()).unwrap(); |
377 | 377 | ||
378 | let crate_def_map = db.crate_def_map(module.krate); | 378 | let crate_def_map = module.def_map(&db); |
379 | let resolved = crate_def_map | 379 | let resolved = crate_def_map |
380 | .resolve_path( | 380 | .resolve_path( |
381 | &db, | 381 | &db, |
diff --git a/crates/hir_def/src/import_map.rs b/crates/hir_def/src/import_map.rs index 0251d016b..0b7830445 100644 --- a/crates/hir_def/src/import_map.rs +++ b/crates/hir_def/src/import_map.rs | |||
@@ -83,7 +83,7 @@ impl ImportMap { | |||
83 | &def_map[module.local_id] | 83 | &def_map[module.local_id] |
84 | } else { | 84 | } else { |
85 | // The crate might reexport a module defined in another crate. | 85 | // The crate might reexport a module defined in another crate. |
86 | ext_def_map = db.crate_def_map(module.krate); | 86 | ext_def_map = module.def_map(db); |
87 | &ext_def_map[module.local_id] | 87 | &ext_def_map[module.local_id] |
88 | }; | 88 | }; |
89 | 89 | ||
diff --git a/crates/hir_def/src/lib.rs b/crates/hir_def/src/lib.rs index 08ed920c6..2f9261a7f 100644 --- a/crates/hir_def/src/lib.rs +++ b/crates/hir_def/src/lib.rs | |||
@@ -50,7 +50,10 @@ pub mod import_map; | |||
50 | #[cfg(test)] | 50 | #[cfg(test)] |
51 | mod test_db; | 51 | mod test_db; |
52 | 52 | ||
53 | use std::hash::{Hash, Hasher}; | 53 | use std::{ |
54 | hash::{Hash, Hasher}, | ||
55 | sync::Arc, | ||
56 | }; | ||
54 | 57 | ||
55 | use base_db::{impl_intern_key, salsa, CrateId}; | 58 | use base_db::{impl_intern_key, salsa, CrateId}; |
56 | use hir_expand::{ | 59 | use hir_expand::{ |
@@ -58,6 +61,7 @@ use hir_expand::{ | |||
58 | MacroCallId, MacroCallKind, MacroDefId, MacroDefKind, | 61 | MacroCallId, MacroCallKind, MacroDefId, MacroDefKind, |
59 | }; | 62 | }; |
60 | use la_arena::Idx; | 63 | use la_arena::Idx; |
64 | use nameres::DefMap; | ||
61 | use syntax::ast; | 65 | use syntax::ast; |
62 | 66 | ||
63 | use crate::builtin_type::BuiltinType; | 67 | use crate::builtin_type::BuiltinType; |
@@ -73,6 +77,12 @@ pub struct ModuleId { | |||
73 | pub local_id: LocalModuleId, | 77 | pub local_id: LocalModuleId, |
74 | } | 78 | } |
75 | 79 | ||
80 | impl ModuleId { | ||
81 | pub fn def_map(&self, db: &dyn db::DefDatabase) -> Arc<DefMap> { | ||
82 | db.crate_def_map(self.krate) | ||
83 | } | ||
84 | } | ||
85 | |||
76 | /// An ID of a module, **local** to a specific crate | 86 | /// An ID of a module, **local** to a specific crate |
77 | pub type LocalModuleId = Idx<nameres::ModuleData>; | 87 | pub type LocalModuleId = Idx<nameres::ModuleData>; |
78 | 88 | ||
diff --git a/crates/hir_def/src/nameres/collector.rs b/crates/hir_def/src/nameres/collector.rs index cd68efbe6..adfcf879a 100644 --- a/crates/hir_def/src/nameres/collector.rs +++ b/crates/hir_def/src/nameres/collector.rs | |||
@@ -578,7 +578,7 @@ impl DefCollector<'_> { | |||
578 | } else if m.krate != self.def_map.krate { | 578 | } else if m.krate != self.def_map.krate { |
579 | mark::hit!(glob_across_crates); | 579 | mark::hit!(glob_across_crates); |
580 | // glob import from other crate => we can just import everything once | 580 | // glob import from other crate => we can just import everything once |
581 | let item_map = self.db.crate_def_map(m.krate); | 581 | let item_map = m.def_map(self.db); |
582 | let scope = &item_map[m.local_id].scope; | 582 | let scope = &item_map[m.local_id].scope; |
583 | 583 | ||
584 | // Module scoped macros is included | 584 | // Module scoped macros is included |
diff --git a/crates/hir_def/src/nameres/path_resolution.rs b/crates/hir_def/src/nameres/path_resolution.rs index ec90f4e65..82528b792 100644 --- a/crates/hir_def/src/nameres/path_resolution.rs +++ b/crates/hir_def/src/nameres/path_resolution.rs | |||
@@ -243,7 +243,7 @@ impl DefMap { | |||
243 | kind: PathKind::Super(0), | 243 | kind: PathKind::Super(0), |
244 | }; | 244 | }; |
245 | log::debug!("resolving {:?} in other crate", path); | 245 | log::debug!("resolving {:?} in other crate", path); |
246 | let defp_map = db.crate_def_map(module.krate); | 246 | let defp_map = module.def_map(db); |
247 | let (def, s) = defp_map.resolve_path(db, module.local_id, &path, shadow); | 247 | let (def, s) = defp_map.resolve_path(db, module.local_id, &path, shadow); |
248 | return ResolvePathResult::with( | 248 | return ResolvePathResult::with( |
249 | def, | 249 | def, |
@@ -356,7 +356,7 @@ impl DefMap { | |||
356 | self | 356 | self |
357 | } else { | 357 | } else { |
358 | // Extend lifetime | 358 | // Extend lifetime |
359 | keep = db.crate_def_map(prelude.krate); | 359 | keep = prelude.def_map(db); |
360 | &keep | 360 | &keep |
361 | }; | 361 | }; |
362 | def_map[prelude.local_id].scope.get(name) | 362 | def_map[prelude.local_id].scope.get(name) |
diff --git a/crates/hir_def/src/resolver.rs b/crates/hir_def/src/resolver.rs index b2f577649..130c074f0 100644 --- a/crates/hir_def/src/resolver.rs +++ b/crates/hir_def/src/resolver.rs | |||
@@ -430,7 +430,7 @@ impl Resolver { | |||
430 | for scope in &self.scopes { | 430 | for scope in &self.scopes { |
431 | if let Scope::ModuleScope(m) = scope { | 431 | if let Scope::ModuleScope(m) = scope { |
432 | if let Some(prelude) = m.crate_def_map.prelude() { | 432 | if let Some(prelude) = m.crate_def_map.prelude() { |
433 | let prelude_def_map = db.crate_def_map(prelude.krate); | 433 | let prelude_def_map = prelude.def_map(db); |
434 | traits.extend(prelude_def_map[prelude.local_id].scope.traits()); | 434 | traits.extend(prelude_def_map[prelude.local_id].scope.traits()); |
435 | } | 435 | } |
436 | traits.extend(m.crate_def_map[m.module_id].scope.traits()); | 436 | traits.extend(m.crate_def_map[m.module_id].scope.traits()); |
@@ -529,7 +529,7 @@ impl Scope { | |||
529 | f(name.clone(), ScopeDef::PerNs(def)); | 529 | f(name.clone(), ScopeDef::PerNs(def)); |
530 | }); | 530 | }); |
531 | if let Some(prelude) = m.crate_def_map.prelude() { | 531 | if let Some(prelude) = m.crate_def_map.prelude() { |
532 | let prelude_def_map = db.crate_def_map(prelude.krate); | 532 | let prelude_def_map = prelude.def_map(db); |
533 | prelude_def_map[prelude.local_id].scope.entries().for_each(|(name, def)| { | 533 | prelude_def_map[prelude.local_id].scope.entries().for_each(|(name, def)| { |
534 | let seen_tuple = (name.clone(), def); | 534 | let seen_tuple = (name.clone(), def); |
535 | if !seen.contains(&seen_tuple) { | 535 | if !seen.contains(&seen_tuple) { |
@@ -633,7 +633,7 @@ pub trait HasResolver: Copy { | |||
633 | 633 | ||
634 | impl HasResolver for ModuleId { | 634 | impl HasResolver for ModuleId { |
635 | fn resolver(self, db: &dyn DefDatabase) -> Resolver { | 635 | fn resolver(self, db: &dyn DefDatabase) -> Resolver { |
636 | let def_map = db.crate_def_map(self.krate); | 636 | let def_map = self.def_map(db); |
637 | Resolver::default().push_module_scope(def_map, self.local_id) | 637 | Resolver::default().push_module_scope(def_map, self.local_id) |
638 | } | 638 | } |
639 | } | 639 | } |
diff --git a/crates/hir_def/src/visibility.rs b/crates/hir_def/src/visibility.rs index 3134fa43d..e79a91102 100644 --- a/crates/hir_def/src/visibility.rs +++ b/crates/hir_def/src/visibility.rs | |||
@@ -103,7 +103,7 @@ impl Visibility { | |||
103 | if from_module.krate != to_module.krate { | 103 | if from_module.krate != to_module.krate { |
104 | return false; | 104 | return false; |
105 | } | 105 | } |
106 | let def_map = db.crate_def_map(from_module.krate); | 106 | let def_map = from_module.def_map(db); |
107 | self.is_visible_from_def_map(&def_map, from_module.local_id) | 107 | self.is_visible_from_def_map(&def_map, from_module.local_id) |
108 | } | 108 | } |
109 | 109 | ||
diff --git a/crates/hir_ty/src/tests.rs b/crates/hir_ty/src/tests.rs index 4a3fcea8d..25ee664d6 100644 --- a/crates/hir_ty/src/tests.rs +++ b/crates/hir_ty/src/tests.rs | |||
@@ -188,10 +188,10 @@ fn infer_with_mismatches(content: &str, include_mismatches: bool) -> String { | |||
188 | }; | 188 | }; |
189 | 189 | ||
190 | let module = db.module_for_file(file_id); | 190 | let module = db.module_for_file(file_id); |
191 | let crate_def_map = db.crate_def_map(module.krate); | 191 | let def_map = module.def_map(&db); |
192 | 192 | ||
193 | let mut defs: Vec<DefWithBodyId> = Vec::new(); | 193 | let mut defs: Vec<DefWithBodyId> = Vec::new(); |
194 | visit_module(&db, &crate_def_map, module.local_id, &mut |it| defs.push(it)); | 194 | visit_module(&db, &def_map, module.local_id, &mut |it| defs.push(it)); |
195 | defs.sort_by_key(|def| match def { | 195 | defs.sort_by_key(|def| match def { |
196 | DefWithBodyId::FunctionId(it) => { | 196 | DefWithBodyId::FunctionId(it) => { |
197 | let loc = it.lookup(&db); | 197 | let loc = it.lookup(&db); |
@@ -321,7 +321,7 @@ fn typing_whitespace_inside_a_function_should_not_invalidate_types() { | |||
321 | { | 321 | { |
322 | let events = db.log_executed(|| { | 322 | let events = db.log_executed(|| { |
323 | let module = db.module_for_file(pos.file_id); | 323 | let module = db.module_for_file(pos.file_id); |
324 | let crate_def_map = db.crate_def_map(module.krate); | 324 | let crate_def_map = module.def_map(&db); |
325 | visit_module(&db, &crate_def_map, module.local_id, &mut |def| { | 325 | visit_module(&db, &crate_def_map, module.local_id, &mut |def| { |
326 | db.infer(def); | 326 | db.infer(def); |
327 | }); | 327 | }); |