aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorbors[bot] <26634292+bors[bot]@users.noreply.github.com>2019-12-20 19:51:03 +0000
committerGitHub <[email protected]>2019-12-20 19:51:03 +0000
commit6eab968c601637361e8fbd1ee93ded1b0d967bee (patch)
tree0d45c734f00247837f923f203b8cc3ffcfcc3e61
parentf578cd21823484cc1ee8e4273cd5c2f837934f34 (diff)
parent7a862f0d47e8ae018d449a04c918ea3705785552 (diff)
Merge #2624
2624: Separate module item from module scope r=matklad a=matklad bors r+ Co-authored-by: Aleksey Kladov <[email protected]>
-rw-r--r--crates/ra_hir/src/code_model.rs2
-rw-r--r--crates/ra_hir_def/src/body.rs3
-rw-r--r--crates/ra_hir_def/src/child_by_source.rs6
-rw-r--r--crates/ra_hir_def/src/item_scope.rs165
-rw-r--r--crates/ra_hir_def/src/lang_item.rs2
-rw-r--r--crates/ra_hir_def/src/lib.rs1
-rw-r--r--crates/ra_hir_def/src/nameres.rs112
-rw-r--r--crates/ra_hir_def/src/nameres/collector.rs61
-rw-r--r--crates/ra_hir_def/src/nameres/tests.rs19
-rw-r--r--crates/ra_hir_def/src/nameres/tests/incremental.rs4
-rw-r--r--crates/ra_hir_def/src/nameres/tests/macros.rs4
-rw-r--r--crates/ra_hir_def/src/resolver.rs3
-rw-r--r--crates/ra_hir_ty/src/method_resolution.rs2
-rw-r--r--crates/ra_hir_ty/src/test_db.rs2
-rw-r--r--crates/ra_hir_ty/src/tests.rs2
15 files changed, 210 insertions, 178 deletions
diff --git a/crates/ra_hir/src/code_model.rs b/crates/ra_hir/src/code_model.rs
index ecf883272..fca3a2950 100644
--- a/crates/ra_hir/src/code_model.rs
+++ b/crates/ra_hir/src/code_model.rs
@@ -221,7 +221,7 @@ impl Module {
221 221
222 pub fn impl_blocks(self, db: &impl DefDatabase) -> Vec<ImplBlock> { 222 pub fn impl_blocks(self, db: &impl DefDatabase) -> Vec<ImplBlock> {
223 let def_map = db.crate_def_map(self.id.krate); 223 let def_map = db.crate_def_map(self.id.krate);
224 def_map[self.id.local_id].impls.iter().copied().map(ImplBlock::from).collect() 224 def_map[self.id.local_id].scope.impls().map(ImplBlock::from).collect()
225 } 225 }
226 226
227 pub(crate) fn with_module_id(self, module_id: LocalModuleId) -> Module { 227 pub(crate) fn with_module_id(self, module_id: LocalModuleId) -> Module {
diff --git a/crates/ra_hir_def/src/body.rs b/crates/ra_hir_def/src/body.rs
index a92c01f86..445d215b7 100644
--- a/crates/ra_hir_def/src/body.rs
+++ b/crates/ra_hir_def/src/body.rs
@@ -17,7 +17,8 @@ use rustc_hash::FxHashMap;
17use crate::{ 17use crate::{
18 db::DefDatabase, 18 db::DefDatabase,
19 expr::{Expr, ExprId, Pat, PatId}, 19 expr::{Expr, ExprId, Pat, PatId},
20 nameres::{BuiltinShadowMode, CrateDefMap}, 20 item_scope::BuiltinShadowMode,
21 nameres::CrateDefMap,
21 path::{ModPath, Path}, 22 path::{ModPath, Path},
22 src::HasSource, 23 src::HasSource,
23 DefWithBodyId, HasModule, Lookup, ModuleDefId, ModuleId, 24 DefWithBodyId, HasModule, Lookup, ModuleDefId, ModuleId,
diff --git a/crates/ra_hir_def/src/child_by_source.rs b/crates/ra_hir_def/src/child_by_source.rs
index f5a65ad40..4488e8502 100644
--- a/crates/ra_hir_def/src/child_by_source.rs
+++ b/crates/ra_hir_def/src/child_by_source.rs
@@ -80,9 +80,9 @@ impl ChildBySource for ModuleId {
80 80
81 module_data.scope.declarations().for_each(|item| add_module_def(db, &mut res, item)); 81 module_data.scope.declarations().for_each(|item| add_module_def(db, &mut res, item));
82 82
83 for &impl_ in module_data.impls.iter() { 83 for imp in module_data.scope.impls() {
84 let src = impl_.lookup(db).source(db); 84 let src = imp.lookup(db).source(db);
85 res[keys::IMPL].insert(src, impl_) 85 res[keys::IMPL].insert(src, imp)
86 } 86 }
87 87
88 res 88 res
diff --git a/crates/ra_hir_def/src/item_scope.rs b/crates/ra_hir_def/src/item_scope.rs
new file mode 100644
index 000000000..6b9be8325
--- /dev/null
+++ b/crates/ra_hir_def/src/item_scope.rs
@@ -0,0 +1,165 @@
1//! Describes items defined or visible (ie, imported) in a certain scope.
2//! This is shared between modules and blocks.
3
4use hir_expand::name::Name;
5use once_cell::sync::Lazy;
6use rustc_hash::FxHashMap;
7
8use crate::{per_ns::PerNs, BuiltinType, ImplId, LocalImportId, MacroDefId, ModuleDefId, TraitId};
9
10#[derive(Debug, Default, PartialEq, Eq)]
11pub struct ItemScope {
12 items: FxHashMap<Name, Resolution>,
13 impls: Vec<ImplId>,
14 /// Macros visible in current module in legacy textual scope
15 ///
16 /// For macros invoked by an unqualified identifier like `bar!()`, `legacy_macros` will be searched in first.
17 /// If it yields no result, then it turns to module scoped `macros`.
18 /// It macros with name qualified with a path like `crate::foo::bar!()`, `legacy_macros` will be skipped,
19 /// and only normal scoped `macros` will be searched in.
20 ///
21 /// Note that this automatically inherit macros defined textually before the definition of module itself.
22 ///
23 /// Module scoped macros will be inserted into `items` instead of here.
24 // FIXME: Macro shadowing in one module is not properly handled. Non-item place macros will
25 // be all resolved to the last one defined if shadowing happens.
26 legacy_macros: FxHashMap<Name, MacroDefId>,
27}
28
29static BUILTIN_SCOPE: Lazy<FxHashMap<Name, Resolution>> = Lazy::new(|| {
30 BuiltinType::ALL
31 .iter()
32 .map(|(name, ty)| {
33 (name.clone(), Resolution { def: PerNs::types(ty.clone().into()), import: None })
34 })
35 .collect()
36});
37
38/// Shadow mode for builtin type which can be shadowed by module.
39#[derive(Debug, Copy, Clone, PartialEq, Eq)]
40pub(crate) enum BuiltinShadowMode {
41 // Prefer Module
42 Module,
43 // Prefer Other Types
44 Other,
45}
46
47/// Legacy macros can only be accessed through special methods like `get_legacy_macros`.
48/// Other methods will only resolve values, types and module scoped macros only.
49impl ItemScope {
50 pub fn entries<'a>(&'a self) -> impl Iterator<Item = (&'a Name, &'a Resolution)> + 'a {
51 //FIXME: shadowing
52 self.items.iter().chain(BUILTIN_SCOPE.iter())
53 }
54
55 pub fn declarations(&self) -> impl Iterator<Item = ModuleDefId> + '_ {
56 self.entries()
57 .filter_map(|(_name, res)| if res.import.is_none() { Some(res.def) } else { None })
58 .flat_map(|per_ns| {
59 per_ns.take_types().into_iter().chain(per_ns.take_values().into_iter())
60 })
61 }
62
63 pub fn impls(&self) -> impl Iterator<Item = ImplId> + ExactSizeIterator + '_ {
64 self.impls.iter().copied()
65 }
66
67 /// Iterate over all module scoped macros
68 pub(crate) fn macros<'a>(&'a self) -> impl Iterator<Item = (&'a Name, MacroDefId)> + 'a {
69 self.items
70 .iter()
71 .filter_map(|(name, res)| res.def.take_macros().map(|macro_| (name, macro_)))
72 }
73
74 /// Iterate over all legacy textual scoped macros visible at the end of the module
75 pub(crate) fn legacy_macros<'a>(&'a self) -> impl Iterator<Item = (&'a Name, MacroDefId)> + 'a {
76 self.legacy_macros.iter().map(|(name, def)| (name, *def))
77 }
78
79 /// Get a name from current module scope, legacy macros are not included
80 pub(crate) fn get(&self, name: &Name, shadow: BuiltinShadowMode) -> Option<&Resolution> {
81 match shadow {
82 BuiltinShadowMode::Module => self.items.get(name).or_else(|| BUILTIN_SCOPE.get(name)),
83 BuiltinShadowMode::Other => {
84 let item = self.items.get(name);
85 if let Some(res) = item {
86 if let Some(ModuleDefId::ModuleId(_)) = res.def.take_types() {
87 return BUILTIN_SCOPE.get(name).or(item);
88 }
89 }
90
91 item.or_else(|| BUILTIN_SCOPE.get(name))
92 }
93 }
94 }
95
96 pub(crate) fn traits<'a>(&'a self) -> impl Iterator<Item = TraitId> + 'a {
97 self.items.values().filter_map(|r| match r.def.take_types() {
98 Some(ModuleDefId::TraitId(t)) => Some(t),
99 _ => None,
100 })
101 }
102
103 pub(crate) fn get_legacy_macro(&self, name: &Name) -> Option<MacroDefId> {
104 self.legacy_macros.get(name).copied()
105 }
106
107 pub(crate) fn define_impl(&mut self, imp: ImplId) {
108 self.impls.push(imp)
109 }
110
111 pub(crate) fn define_legacy_macro(&mut self, name: Name, mac: MacroDefId) {
112 self.legacy_macros.insert(name, mac);
113 }
114
115 pub(crate) fn push_res(
116 &mut self,
117 name: Name,
118 res: &Resolution,
119 import: Option<LocalImportId>,
120 ) -> bool {
121 let mut changed = false;
122 let existing = self.items.entry(name.clone()).or_default();
123
124 if existing.def.types.is_none() && res.def.types.is_some() {
125 existing.def.types = res.def.types;
126 existing.import = import.or(res.import);
127 changed = true;
128 }
129 if existing.def.values.is_none() && res.def.values.is_some() {
130 existing.def.values = res.def.values;
131 existing.import = import.or(res.import);
132 changed = true;
133 }
134 if existing.def.macros.is_none() && res.def.macros.is_some() {
135 existing.def.macros = res.def.macros;
136 existing.import = import.or(res.import);
137 changed = true;
138 }
139
140 if existing.def.is_none()
141 && res.def.is_none()
142 && existing.import.is_none()
143 && res.import.is_some()
144 {
145 existing.import = res.import;
146 }
147 changed
148 }
149
150 pub(crate) fn collect_resolutions(&self) -> Vec<(Name, Resolution)> {
151 self.items.iter().map(|(name, res)| (name.clone(), res.clone())).collect()
152 }
153
154 pub(crate) fn collect_legacy_macros(&self) -> FxHashMap<Name, MacroDefId> {
155 self.legacy_macros.clone()
156 }
157}
158
159#[derive(Debug, Clone, PartialEq, Eq, Default)]
160pub struct Resolution {
161 /// None for unresolved
162 pub def: PerNs,
163 /// ident by which this is imported into local scope.
164 pub import: Option<LocalImportId>,
165}
diff --git a/crates/ra_hir_def/src/lang_item.rs b/crates/ra_hir_def/src/lang_item.rs
index f4fdbdcfc..cef061837 100644
--- a/crates/ra_hir_def/src/lang_item.rs
+++ b/crates/ra_hir_def/src/lang_item.rs
@@ -81,7 +81,7 @@ impl LangItems {
81 // Look for impl targets 81 // Look for impl targets
82 let def_map = db.crate_def_map(module.krate); 82 let def_map = db.crate_def_map(module.krate);
83 let module_data = &def_map[module.local_id]; 83 let module_data = &def_map[module.local_id];
84 for &impl_block in module_data.impls.iter() { 84 for impl_block in module_data.scope.impls() {
85 self.collect_lang_item(db, impl_block, LangItemTarget::ImplBlockId) 85 self.collect_lang_item(db, impl_block, LangItemTarget::ImplBlockId)
86 } 86 }
87 87
diff --git a/crates/ra_hir_def/src/lib.rs b/crates/ra_hir_def/src/lib.rs
index 6bb5408a8..acd4f4af1 100644
--- a/crates/ra_hir_def/src/lib.rs
+++ b/crates/ra_hir_def/src/lib.rs
@@ -15,6 +15,7 @@ pub mod type_ref;
15pub mod builtin_type; 15pub mod builtin_type;
16pub mod diagnostics; 16pub mod diagnostics;
17pub mod per_ns; 17pub mod per_ns;
18pub mod item_scope;
18 19
19pub mod dyn_map; 20pub mod dyn_map;
20pub mod keys; 21pub mod keys;
diff --git a/crates/ra_hir_def/src/nameres.rs b/crates/ra_hir_def/src/nameres.rs
index af52fa36e..5d4ca73a3 100644
--- a/crates/ra_hir_def/src/nameres.rs
+++ b/crates/ra_hir_def/src/nameres.rs
@@ -57,8 +57,7 @@ mod tests;
57 57
58use std::sync::Arc; 58use std::sync::Arc;
59 59
60use hir_expand::{diagnostics::DiagnosticSink, name::Name, InFile, MacroDefId}; 60use hir_expand::{diagnostics::DiagnosticSink, name::Name, InFile};
61use once_cell::sync::Lazy;
62use ra_arena::Arena; 61use ra_arena::Arena;
63use ra_db::{CrateId, Edition, FileId, FilePosition}; 62use ra_db::{CrateId, Edition, FileId, FilePosition};
64use ra_prof::profile; 63use ra_prof::profile;
@@ -69,12 +68,12 @@ use ra_syntax::{
69use rustc_hash::FxHashMap; 68use rustc_hash::FxHashMap;
70 69
71use crate::{ 70use crate::{
72 builtin_type::BuiltinType,
73 db::DefDatabase, 71 db::DefDatabase,
72 item_scope::{BuiltinShadowMode, ItemScope},
74 nameres::{diagnostics::DefDiagnostic, path_resolution::ResolveMode}, 73 nameres::{diagnostics::DefDiagnostic, path_resolution::ResolveMode},
75 path::ModPath, 74 path::ModPath,
76 per_ns::PerNs, 75 per_ns::PerNs,
77 AstId, ImplId, LocalImportId, LocalModuleId, ModuleDefId, ModuleId, TraitId, 76 AstId, LocalModuleId, ModuleDefId, ModuleId,
78}; 77};
79 78
80/// Contains all top-level defs from a macro-expanded crate 79/// Contains all top-level defs from a macro-expanded crate
@@ -166,113 +165,10 @@ impl ModuleOrigin {
166pub struct ModuleData { 165pub struct ModuleData {
167 pub parent: Option<LocalModuleId>, 166 pub parent: Option<LocalModuleId>,
168 pub children: FxHashMap<Name, LocalModuleId>, 167 pub children: FxHashMap<Name, LocalModuleId>,
169 pub scope: ModuleScope, 168 pub scope: ItemScope,
170 169
171 /// Where does this module come from? 170 /// Where does this module come from?
172 pub origin: ModuleOrigin, 171 pub origin: ModuleOrigin,
173
174 pub impls: Vec<ImplId>,
175}
176
177#[derive(Debug, Default, PartialEq, Eq)]
178pub struct ModuleScope {
179 items: FxHashMap<Name, Resolution>,
180 /// Macros visable in current module in legacy textual scope
181 ///
182 /// For macros invoked by an unquatified identifier like `bar!()`, `legacy_macros` will be searched in first.
183 /// If it yields no result, then it turns to module scoped `macros`.
184 /// It macros with name quatified with a path like `crate::foo::bar!()`, `legacy_macros` will be skipped,
185 /// and only normal scoped `macros` will be searched in.
186 ///
187 /// Note that this automatically inherit macros defined textually before the definition of module itself.
188 ///
189 /// Module scoped macros will be inserted into `items` instead of here.
190 // FIXME: Macro shadowing in one module is not properly handled. Non-item place macros will
191 // be all resolved to the last one defined if shadowing happens.
192 legacy_macros: FxHashMap<Name, MacroDefId>,
193}
194
195static BUILTIN_SCOPE: Lazy<FxHashMap<Name, Resolution>> = Lazy::new(|| {
196 BuiltinType::ALL
197 .iter()
198 .map(|(name, ty)| {
199 (name.clone(), Resolution { def: PerNs::types(ty.clone().into()), import: None })
200 })
201 .collect()
202});
203
204/// Shadow mode for builtin type which can be shadowed by module.
205#[derive(Debug, Copy, Clone, PartialEq, Eq)]
206pub enum BuiltinShadowMode {
207 // Prefer Module
208 Module,
209 // Prefer Other Types
210 Other,
211}
212
213/// Legacy macros can only be accessed through special methods like `get_legacy_macros`.
214/// Other methods will only resolve values, types and module scoped macros only.
215impl ModuleScope {
216 pub fn entries<'a>(&'a self) -> impl Iterator<Item = (&'a Name, &'a Resolution)> + 'a {
217 //FIXME: shadowing
218 self.items.iter().chain(BUILTIN_SCOPE.iter())
219 }
220
221 pub fn declarations(&self) -> impl Iterator<Item = ModuleDefId> + '_ {
222 self.entries()
223 .filter_map(|(_name, res)| if res.import.is_none() { Some(res.def) } else { None })
224 .flat_map(|per_ns| {
225 per_ns.take_types().into_iter().chain(per_ns.take_values().into_iter())
226 })
227 }
228
229 /// Iterate over all module scoped macros
230 pub fn macros<'a>(&'a self) -> impl Iterator<Item = (&'a Name, MacroDefId)> + 'a {
231 self.items
232 .iter()
233 .filter_map(|(name, res)| res.def.take_macros().map(|macro_| (name, macro_)))
234 }
235
236 /// Iterate over all legacy textual scoped macros visable at the end of the module
237 pub fn legacy_macros<'a>(&'a self) -> impl Iterator<Item = (&'a Name, MacroDefId)> + 'a {
238 self.legacy_macros.iter().map(|(name, def)| (name, *def))
239 }
240
241 /// Get a name from current module scope, legacy macros are not included
242 pub fn get(&self, name: &Name, shadow: BuiltinShadowMode) -> Option<&Resolution> {
243 match shadow {
244 BuiltinShadowMode::Module => self.items.get(name).or_else(|| BUILTIN_SCOPE.get(name)),
245 BuiltinShadowMode::Other => {
246 let item = self.items.get(name);
247 if let Some(res) = item {
248 if let Some(ModuleDefId::ModuleId(_)) = res.def.take_types() {
249 return BUILTIN_SCOPE.get(name).or(item);
250 }
251 }
252
253 item.or_else(|| BUILTIN_SCOPE.get(name))
254 }
255 }
256 }
257
258 pub fn traits<'a>(&'a self) -> impl Iterator<Item = TraitId> + 'a {
259 self.items.values().filter_map(|r| match r.def.take_types() {
260 Some(ModuleDefId::TraitId(t)) => Some(t),
261 _ => None,
262 })
263 }
264
265 fn get_legacy_macro(&self, name: &Name) -> Option<MacroDefId> {
266 self.legacy_macros.get(name).copied()
267 }
268}
269
270#[derive(Debug, Clone, PartialEq, Eq, Default)]
271pub struct Resolution {
272 /// None for unresolved
273 pub def: PerNs,
274 /// ident by which this is imported into local scope.
275 pub import: Option<LocalImportId>,
276} 172}
277 173
278impl CrateDefMap { 174impl CrateDefMap {
diff --git a/crates/ra_hir_def/src/nameres/collector.rs b/crates/ra_hir_def/src/nameres/collector.rs
index e68bf4868..8b641d8b5 100644
--- a/crates/ra_hir_def/src/nameres/collector.rs
+++ b/crates/ra_hir_def/src/nameres/collector.rs
@@ -18,9 +18,10 @@ use test_utils::tested_by;
18use crate::{ 18use crate::{
19 attr::Attrs, 19 attr::Attrs,
20 db::DefDatabase, 20 db::DefDatabase,
21 item_scope::Resolution,
21 nameres::{ 22 nameres::{
22 diagnostics::DefDiagnostic, mod_resolution::ModDir, path_resolution::ReachedFixedPoint, 23 diagnostics::DefDiagnostic, mod_resolution::ModDir, path_resolution::ReachedFixedPoint,
23 raw, BuiltinShadowMode, CrateDefMap, ModuleData, ModuleOrigin, Resolution, ResolveMode, 24 raw, BuiltinShadowMode, CrateDefMap, ModuleData, ModuleOrigin, ResolveMode,
24 }, 25 },
25 path::{ModPath, PathKind}, 26 path::{ModPath, PathKind},
26 per_ns::PerNs, 27 per_ns::PerNs,
@@ -225,14 +226,14 @@ where
225 226
226 /// Define a legacy textual scoped macro in module 227 /// Define a legacy textual scoped macro in module
227 /// 228 ///
228 /// We use a map `legacy_macros` to store all legacy textual scoped macros visable per module. 229 /// We use a map `legacy_macros` to store all legacy textual scoped macros visible per module.
229 /// It will clone all macros from parent legacy scope, whose definition is prior to 230 /// It will clone all macros from parent legacy scope, whose definition is prior to
230 /// the definition of current module. 231 /// the definition of current module.
231 /// And also, `macro_use` on a module will import all legacy macros visable inside to 232 /// And also, `macro_use` on a module will import all legacy macros visible inside to
232 /// current legacy scope, with possible shadowing. 233 /// current legacy scope, with possible shadowing.
233 fn define_legacy_macro(&mut self, module_id: LocalModuleId, name: Name, macro_: MacroDefId) { 234 fn define_legacy_macro(&mut self, module_id: LocalModuleId, name: Name, mac: MacroDefId) {
234 // Always shadowing 235 // Always shadowing
235 self.def_map.modules[module_id].scope.legacy_macros.insert(name, macro_); 236 self.def_map.modules[module_id].scope.define_legacy_macro(name, mac);
236 } 237 }
237 238
238 /// Import macros from `#[macro_use] extern crate`. 239 /// Import macros from `#[macro_use] extern crate`.
@@ -371,11 +372,7 @@ where
371 let scope = &item_map[m.local_id].scope; 372 let scope = &item_map[m.local_id].scope;
372 373
373 // Module scoped macros is included 374 // Module scoped macros is included
374 let items = scope 375 let items = scope.collect_resolutions();
375 .items
376 .iter()
377 .map(|(name, res)| (name.clone(), res.clone()))
378 .collect::<Vec<_>>();
379 376
380 self.update(module_id, Some(import_id), &items); 377 self.update(module_id, Some(import_id), &items);
381 } else { 378 } else {
@@ -385,11 +382,7 @@ where
385 let scope = &self.def_map[m.local_id].scope; 382 let scope = &self.def_map[m.local_id].scope;
386 383
387 // Module scoped macros is included 384 // Module scoped macros is included
388 let items = scope 385 let items = scope.collect_resolutions();
389 .items
390 .iter()
391 .map(|(name, res)| (name.clone(), res.clone()))
392 .collect::<Vec<_>>();
393 386
394 self.update(module_id, Some(import_id), &items); 387 self.update(module_id, Some(import_id), &items);
395 // record the glob import in case we add further items 388 // record the glob import in case we add further items
@@ -466,34 +459,10 @@ where
466 // prevent stack overflows (but this shouldn't be possible) 459 // prevent stack overflows (but this shouldn't be possible)
467 panic!("infinite recursion in glob imports!"); 460 panic!("infinite recursion in glob imports!");
468 } 461 }
469 let module_items = &mut self.def_map.modules[module_id].scope; 462 let scope = &mut self.def_map.modules[module_id].scope;
470 let mut changed = false; 463 let mut changed = false;
471 for (name, res) in resolutions { 464 for (name, res) in resolutions {
472 let existing = module_items.items.entry(name.clone()).or_default(); 465 changed |= scope.push_res(name.clone(), res, import);
473
474 if existing.def.types.is_none() && res.def.types.is_some() {
475 existing.def.types = res.def.types;
476 existing.import = import.or(res.import);
477 changed = true;
478 }
479 if existing.def.values.is_none() && res.def.values.is_some() {
480 existing.def.values = res.def.values;
481 existing.import = import.or(res.import);
482 changed = true;
483 }
484 if existing.def.macros.is_none() && res.def.macros.is_some() {
485 existing.def.macros = res.def.macros;
486 existing.import = import.or(res.import);
487 changed = true;
488 }
489
490 if existing.def.is_none()
491 && res.def.is_none()
492 && existing.import.is_none()
493 && res.import.is_some()
494 {
495 existing.import = res.import;
496 }
497 } 466 }
498 467
499 if !changed { 468 if !changed {
@@ -666,7 +635,9 @@ where
666 let impl_id = 635 let impl_id =
667 ImplLoc { container, ast_id: AstId::new(self.file_id, ast_id) } 636 ImplLoc { container, ast_id: AstId::new(self.file_id, ast_id) }
668 .intern(self.def_collector.db); 637 .intern(self.def_collector.db);
669 self.def_collector.def_map.modules[self.module_id].impls.push(impl_id) 638 self.def_collector.def_map.modules[self.module_id]
639 .scope
640 .define_impl(impl_id)
670 } 641 }
671 } 642 }
672 } 643 }
@@ -740,7 +711,9 @@ where
740 let res = modules.alloc(ModuleData::default()); 711 let res = modules.alloc(ModuleData::default());
741 modules[res].parent = Some(self.module_id); 712 modules[res].parent = Some(self.module_id);
742 modules[res].origin = ModuleOrigin::not_sure_file(definition, declaration); 713 modules[res].origin = ModuleOrigin::not_sure_file(definition, declaration);
743 modules[res].scope.legacy_macros = modules[self.module_id].scope.legacy_macros.clone(); 714 for (name, mac) in modules[self.module_id].scope.collect_legacy_macros() {
715 modules[res].scope.define_legacy_macro(name, mac)
716 }
744 modules[self.module_id].children.insert(name.clone(), res); 717 modules[self.module_id].children.insert(name.clone(), res);
745 let resolution = Resolution { 718 let resolution = Resolution {
746 def: PerNs::types( 719 def: PerNs::types(
@@ -904,7 +877,7 @@ where
904 } 877 }
905 878
906 fn import_all_legacy_macros(&mut self, module_id: LocalModuleId) { 879 fn import_all_legacy_macros(&mut self, module_id: LocalModuleId) {
907 let macros = self.def_collector.def_map[module_id].scope.legacy_macros.clone(); 880 let macros = self.def_collector.def_map[module_id].scope.collect_legacy_macros();
908 for (name, macro_) in macros { 881 for (name, macro_) in macros {
909 self.def_collector.define_legacy_macro(self.module_id, name.clone(), macro_); 882 self.def_collector.define_legacy_macro(self.module_id, name.clone(), macro_);
910 } 883 }
diff --git a/crates/ra_hir_def/src/nameres/tests.rs b/crates/ra_hir_def/src/nameres/tests.rs
index 61cdd768e..4e968bcc8 100644
--- a/crates/ra_hir_def/src/nameres/tests.rs
+++ b/crates/ra_hir_def/src/nameres/tests.rs
@@ -32,27 +32,22 @@ fn render_crate_def_map(map: &CrateDefMap) -> String {
32 *buf += path; 32 *buf += path;
33 *buf += "\n"; 33 *buf += "\n";
34 34
35 let mut entries = map.modules[module] 35 let mut entries = map.modules[module].scope.collect_resolutions();
36 .scope 36 entries.sort_by_key(|(name, _)| name.clone());
37 .items
38 .iter()
39 .map(|(name, res)| (name, res.def))
40 .collect::<Vec<_>>();
41 entries.sort_by_key(|(name, _)| *name);
42 37
43 for (name, res) in entries { 38 for (name, res) in entries {
44 *buf += &format!("{}:", name); 39 *buf += &format!("{}:", name);
45 40
46 if res.types.is_some() { 41 if res.def.types.is_some() {
47 *buf += " t"; 42 *buf += " t";
48 } 43 }
49 if res.values.is_some() { 44 if res.def.values.is_some() {
50 *buf += " v"; 45 *buf += " v";
51 } 46 }
52 if res.macros.is_some() { 47 if res.def.macros.is_some() {
53 *buf += " m"; 48 *buf += " m";
54 } 49 }
55 if res.is_none() { 50 if res.def.is_none() {
56 *buf += " _"; 51 *buf += " _";
57 } 52 }
58 53
@@ -587,6 +582,6 @@ mod b {
587 ⋮T: v 582 ⋮T: v
588 583
589 ⋮crate::a 584 ⋮crate::a
590 ⋮T: t v 585 ⋮T: t v
591"###); 586"###);
592} 587}
diff --git a/crates/ra_hir_def/src/nameres/tests/incremental.rs b/crates/ra_hir_def/src/nameres/tests/incremental.rs
index 903a22771..ef2e9435c 100644
--- a/crates/ra_hir_def/src/nameres/tests/incremental.rs
+++ b/crates/ra_hir_def/src/nameres/tests/incremental.rs
@@ -116,7 +116,7 @@ fn typing_inside_a_macro_should_not_invalidate_def_map() {
116 let events = db.log_executed(|| { 116 let events = db.log_executed(|| {
117 let crate_def_map = db.crate_def_map(krate); 117 let crate_def_map = db.crate_def_map(krate);
118 let (_, module_data) = crate_def_map.modules.iter().last().unwrap(); 118 let (_, module_data) = crate_def_map.modules.iter().last().unwrap();
119 assert_eq!(module_data.scope.items.len(), 1); 119 assert_eq!(module_data.scope.collect_resolutions().len(), 1);
120 }); 120 });
121 assert!(format!("{:?}", events).contains("crate_def_map"), "{:#?}", events) 121 assert!(format!("{:?}", events).contains("crate_def_map"), "{:#?}", events)
122 } 122 }
@@ -126,7 +126,7 @@ fn typing_inside_a_macro_should_not_invalidate_def_map() {
126 let events = db.log_executed(|| { 126 let events = db.log_executed(|| {
127 let crate_def_map = db.crate_def_map(krate); 127 let crate_def_map = db.crate_def_map(krate);
128 let (_, module_data) = crate_def_map.modules.iter().last().unwrap(); 128 let (_, module_data) = crate_def_map.modules.iter().last().unwrap();
129 assert_eq!(module_data.scope.items.len(), 1); 129 assert_eq!(module_data.scope.collect_resolutions().len(), 1);
130 }); 130 });
131 assert!(!format!("{:?}", events).contains("crate_def_map"), "{:#?}", events) 131 assert!(!format!("{:?}", events).contains("crate_def_map"), "{:#?}", events)
132 } 132 }
diff --git a/crates/ra_hir_def/src/nameres/tests/macros.rs b/crates/ra_hir_def/src/nameres/tests/macros.rs
index cfa4ecb1a..d104f5993 100644
--- a/crates/ra_hir_def/src/nameres/tests/macros.rs
+++ b/crates/ra_hir_def/src/nameres/tests/macros.rs
@@ -610,7 +610,7 @@ fn expand_derive() {
610 struct Foo; 610 struct Foo;
611 ", 611 ",
612 ); 612 );
613 assert_eq!(map.modules[map.root].impls.len(), 1); 613 assert_eq!(map.modules[map.root].scope.impls().len(), 1);
614} 614}
615 615
616#[test] 616#[test]
@@ -622,5 +622,5 @@ fn expand_multiple_derive() {
622 struct Foo; 622 struct Foo;
623 ", 623 ",
624 ); 624 );
625 assert_eq!(map.modules[map.root].impls.len(), 2); 625 assert_eq!(map.modules[map.root].scope.impls().len(), 2);
626} 626}
diff --git a/crates/ra_hir_def/src/resolver.rs b/crates/ra_hir_def/src/resolver.rs
index af9d194f8..83013fed3 100644
--- a/crates/ra_hir_def/src/resolver.rs
+++ b/crates/ra_hir_def/src/resolver.rs
@@ -14,7 +14,8 @@ use crate::{
14 db::DefDatabase, 14 db::DefDatabase,
15 expr::{ExprId, PatId}, 15 expr::{ExprId, PatId},
16 generics::GenericParams, 16 generics::GenericParams,
17 nameres::{BuiltinShadowMode, CrateDefMap}, 17 item_scope::BuiltinShadowMode,
18 nameres::CrateDefMap,
18 path::{ModPath, PathKind}, 19 path::{ModPath, PathKind},
19 per_ns::PerNs, 20 per_ns::PerNs,
20 AdtId, AssocContainerId, ConstId, ContainerId, DefWithBodyId, EnumId, EnumVariantId, 21 AdtId, AssocContainerId, ConstId, ContainerId, DefWithBodyId, EnumId, EnumVariantId,
diff --git a/crates/ra_hir_ty/src/method_resolution.rs b/crates/ra_hir_ty/src/method_resolution.rs
index 92fb4c081..888dc3116 100644
--- a/crates/ra_hir_ty/src/method_resolution.rs
+++ b/crates/ra_hir_ty/src/method_resolution.rs
@@ -58,7 +58,7 @@ impl CrateImplBlocks {
58 58
59 let crate_def_map = db.crate_def_map(krate); 59 let crate_def_map = db.crate_def_map(krate);
60 for (_module_id, module_data) in crate_def_map.modules.iter() { 60 for (_module_id, module_data) in crate_def_map.modules.iter() {
61 for &impl_id in module_data.impls.iter() { 61 for impl_id in module_data.scope.impls() {
62 match db.impl_trait(impl_id) { 62 match db.impl_trait(impl_id) {
63 Some(tr) => { 63 Some(tr) => {
64 res.impls_by_trait.entry(tr.trait_).or_default().push(impl_id); 64 res.impls_by_trait.entry(tr.trait_).or_default().push(impl_id);
diff --git a/crates/ra_hir_ty/src/test_db.rs b/crates/ra_hir_ty/src/test_db.rs
index 476f6df52..1a31b587b 100644
--- a/crates/ra_hir_ty/src/test_db.rs
+++ b/crates/ra_hir_ty/src/test_db.rs
@@ -98,7 +98,7 @@ impl TestDB {
98 } 98 }
99 } 99 }
100 100
101 for &impl_id in crate_def_map[module_id].impls.iter() { 101 for impl_id in crate_def_map[module_id].scope.impls() {
102 let impl_data = self.impl_data(impl_id); 102 let impl_data = self.impl_data(impl_id);
103 for item in impl_data.items.iter() { 103 for item in impl_data.items.iter() {
104 if let AssocItemId::FunctionId(f) = item { 104 if let AssocItemId::FunctionId(f) = item {
diff --git a/crates/ra_hir_ty/src/tests.rs b/crates/ra_hir_ty/src/tests.rs
index d724ee122..d447b4571 100644
--- a/crates/ra_hir_ty/src/tests.rs
+++ b/crates/ra_hir_ty/src/tests.rs
@@ -182,7 +182,7 @@ fn visit_module(
182 _ => (), 182 _ => (),
183 } 183 }
184 } 184 }
185 for &impl_id in crate_def_map[module_id].impls.iter() { 185 for impl_id in crate_def_map[module_id].scope.impls() {
186 let impl_data = db.impl_data(impl_id); 186 let impl_data = db.impl_data(impl_id);
187 for &item in impl_data.items.iter() { 187 for &item in impl_data.items.iter() {
188 match item { 188 match item {