diff options
-rw-r--r-- | crates/ra_hir/src/code_model.rs | 2 | ||||
-rw-r--r-- | crates/ra_hir_def/src/body.rs | 3 | ||||
-rw-r--r-- | crates/ra_hir_def/src/child_by_source.rs | 6 | ||||
-rw-r--r-- | crates/ra_hir_def/src/item_scope.rs | 165 | ||||
-rw-r--r-- | crates/ra_hir_def/src/lang_item.rs | 2 | ||||
-rw-r--r-- | crates/ra_hir_def/src/lib.rs | 1 | ||||
-rw-r--r-- | crates/ra_hir_def/src/nameres.rs | 112 | ||||
-rw-r--r-- | crates/ra_hir_def/src/nameres/collector.rs | 61 | ||||
-rw-r--r-- | crates/ra_hir_def/src/nameres/tests.rs | 19 | ||||
-rw-r--r-- | crates/ra_hir_def/src/nameres/tests/incremental.rs | 4 | ||||
-rw-r--r-- | crates/ra_hir_def/src/nameres/tests/macros.rs | 4 | ||||
-rw-r--r-- | crates/ra_hir_def/src/resolver.rs | 3 | ||||
-rw-r--r-- | crates/ra_hir_ty/src/method_resolution.rs | 2 | ||||
-rw-r--r-- | crates/ra_hir_ty/src/test_db.rs | 2 | ||||
-rw-r--r-- | crates/ra_hir_ty/src/tests.rs | 2 |
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; | |||
17 | use crate::{ | 17 | use 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 | |||
4 | use hir_expand::name::Name; | ||
5 | use once_cell::sync::Lazy; | ||
6 | use rustc_hash::FxHashMap; | ||
7 | |||
8 | use crate::{per_ns::PerNs, BuiltinType, ImplId, LocalImportId, MacroDefId, ModuleDefId, TraitId}; | ||
9 | |||
10 | #[derive(Debug, Default, PartialEq, Eq)] | ||
11 | pub 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 | |||
29 | static 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)] | ||
40 | pub(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. | ||
49 | impl 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)] | ||
160 | pub 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; | |||
15 | pub mod builtin_type; | 15 | pub mod builtin_type; |
16 | pub mod diagnostics; | 16 | pub mod diagnostics; |
17 | pub mod per_ns; | 17 | pub mod per_ns; |
18 | pub mod item_scope; | ||
18 | 19 | ||
19 | pub mod dyn_map; | 20 | pub mod dyn_map; |
20 | pub mod keys; | 21 | pub 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 | ||
58 | use std::sync::Arc; | 58 | use std::sync::Arc; |
59 | 59 | ||
60 | use hir_expand::{diagnostics::DiagnosticSink, name::Name, InFile, MacroDefId}; | 60 | use hir_expand::{diagnostics::DiagnosticSink, name::Name, InFile}; |
61 | use once_cell::sync::Lazy; | ||
62 | use ra_arena::Arena; | 61 | use ra_arena::Arena; |
63 | use ra_db::{CrateId, Edition, FileId, FilePosition}; | 62 | use ra_db::{CrateId, Edition, FileId, FilePosition}; |
64 | use ra_prof::profile; | 63 | use ra_prof::profile; |
@@ -69,12 +68,12 @@ use ra_syntax::{ | |||
69 | use rustc_hash::FxHashMap; | 68 | use rustc_hash::FxHashMap; |
70 | 69 | ||
71 | use crate::{ | 70 | use 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 { | |||
166 | pub struct ModuleData { | 165 | pub 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)] | ||
178 | pub 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 | |||
195 | static 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)] | ||
206 | pub 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. | ||
215 | impl 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)] | ||
271 | pub 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 | ||
278 | impl CrateDefMap { | 174 | impl 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; | |||
18 | use crate::{ | 18 | use 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 { |