diff options
Diffstat (limited to 'crates/ra_hir/src/resolve.rs')
-rw-r--r-- | crates/ra_hir/src/resolve.rs | 405 |
1 files changed, 233 insertions, 172 deletions
diff --git a/crates/ra_hir/src/resolve.rs b/crates/ra_hir/src/resolve.rs index a77a9aeb1..d841593f8 100644 --- a/crates/ra_hir/src/resolve.rs +++ b/crates/ra_hir/src/resolve.rs | |||
@@ -1,7 +1,7 @@ | |||
1 | //! Name resolution. | 1 | //! Name resolution. |
2 | use std::sync::Arc; | 2 | use std::sync::Arc; |
3 | 3 | ||
4 | use rustc_hash::{FxHashMap, FxHashSet}; | 4 | use rustc_hash::FxHashSet; |
5 | 5 | ||
6 | use crate::{ | 6 | use crate::{ |
7 | code_model::Crate, | 7 | code_model::Crate, |
@@ -14,8 +14,9 @@ use crate::{ | |||
14 | impl_block::ImplBlock, | 14 | impl_block::ImplBlock, |
15 | name::{Name, SELF_PARAM, SELF_TYPE}, | 15 | name::{Name, SELF_PARAM, SELF_TYPE}, |
16 | nameres::{CrateDefMap, CrateModuleId, PerNs}, | 16 | nameres::{CrateDefMap, CrateModuleId, PerNs}, |
17 | path::Path, | 17 | path::{Path, PathKind}, |
18 | Adt, Enum, MacroDef, ModuleDef, Struct, Trait, | 18 | Adt, BuiltinType, Const, Enum, EnumVariant, Function, MacroDef, ModuleDef, Static, Struct, |
19 | Trait, TypeAlias, | ||
19 | }; | 20 | }; |
20 | 21 | ||
21 | #[derive(Debug, Clone, Default)] | 22 | #[derive(Debug, Clone, Default)] |
@@ -37,69 +38,6 @@ pub(crate) struct ExprScope { | |||
37 | } | 38 | } |
38 | 39 | ||
39 | #[derive(Debug, Clone)] | 40 | #[derive(Debug, Clone)] |
40 | pub(crate) struct PathResult { | ||
41 | /// The actual path resolution | ||
42 | // FIXME: `PerNs<Resolution>` type doesn't make sense, as not every | ||
43 | // Resolution variant can appear in every namespace | ||
44 | resolution: PerNs<Resolution>, | ||
45 | /// The first index in the path that we | ||
46 | /// were unable to resolve. | ||
47 | /// When path is fully resolved, this is 0. | ||
48 | remaining_index: usize, | ||
49 | } | ||
50 | |||
51 | impl PathResult { | ||
52 | /// Returns the remaining index in the result | ||
53 | /// returns None if the path was fully resolved | ||
54 | pub(crate) fn remaining_index(&self) -> Option<usize> { | ||
55 | if self.remaining_index > 0 { | ||
56 | Some(self.remaining_index) | ||
57 | } else { | ||
58 | None | ||
59 | } | ||
60 | } | ||
61 | |||
62 | /// Consumes `PathResult` and returns the contained `PerNs<Resolution>` | ||
63 | /// if the path was fully resolved, meaning we have no remaining items | ||
64 | pub(crate) fn into_fully_resolved(self) -> PerNs<Resolution> { | ||
65 | if self.is_fully_resolved() { | ||
66 | self.resolution | ||
67 | } else { | ||
68 | PerNs::none() | ||
69 | } | ||
70 | } | ||
71 | |||
72 | /// Consumes `PathResult` and returns the resolution and the | ||
73 | /// remaining_index as a tuple. | ||
74 | pub(crate) fn into_inner(self) -> (PerNs<Resolution>, Option<usize>) { | ||
75 | let index = self.remaining_index(); | ||
76 | (self.resolution, index) | ||
77 | } | ||
78 | |||
79 | /// Path is fully resolved when `remaining_index` is none | ||
80 | /// and the resolution contains anything | ||
81 | pub(crate) fn is_fully_resolved(&self) -> bool { | ||
82 | !self.resolution.is_none() && self.remaining_index().is_none() | ||
83 | } | ||
84 | |||
85 | fn empty() -> PathResult { | ||
86 | PathResult { resolution: PerNs::none(), remaining_index: 0 } | ||
87 | } | ||
88 | |||
89 | fn from_resolution(res: PerNs<Resolution>) -> PathResult { | ||
90 | PathResult::from_resolution_with_index(res, 0) | ||
91 | } | ||
92 | |||
93 | fn from_resolution_with_index(res: PerNs<Resolution>, remaining_index: usize) -> PathResult { | ||
94 | if res.is_none() { | ||
95 | PathResult::empty() | ||
96 | } else { | ||
97 | PathResult { resolution: res, remaining_index } | ||
98 | } | ||
99 | } | ||
100 | } | ||
101 | |||
102 | #[derive(Debug, Clone)] | ||
103 | pub(crate) enum Scope { | 41 | pub(crate) enum Scope { |
104 | /// All the items and imported names of a module | 42 | /// All the items and imported names of a module |
105 | ModuleScope(ModuleItemMap), | 43 | ModuleScope(ModuleItemMap), |
@@ -112,25 +50,41 @@ pub(crate) enum Scope { | |||
112 | } | 50 | } |
113 | 51 | ||
114 | #[derive(Debug, Clone, PartialEq, Eq)] | 52 | #[derive(Debug, Clone, PartialEq, Eq)] |
115 | pub enum Resolution { | 53 | pub enum TypeNs { |
116 | /// An item | 54 | SelfType(ImplBlock), |
117 | Def(ModuleDef), | 55 | GenericParam(u32), |
56 | Adt(Adt), | ||
57 | EnumVariant(EnumVariant), | ||
58 | TypeAlias(TypeAlias), | ||
59 | BuiltinType(BuiltinType), | ||
60 | Trait(Trait), | ||
61 | // Module belong to type ns, but the resovler is used when all module paths | ||
62 | // are fully resolved. | ||
63 | // Module(Module) | ||
64 | } | ||
65 | |||
66 | #[derive(Debug)] | ||
67 | pub enum ValueOrPartial { | ||
68 | ValueNs(ValueNs), | ||
69 | Partial(TypeNs, usize), | ||
70 | } | ||
118 | 71 | ||
119 | // FIXME: there's no way we can syntactically confuse a local with generic | 72 | #[derive(Debug)] |
120 | // param, so these two should not be members of the single enum | 73 | pub enum ValueNs { |
121 | /// A local binding (only value namespace) | ||
122 | LocalBinding(PatId), | 74 | LocalBinding(PatId), |
123 | /// A generic parameter | 75 | Function(Function), |
124 | GenericParam(u32), | 76 | Const(Const), |
125 | SelfType(ImplBlock), | 77 | Static(Static), |
78 | Struct(Struct), | ||
79 | EnumVariant(EnumVariant), | ||
126 | } | 80 | } |
127 | 81 | ||
128 | impl Resolver { | 82 | impl Resolver { |
129 | /// Resolve known trait from std, like `std::futures::Future` | 83 | /// Resolve known trait from std, like `std::futures::Future` |
130 | pub(crate) fn resolve_known_trait(&self, db: &impl HirDatabase, path: &Path) -> Option<Trait> { | 84 | pub(crate) fn resolve_known_trait(&self, db: &impl HirDatabase, path: &Path) -> Option<Trait> { |
131 | let res = self.resolve_path_segments(db, path).into_fully_resolved().take_types()?; | 85 | let res = self.resolve_module_path(db, path).take_types()?; |
132 | match res { | 86 | match res { |
133 | Resolution::Def(ModuleDef::Trait(it)) => Some(it), | 87 | ModuleDef::Trait(it) => Some(it), |
134 | _ => None, | 88 | _ => None, |
135 | } | 89 | } |
136 | } | 90 | } |
@@ -141,94 +95,214 @@ impl Resolver { | |||
141 | db: &impl HirDatabase, | 95 | db: &impl HirDatabase, |
142 | path: &Path, | 96 | path: &Path, |
143 | ) -> Option<Struct> { | 97 | ) -> Option<Struct> { |
144 | let res = self.resolve_path_segments(db, path).into_fully_resolved().take_types()?; | 98 | let res = self.resolve_module_path(db, path).take_types()?; |
145 | match res { | 99 | match res { |
146 | Resolution::Def(ModuleDef::Adt(Adt::Struct(it))) => Some(it), | 100 | ModuleDef::Adt(Adt::Struct(it)) => Some(it), |
147 | _ => None, | 101 | _ => None, |
148 | } | 102 | } |
149 | } | 103 | } |
150 | 104 | ||
151 | /// Resolve known enum from std, like `std::result::Result` | 105 | /// Resolve known enum from std, like `std::result::Result` |
152 | pub(crate) fn resolve_known_enum(&self, db: &impl HirDatabase, path: &Path) -> Option<Enum> { | 106 | pub(crate) fn resolve_known_enum(&self, db: &impl HirDatabase, path: &Path) -> Option<Enum> { |
153 | let res = self.resolve_path_segments(db, path).into_fully_resolved().take_types()?; | 107 | let res = self.resolve_module_path(db, path).take_types()?; |
154 | match res { | 108 | match res { |
155 | Resolution::Def(ModuleDef::Adt(Adt::Enum(it))) => Some(it), | 109 | ModuleDef::Adt(Adt::Enum(it)) => Some(it), |
156 | _ => None, | 110 | _ => None, |
157 | } | 111 | } |
158 | } | 112 | } |
159 | 113 | ||
160 | pub(crate) fn resolve_name(&self, db: &impl HirDatabase, name: &Name) -> PerNs<Resolution> { | 114 | /// pub only for source-binder |
161 | let mut resolution = PerNs::none(); | 115 | pub(crate) fn resolve_module_path( |
116 | &self, | ||
117 | db: &impl HirDatabase, | ||
118 | path: &Path, | ||
119 | ) -> PerNs<ModuleDef> { | ||
120 | let (item_map, module) = match self.module() { | ||
121 | Some(it) => it, | ||
122 | None => return PerNs::none(), | ||
123 | }; | ||
124 | let (module_res, segment_index) = item_map.resolve_path(db, module, path); | ||
125 | if segment_index.is_some() { | ||
126 | return PerNs::none(); | ||
127 | } | ||
128 | module_res | ||
129 | } | ||
130 | |||
131 | pub(crate) fn resolve_path_in_type_ns( | ||
132 | &self, | ||
133 | db: &impl HirDatabase, | ||
134 | path: &Path, | ||
135 | ) -> Option<(TypeNs, Option<usize>)> { | ||
136 | let first_name = &path.segments.first()?.name; | ||
137 | let skip_to_mod = path.kind != PathKind::Plain; | ||
162 | for scope in self.scopes.iter().rev() { | 138 | for scope in self.scopes.iter().rev() { |
163 | resolution = resolution.or(scope.resolve_name(db, name)); | 139 | match scope { |
164 | if resolution.is_all() { | 140 | Scope::ExprScope(_) => continue, |
165 | return resolution; | 141 | Scope::GenericParams(_) | Scope::ImplBlockScope(_) if skip_to_mod => continue, |
142 | |||
143 | Scope::GenericParams(params) => { | ||
144 | if let Some(param) = params.find_by_name(first_name) { | ||
145 | let idx = if path.segments.len() == 1 { None } else { Some(1) }; | ||
146 | return Some((TypeNs::GenericParam(param.idx), idx)); | ||
147 | } | ||
148 | } | ||
149 | Scope::ImplBlockScope(impl_) => { | ||
150 | if first_name == &SELF_TYPE { | ||
151 | let idx = if path.segments.len() == 1 { None } else { Some(1) }; | ||
152 | return Some((TypeNs::SelfType(*impl_), idx)); | ||
153 | } | ||
154 | } | ||
155 | Scope::ModuleScope(m) => { | ||
156 | let (module_def, idx) = m.crate_def_map.resolve_path(db, m.module_id, path); | ||
157 | let res = match module_def.take_types()? { | ||
158 | ModuleDef::Adt(it) => TypeNs::Adt(it), | ||
159 | ModuleDef::EnumVariant(it) => TypeNs::EnumVariant(it), | ||
160 | |||
161 | ModuleDef::TypeAlias(it) => TypeNs::TypeAlias(it), | ||
162 | ModuleDef::BuiltinType(it) => TypeNs::BuiltinType(it), | ||
163 | |||
164 | ModuleDef::Trait(it) => TypeNs::Trait(it), | ||
165 | |||
166 | ModuleDef::Function(_) | ||
167 | | ModuleDef::Const(_) | ||
168 | | ModuleDef::Static(_) | ||
169 | | ModuleDef::Module(_) => return None, | ||
170 | }; | ||
171 | return Some((res, idx)); | ||
172 | } | ||
166 | } | 173 | } |
167 | } | 174 | } |
168 | resolution | 175 | None |
169 | } | 176 | } |
170 | 177 | ||
171 | pub(crate) fn resolve_path_as_macro( | 178 | pub(crate) fn resolve_path_in_type_ns_fully( |
172 | &self, | 179 | &self, |
173 | db: &impl HirDatabase, | 180 | db: &impl HirDatabase, |
174 | path: &Path, | 181 | path: &Path, |
175 | ) -> Option<MacroDef> { | 182 | ) -> Option<TypeNs> { |
176 | let (item_map, module) = self.module()?; | 183 | let (res, unresolved) = self.resolve_path_in_type_ns(db, path)?; |
177 | item_map.resolve_path(db, module, path).0.get_macros() | 184 | if unresolved.is_some() { |
185 | return None; | ||
186 | } | ||
187 | Some(res) | ||
178 | } | 188 | } |
179 | 189 | ||
180 | /// Returns the resolved path segments | 190 | pub(crate) fn resolve_path_in_value_ns( |
181 | /// Which may be fully resolved, empty or partially resolved. | 191 | &self, |
182 | pub(crate) fn resolve_path_segments(&self, db: &impl HirDatabase, path: &Path) -> PathResult { | 192 | db: &impl HirDatabase, |
183 | if let Some(name) = path.as_ident() { | 193 | path: &Path, |
184 | PathResult::from_resolution(self.resolve_name(db, name)) | 194 | ) -> Option<ValueOrPartial> { |
185 | } else if path.is_self() { | 195 | let n_segments = path.segments.len(); |
186 | PathResult::from_resolution(self.resolve_name(db, &SELF_PARAM)) | 196 | let tmp = SELF_PARAM; |
187 | } else { | 197 | let first_name = if path.is_self() { &tmp } else { &path.segments.first()?.name }; |
188 | let (item_map, module) = match self.module() { | 198 | let skip_to_mod = path.kind != PathKind::Plain && !path.is_self(); |
189 | Some(it) => it, | 199 | for scope in self.scopes.iter().rev() { |
190 | None => return PathResult::empty(), | 200 | match scope { |
191 | }; | 201 | Scope::ExprScope(_) | Scope::GenericParams(_) | Scope::ImplBlockScope(_) |
192 | let (module_res, segment_index) = item_map.resolve_path(db, module, path); | 202 | if skip_to_mod => |
193 | 203 | { | |
194 | let def = module_res.map(Resolution::Def); | 204 | continue |
195 | 205 | } | |
196 | if let Some(index) = segment_index { | 206 | |
197 | PathResult::from_resolution_with_index(def, index) | 207 | Scope::ExprScope(scope) if n_segments <= 1 => { |
198 | } else { | 208 | let entry = scope |
199 | PathResult::from_resolution(def) | 209 | .expr_scopes |
210 | .entries(scope.scope_id) | ||
211 | .iter() | ||
212 | .find(|entry| entry.name() == first_name); | ||
213 | |||
214 | if let Some(e) = entry { | ||
215 | return Some(ValueOrPartial::ValueNs(ValueNs::LocalBinding(e.pat()))); | ||
216 | } | ||
217 | } | ||
218 | Scope::ExprScope(_) => continue, | ||
219 | |||
220 | Scope::GenericParams(params) if n_segments > 1 => { | ||
221 | if let Some(param) = params.find_by_name(first_name) { | ||
222 | let ty = TypeNs::GenericParam(param.idx); | ||
223 | return Some(ValueOrPartial::Partial(ty, 1)); | ||
224 | } | ||
225 | } | ||
226 | Scope::GenericParams(_) => continue, | ||
227 | |||
228 | Scope::ImplBlockScope(impl_) if n_segments > 1 => { | ||
229 | if first_name == &SELF_TYPE { | ||
230 | let ty = TypeNs::SelfType(*impl_); | ||
231 | return Some(ValueOrPartial::Partial(ty, 1)); | ||
232 | } | ||
233 | } | ||
234 | Scope::ImplBlockScope(_) => continue, | ||
235 | |||
236 | Scope::ModuleScope(m) => { | ||
237 | let (module_def, idx) = m.crate_def_map.resolve_path(db, m.module_id, path); | ||
238 | return match idx { | ||
239 | None => { | ||
240 | let value = match module_def.take_values()? { | ||
241 | ModuleDef::Function(it) => ValueNs::Function(it), | ||
242 | ModuleDef::Adt(Adt::Struct(it)) => ValueNs::Struct(it), | ||
243 | ModuleDef::EnumVariant(it) => ValueNs::EnumVariant(it), | ||
244 | ModuleDef::Const(it) => ValueNs::Const(it), | ||
245 | ModuleDef::Static(it) => ValueNs::Static(it), | ||
246 | |||
247 | ModuleDef::Adt(Adt::Enum(_)) | ||
248 | | ModuleDef::Adt(Adt::Union(_)) | ||
249 | | ModuleDef::Trait(_) | ||
250 | | ModuleDef::TypeAlias(_) | ||
251 | | ModuleDef::BuiltinType(_) | ||
252 | | ModuleDef::Module(_) => return None, | ||
253 | }; | ||
254 | Some(ValueOrPartial::ValueNs(value)) | ||
255 | } | ||
256 | Some(idx) => { | ||
257 | let ty = match module_def.take_types()? { | ||
258 | ModuleDef::Adt(it) => TypeNs::Adt(it), | ||
259 | ModuleDef::Trait(it) => TypeNs::Trait(it), | ||
260 | ModuleDef::TypeAlias(it) => TypeNs::TypeAlias(it), | ||
261 | ModuleDef::BuiltinType(it) => TypeNs::BuiltinType(it), | ||
262 | |||
263 | ModuleDef::Module(_) | ||
264 | | ModuleDef::Function(_) | ||
265 | | ModuleDef::EnumVariant(_) | ||
266 | | ModuleDef::Const(_) | ||
267 | | ModuleDef::Static(_) => return None, | ||
268 | }; | ||
269 | Some(ValueOrPartial::Partial(ty, idx)) | ||
270 | } | ||
271 | }; | ||
272 | } | ||
200 | } | 273 | } |
201 | } | 274 | } |
275 | None | ||
202 | } | 276 | } |
203 | 277 | ||
204 | /// Returns the fully resolved path if we were able to resolve it. | 278 | pub(crate) fn resolve_path_in_value_ns_fully( |
205 | /// otherwise returns `PerNs::none` | ||
206 | pub(crate) fn resolve_path_without_assoc_items( | ||
207 | &self, | 279 | &self, |
208 | db: &impl HirDatabase, | 280 | db: &impl HirDatabase, |
209 | path: &Path, | 281 | path: &Path, |
210 | ) -> PerNs<Resolution> { | 282 | ) -> Option<ValueNs> { |
211 | // into_fully_resolved() returns the fully resolved path or PerNs::none() otherwise | 283 | match self.resolve_path_in_value_ns(db, path)? { |
212 | self.resolve_path_segments(db, path).into_fully_resolved() | 284 | ValueOrPartial::ValueNs(it) => Some(it), |
285 | ValueOrPartial::Partial(..) => None, | ||
286 | } | ||
213 | } | 287 | } |
214 | 288 | ||
215 | pub(crate) fn all_names(&self, db: &impl HirDatabase) -> FxHashMap<Name, PerNs<Resolution>> { | 289 | pub(crate) fn resolve_path_as_macro( |
216 | let mut names = FxHashMap::default(); | 290 | &self, |
291 | db: &impl HirDatabase, | ||
292 | path: &Path, | ||
293 | ) -> Option<MacroDef> { | ||
294 | let (item_map, module) = self.module()?; | ||
295 | item_map.resolve_path(db, module, path).0.get_macros() | ||
296 | } | ||
297 | |||
298 | pub(crate) fn process_all_names( | ||
299 | &self, | ||
300 | db: &impl HirDatabase, | ||
301 | f: &mut dyn FnMut(Name, ScopeDef), | ||
302 | ) { | ||
217 | for scope in self.scopes.iter().rev() { | 303 | for scope in self.scopes.iter().rev() { |
218 | scope.collect_names(db, &mut |name, res| { | 304 | scope.process_names(db, f); |
219 | let current: &mut PerNs<Resolution> = names.entry(name).or_default(); | ||
220 | if current.types.is_none() { | ||
221 | current.types = res.types; | ||
222 | } | ||
223 | if current.values.is_none() { | ||
224 | current.values = res.values; | ||
225 | } | ||
226 | if current.macros.is_none() { | ||
227 | current.macros = res.macros; | ||
228 | } | ||
229 | }); | ||
230 | } | 305 | } |
231 | names | ||
232 | } | 306 | } |
233 | 307 | ||
234 | pub(crate) fn traits_in_scope(&self, db: &impl HirDatabase) -> FxHashSet<Trait> { | 308 | pub(crate) fn traits_in_scope(&self, db: &impl HirDatabase) -> FxHashSet<Trait> { |
@@ -301,41 +375,28 @@ impl Resolver { | |||
301 | } | 375 | } |
302 | } | 376 | } |
303 | 377 | ||
304 | impl Scope { | 378 | /// For IDE only |
305 | fn resolve_name(&self, db: &impl HirDatabase, name: &Name) -> PerNs<Resolution> { | 379 | pub enum ScopeDef { |
306 | match self { | 380 | ModuleDef(ModuleDef), |
307 | Scope::ModuleScope(m) => { | 381 | MacroDef(MacroDef), |
308 | if name == &SELF_PARAM { | 382 | GenericParam(u32), |
309 | PerNs::types(Resolution::Def(m.crate_def_map.mk_module(m.module_id).into())) | 383 | SelfType(ImplBlock), |
310 | } else { | 384 | LocalBinding(PatId), |
311 | m.crate_def_map | 385 | Unknown, |
312 | .resolve_name_in_module(db, m.module_id, name) | 386 | } |
313 | .map(Resolution::Def) | 387 | |
314 | } | 388 | impl From<PerNs<ModuleDef>> for ScopeDef { |
315 | } | 389 | fn from(def: PerNs<ModuleDef>) -> Self { |
316 | Scope::GenericParams(gp) => match gp.find_by_name(name) { | 390 | def.take_types() |
317 | Some(gp) => PerNs::types(Resolution::GenericParam(gp.idx)), | 391 | .or_else(|| def.take_values()) |
318 | None => PerNs::none(), | 392 | .map(ScopeDef::ModuleDef) |
319 | }, | 393 | .or_else(|| def.get_macros().map(ScopeDef::MacroDef)) |
320 | Scope::ImplBlockScope(i) => { | 394 | .unwrap_or(ScopeDef::Unknown) |
321 | if name == &SELF_TYPE { | ||
322 | PerNs::types(Resolution::SelfType(*i)) | ||
323 | } else { | ||
324 | PerNs::none() | ||
325 | } | ||
326 | } | ||
327 | Scope::ExprScope(e) => { | ||
328 | let entry = | ||
329 | e.expr_scopes.entries(e.scope_id).iter().find(|entry| entry.name() == name); | ||
330 | match entry { | ||
331 | Some(e) => PerNs::values(Resolution::LocalBinding(e.pat())), | ||
332 | None => PerNs::none(), | ||
333 | } | ||
334 | } | ||
335 | } | ||
336 | } | 395 | } |
396 | } | ||
337 | 397 | ||
338 | fn collect_names(&self, db: &impl HirDatabase, f: &mut dyn FnMut(Name, PerNs<Resolution>)) { | 398 | impl Scope { |
399 | fn process_names(&self, db: &impl HirDatabase, f: &mut dyn FnMut(Name, ScopeDef)) { | ||
339 | match self { | 400 | match self { |
340 | Scope::ModuleScope(m) => { | 401 | Scope::ModuleScope(m) => { |
341 | // FIXME: should we provide `self` here? | 402 | // FIXME: should we provide `self` here? |
@@ -346,32 +407,32 @@ impl Scope { | |||
346 | // }), | 407 | // }), |
347 | // ); | 408 | // ); |
348 | m.crate_def_map[m.module_id].scope.entries().for_each(|(name, res)| { | 409 | m.crate_def_map[m.module_id].scope.entries().for_each(|(name, res)| { |
349 | f(name.clone(), res.def.map(Resolution::Def)); | 410 | f(name.clone(), res.def.into()); |
350 | }); | 411 | }); |
351 | m.crate_def_map[m.module_id].scope.legacy_macros().for_each(|(name, macro_)| { | 412 | m.crate_def_map[m.module_id].scope.legacy_macros().for_each(|(name, macro_)| { |
352 | f(name.clone(), PerNs::macros(macro_)); | 413 | f(name.clone(), ScopeDef::MacroDef(macro_)); |
353 | }); | 414 | }); |
354 | m.crate_def_map.extern_prelude().iter().for_each(|(name, def)| { | 415 | m.crate_def_map.extern_prelude().iter().for_each(|(name, def)| { |
355 | f(name.clone(), PerNs::types(Resolution::Def(*def))); | 416 | f(name.clone(), ScopeDef::ModuleDef(*def)); |
356 | }); | 417 | }); |
357 | if let Some(prelude) = m.crate_def_map.prelude() { | 418 | if let Some(prelude) = m.crate_def_map.prelude() { |
358 | let prelude_def_map = db.crate_def_map(prelude.krate); | 419 | let prelude_def_map = db.crate_def_map(prelude.krate); |
359 | prelude_def_map[prelude.module_id].scope.entries().for_each(|(name, res)| { | 420 | prelude_def_map[prelude.module_id].scope.entries().for_each(|(name, res)| { |
360 | f(name.clone(), res.def.map(Resolution::Def)); | 421 | f(name.clone(), res.def.into()); |
361 | }); | 422 | }); |
362 | } | 423 | } |
363 | } | 424 | } |
364 | Scope::GenericParams(gp) => { | 425 | Scope::GenericParams(gp) => { |
365 | for param in &gp.params { | 426 | for param in &gp.params { |
366 | f(param.name.clone(), PerNs::types(Resolution::GenericParam(param.idx))) | 427 | f(param.name.clone(), ScopeDef::GenericParam(param.idx)) |
367 | } | 428 | } |
368 | } | 429 | } |
369 | Scope::ImplBlockScope(i) => { | 430 | Scope::ImplBlockScope(i) => { |
370 | f(SELF_TYPE, PerNs::types(Resolution::SelfType(*i))); | 431 | f(SELF_TYPE, ScopeDef::SelfType(*i)); |
371 | } | 432 | } |
372 | Scope::ExprScope(e) => { | 433 | Scope::ExprScope(e) => { |
373 | e.expr_scopes.entries(e.scope_id).iter().for_each(|e| { | 434 | e.expr_scopes.entries(e.scope_id).iter().for_each(|e| { |
374 | f(e.name().clone(), PerNs::values(Resolution::LocalBinding(e.pat()))); | 435 | f(e.name().clone(), ScopeDef::LocalBinding(e.pat())); |
375 | }); | 436 | }); |
376 | } | 437 | } |
377 | } | 438 | } |