diff options
Diffstat (limited to 'crates/hir_def/src/resolver.rs')
-rw-r--r-- | crates/hir_def/src/resolver.rs | 294 |
1 files changed, 145 insertions, 149 deletions
diff --git a/crates/hir_def/src/resolver.rs b/crates/hir_def/src/resolver.rs index 85ddc2c47..e85f85e49 100644 --- a/crates/hir_def/src/resolver.rs +++ b/crates/hir_def/src/resolver.rs | |||
@@ -10,19 +10,19 @@ use rustc_hash::FxHashSet; | |||
10 | 10 | ||
11 | use crate::{ | 11 | use crate::{ |
12 | body::scope::{ExprScopes, ScopeId}, | 12 | body::scope::{ExprScopes, ScopeId}, |
13 | body::Body, | ||
14 | builtin_type::BuiltinType, | 13 | builtin_type::BuiltinType, |
15 | db::DefDatabase, | 14 | db::DefDatabase, |
16 | expr::{ExprId, PatId}, | 15 | expr::{ExprId, PatId}, |
17 | generics::GenericParams, | 16 | generics::GenericParams, |
18 | item_scope::{BuiltinShadowMode, BUILTIN_SCOPE}, | 17 | item_scope::{BuiltinShadowMode, BUILTIN_SCOPE}, |
19 | nameres::CrateDefMap, | 18 | nameres::DefMap, |
20 | path::{ModPath, PathKind}, | 19 | path::{ModPath, PathKind}, |
21 | per_ns::PerNs, | 20 | per_ns::PerNs, |
22 | visibility::{RawVisibility, Visibility}, | 21 | visibility::{RawVisibility, Visibility}, |
23 | AdtId, AssocContainerId, ConstId, ConstParamId, ContainerId, DefWithBodyId, EnumId, | 22 | AdtId, AssocContainerId, ConstId, ConstParamId, ContainerId, DefWithBodyId, EnumId, |
24 | EnumVariantId, FunctionId, GenericDefId, HasModule, ImplId, LocalModuleId, Lookup, ModuleDefId, | 23 | EnumVariantId, FunctionId, GenericDefId, GenericParamId, HasModule, ImplId, LifetimeParamId, |
25 | ModuleId, StaticId, StructId, TraitId, TypeAliasId, TypeParamId, VariantId, | 24 | LocalModuleId, Lookup, ModuleDefId, ModuleId, StaticId, StructId, TraitId, TypeAliasId, |
25 | TypeParamId, VariantId, | ||
26 | }; | 26 | }; |
27 | 27 | ||
28 | #[derive(Debug, Clone, Default)] | 28 | #[derive(Debug, Clone, Default)] |
@@ -34,7 +34,7 @@ pub struct Resolver { | |||
34 | // FIXME how to store these best | 34 | // FIXME how to store these best |
35 | #[derive(Debug, Clone)] | 35 | #[derive(Debug, Clone)] |
36 | struct ModuleItemMap { | 36 | struct ModuleItemMap { |
37 | crate_def_map: Arc<CrateDefMap>, | 37 | crate_def_map: Arc<DefMap>, |
38 | module_id: LocalModuleId, | 38 | module_id: LocalModuleId, |
39 | } | 39 | } |
40 | 40 | ||
@@ -57,8 +57,6 @@ enum Scope { | |||
57 | AdtScope(AdtId), | 57 | AdtScope(AdtId), |
58 | /// Local bindings | 58 | /// Local bindings |
59 | ExprScope(ExprScope), | 59 | ExprScope(ExprScope), |
60 | /// Temporary hack to support local items. | ||
61 | LocalItemsScope(Arc<Body>), | ||
62 | } | 60 | } |
63 | 61 | ||
64 | #[derive(Debug, Clone, PartialEq, Eq, Hash)] | 62 | #[derive(Debug, Clone, PartialEq, Eq, Hash)] |
@@ -145,27 +143,34 @@ impl Resolver { | |||
145 | self.resolve_module_path(db, path, BuiltinShadowMode::Module) | 143 | self.resolve_module_path(db, path, BuiltinShadowMode::Module) |
146 | } | 144 | } |
147 | 145 | ||
146 | pub fn resolve_module_path_in_trait_items( | ||
147 | &self, | ||
148 | db: &dyn DefDatabase, | ||
149 | path: &ModPath, | ||
150 | ) -> Option<TraitId> { | ||
151 | let (item_map, module) = self.module_scope()?; | ||
152 | let (module_res, ..) = item_map.resolve_path(db, module, &path, BuiltinShadowMode::Module); | ||
153 | match module_res.take_types()? { | ||
154 | ModuleDefId::TraitId(it) => Some(it), | ||
155 | _ => None, | ||
156 | } | ||
157 | } | ||
158 | |||
148 | pub fn resolve_path_in_type_ns( | 159 | pub fn resolve_path_in_type_ns( |
149 | &self, | 160 | &self, |
150 | db: &dyn DefDatabase, | 161 | db: &dyn DefDatabase, |
151 | path: &ModPath, | 162 | path: &ModPath, |
152 | ) -> Option<(TypeNs, Option<usize>)> { | 163 | ) -> Option<(TypeNs, Option<usize>)> { |
153 | let first_name = path.segments.first()?; | 164 | let first_name = path.segments().first()?; |
154 | let skip_to_mod = path.kind != PathKind::Plain; | 165 | let skip_to_mod = path.kind != PathKind::Plain; |
155 | for scope in self.scopes.iter().rev() { | 166 | for scope in self.scopes.iter().rev() { |
156 | match scope { | 167 | match scope { |
157 | Scope::ExprScope(_) => continue, | 168 | Scope::ExprScope(_) => continue, |
158 | Scope::GenericParams { .. } | 169 | Scope::GenericParams { .. } | Scope::ImplDefScope(_) if skip_to_mod => continue, |
159 | | Scope::ImplDefScope(_) | ||
160 | | Scope::LocalItemsScope(_) | ||
161 | if skip_to_mod => | ||
162 | { | ||
163 | continue | ||
164 | } | ||
165 | 170 | ||
166 | Scope::GenericParams { params, def } => { | 171 | Scope::GenericParams { params, def } => { |
167 | if let Some(local_id) = params.find_type_by_name(first_name) { | 172 | if let Some(local_id) = params.find_type_by_name(first_name) { |
168 | let idx = if path.segments.len() == 1 { None } else { Some(1) }; | 173 | let idx = if path.segments().len() == 1 { None } else { Some(1) }; |
169 | return Some(( | 174 | return Some(( |
170 | TypeNs::GenericParam(TypeParamId { local_id, parent: *def }), | 175 | TypeNs::GenericParam(TypeParamId { local_id, parent: *def }), |
171 | idx, | 176 | idx, |
@@ -174,52 +179,24 @@ impl Resolver { | |||
174 | } | 179 | } |
175 | Scope::ImplDefScope(impl_) => { | 180 | Scope::ImplDefScope(impl_) => { |
176 | if first_name == &name![Self] { | 181 | if first_name == &name![Self] { |
177 | let idx = if path.segments.len() == 1 { None } else { Some(1) }; | 182 | let idx = if path.segments().len() == 1 { None } else { Some(1) }; |
178 | return Some((TypeNs::SelfType(*impl_), idx)); | 183 | return Some((TypeNs::SelfType(*impl_), idx)); |
179 | } | 184 | } |
180 | } | 185 | } |
181 | Scope::AdtScope(adt) => { | 186 | Scope::AdtScope(adt) => { |
182 | if first_name == &name![Self] { | 187 | if first_name == &name![Self] { |
183 | let idx = if path.segments.len() == 1 { None } else { Some(1) }; | 188 | let idx = if path.segments().len() == 1 { None } else { Some(1) }; |
184 | return Some((TypeNs::AdtSelfType(*adt), idx)); | 189 | return Some((TypeNs::AdtSelfType(*adt), idx)); |
185 | } | 190 | } |
186 | } | 191 | } |
187 | Scope::ModuleScope(m) => { | 192 | Scope::ModuleScope(m) => { |
188 | let (module_def, idx) = m.crate_def_map.resolve_path( | 193 | if let Some(res) = m.resolve_path_in_type_ns(db, path) { |
189 | db, | 194 | return Some(res); |
190 | m.module_id, | ||
191 | &path, | ||
192 | BuiltinShadowMode::Other, | ||
193 | ); | ||
194 | let res = to_type_ns(module_def)?; | ||
195 | return Some((res, idx)); | ||
196 | } | ||
197 | Scope::LocalItemsScope(body) => { | ||
198 | let def = body.item_scope.get(first_name); | ||
199 | if let Some(res) = to_type_ns(def) { | ||
200 | return Some((res, None)); | ||
201 | } | 195 | } |
202 | } | 196 | } |
203 | } | 197 | } |
204 | } | 198 | } |
205 | return None; | 199 | None |
206 | fn to_type_ns(per_ns: PerNs) -> Option<TypeNs> { | ||
207 | let res = match per_ns.take_types()? { | ||
208 | ModuleDefId::AdtId(it) => TypeNs::AdtId(it), | ||
209 | ModuleDefId::EnumVariantId(it) => TypeNs::EnumVariantId(it), | ||
210 | |||
211 | ModuleDefId::TypeAliasId(it) => TypeNs::TypeAliasId(it), | ||
212 | ModuleDefId::BuiltinType(it) => TypeNs::BuiltinType(it), | ||
213 | |||
214 | ModuleDefId::TraitId(it) => TypeNs::TraitId(it), | ||
215 | |||
216 | ModuleDefId::FunctionId(_) | ||
217 | | ModuleDefId::ConstId(_) | ||
218 | | ModuleDefId::StaticId(_) | ||
219 | | ModuleDefId::ModuleId(_) => return None, | ||
220 | }; | ||
221 | Some(res) | ||
222 | } | ||
223 | } | 200 | } |
224 | 201 | ||
225 | pub fn resolve_path_in_type_ns_fully( | 202 | pub fn resolve_path_in_type_ns_fully( |
@@ -256,9 +233,9 @@ impl Resolver { | |||
256 | db: &dyn DefDatabase, | 233 | db: &dyn DefDatabase, |
257 | path: &ModPath, | 234 | path: &ModPath, |
258 | ) -> Option<ResolveValueResult> { | 235 | ) -> Option<ResolveValueResult> { |
259 | let n_segments = path.segments.len(); | 236 | let n_segments = path.segments().len(); |
260 | let tmp = name![self]; | 237 | let tmp = name![self]; |
261 | let first_name = if path.is_self() { &tmp } else { path.segments.first()? }; | 238 | let first_name = if path.is_self() { &tmp } else { path.segments().first()? }; |
262 | let skip_to_mod = path.kind != PathKind::Plain && !path.is_self(); | 239 | let skip_to_mod = path.kind != PathKind::Plain && !path.is_self(); |
263 | for scope in self.scopes.iter().rev() { | 240 | for scope in self.scopes.iter().rev() { |
264 | match scope { | 241 | match scope { |
@@ -266,7 +243,6 @@ impl Resolver { | |||
266 | | Scope::ExprScope(_) | 243 | | Scope::ExprScope(_) |
267 | | Scope::GenericParams { .. } | 244 | | Scope::GenericParams { .. } |
268 | | Scope::ImplDefScope(_) | 245 | | Scope::ImplDefScope(_) |
269 | | Scope::LocalItemsScope(_) | ||
270 | if skip_to_mod => | 246 | if skip_to_mod => |
271 | { | 247 | { |
272 | continue | 248 | continue |
@@ -321,63 +297,14 @@ impl Resolver { | |||
321 | } | 297 | } |
322 | 298 | ||
323 | Scope::ModuleScope(m) => { | 299 | Scope::ModuleScope(m) => { |
324 | let (module_def, idx) = m.crate_def_map.resolve_path( | 300 | if let Some(def) = m.resolve_path_in_value_ns(db, path) { |
325 | db, | 301 | return Some(def); |
326 | m.module_id, | ||
327 | &path, | ||
328 | BuiltinShadowMode::Other, | ||
329 | ); | ||
330 | return match idx { | ||
331 | None => { | ||
332 | let value = to_value_ns(module_def)?; | ||
333 | Some(ResolveValueResult::ValueNs(value)) | ||
334 | } | ||
335 | Some(idx) => { | ||
336 | let ty = match module_def.take_types()? { | ||
337 | ModuleDefId::AdtId(it) => TypeNs::AdtId(it), | ||
338 | ModuleDefId::TraitId(it) => TypeNs::TraitId(it), | ||
339 | ModuleDefId::TypeAliasId(it) => TypeNs::TypeAliasId(it), | ||
340 | ModuleDefId::BuiltinType(it) => TypeNs::BuiltinType(it), | ||
341 | |||
342 | ModuleDefId::ModuleId(_) | ||
343 | | ModuleDefId::FunctionId(_) | ||
344 | | ModuleDefId::EnumVariantId(_) | ||
345 | | ModuleDefId::ConstId(_) | ||
346 | | ModuleDefId::StaticId(_) => return None, | ||
347 | }; | ||
348 | Some(ResolveValueResult::Partial(ty, idx)) | ||
349 | } | ||
350 | }; | ||
351 | } | ||
352 | Scope::LocalItemsScope(body) => { | ||
353 | // we don't bother looking in the builtin scope here because there are no builtin values | ||
354 | let def = to_value_ns(body.item_scope.get(first_name)); | ||
355 | |||
356 | if let Some(res) = def { | ||
357 | return Some(ResolveValueResult::ValueNs(res)); | ||
358 | } | 302 | } |
359 | } | 303 | } |
360 | } | 304 | } |
361 | } | 305 | } |
362 | return None; | 306 | |
363 | 307 | None | |
364 | fn to_value_ns(per_ns: PerNs) -> Option<ValueNs> { | ||
365 | let res = match per_ns.take_values()? { | ||
366 | ModuleDefId::FunctionId(it) => ValueNs::FunctionId(it), | ||
367 | ModuleDefId::AdtId(AdtId::StructId(it)) => ValueNs::StructId(it), | ||
368 | ModuleDefId::EnumVariantId(it) => ValueNs::EnumVariantId(it), | ||
369 | ModuleDefId::ConstId(it) => ValueNs::ConstId(it), | ||
370 | ModuleDefId::StaticId(it) => ValueNs::StaticId(it), | ||
371 | |||
372 | ModuleDefId::AdtId(AdtId::EnumId(_)) | ||
373 | | ModuleDefId::AdtId(AdtId::UnionId(_)) | ||
374 | | ModuleDefId::TraitId(_) | ||
375 | | ModuleDefId::TypeAliasId(_) | ||
376 | | ModuleDefId::BuiltinType(_) | ||
377 | | ModuleDefId::ModuleId(_) => return None, | ||
378 | }; | ||
379 | Some(res) | ||
380 | } | ||
381 | } | 308 | } |
382 | 309 | ||
383 | pub fn resolve_path_in_value_ns_fully( | 310 | pub fn resolve_path_in_value_ns_fully( |
@@ -396,11 +323,6 @@ impl Resolver { | |||
396 | db: &dyn DefDatabase, | 323 | db: &dyn DefDatabase, |
397 | path: &ModPath, | 324 | path: &ModPath, |
398 | ) -> Option<MacroDefId> { | 325 | ) -> Option<MacroDefId> { |
399 | // Search item scope legacy macro first | ||
400 | if let Some(def) = self.resolve_local_macro_def(path) { | ||
401 | return Some(def); | ||
402 | } | ||
403 | |||
404 | let (item_map, module) = self.module_scope()?; | 326 | let (item_map, module) = self.module_scope()?; |
405 | item_map.resolve_path(db, module, &path, BuiltinShadowMode::Other).0.take_macros() | 327 | item_map.resolve_path(db, module, &path, BuiltinShadowMode::Other).0.take_macros() |
406 | } | 328 | } |
@@ -415,8 +337,8 @@ impl Resolver { | |||
415 | let mut traits = FxHashSet::default(); | 337 | let mut traits = FxHashSet::default(); |
416 | for scope in &self.scopes { | 338 | for scope in &self.scopes { |
417 | if let Scope::ModuleScope(m) = scope { | 339 | if let Scope::ModuleScope(m) = scope { |
418 | if let Some(prelude) = m.crate_def_map.prelude { | 340 | if let Some(prelude) = m.crate_def_map.prelude() { |
419 | let prelude_def_map = db.crate_def_map(prelude.krate); | 341 | let prelude_def_map = prelude.def_map(db); |
420 | traits.extend(prelude_def_map[prelude.local_id].scope.traits()); | 342 | traits.extend(prelude_def_map[prelude.local_id].scope.traits()); |
421 | } | 343 | } |
422 | traits.extend(m.crate_def_map[m.module_id].scope.traits()); | 344 | traits.extend(m.crate_def_map[m.module_id].scope.traits()); |
@@ -425,7 +347,7 @@ impl Resolver { | |||
425 | traits | 347 | traits |
426 | } | 348 | } |
427 | 349 | ||
428 | fn module_scope(&self) -> Option<(&CrateDefMap, LocalModuleId)> { | 350 | fn module_scope(&self) -> Option<(&DefMap, LocalModuleId)> { |
429 | self.scopes.iter().rev().find_map(|scope| match scope { | 351 | self.scopes.iter().rev().find_map(|scope| match scope { |
430 | Scope::ModuleScope(m) => Some((&*m.crate_def_map, m.module_id)), | 352 | Scope::ModuleScope(m) => Some((&*m.crate_def_map, m.module_id)), |
431 | 353 | ||
@@ -433,23 +355,14 @@ impl Resolver { | |||
433 | }) | 355 | }) |
434 | } | 356 | } |
435 | 357 | ||
436 | fn resolve_local_macro_def(&self, path: &ModPath) -> Option<MacroDefId> { | ||
437 | let name = path.as_ident()?; | ||
438 | self.scopes.iter().rev().find_map(|scope| { | ||
439 | if let Scope::LocalItemsScope(body) = scope { | ||
440 | return body.item_scope.get_legacy_macro(name); | ||
441 | } | ||
442 | None | ||
443 | }) | ||
444 | } | ||
445 | |||
446 | pub fn module(&self) -> Option<ModuleId> { | 358 | pub fn module(&self) -> Option<ModuleId> { |
447 | let (def_map, local_id) = self.module_scope()?; | 359 | let (def_map, local_id) = self.module_scope()?; |
448 | Some(ModuleId { krate: def_map.krate, local_id }) | 360 | Some(def_map.module_id(local_id)) |
449 | } | 361 | } |
450 | 362 | ||
451 | pub fn krate(&self) -> Option<CrateId> { | 363 | pub fn krate(&self) -> Option<CrateId> { |
452 | self.module_scope().map(|t| t.0.krate) | 364 | // FIXME: can this ever be `None`? |
365 | self.module_scope().map(|t| t.0.krate()) | ||
453 | } | 366 | } |
454 | 367 | ||
455 | pub fn where_predicates_in_scope<'a>( | 368 | pub fn where_predicates_in_scope<'a>( |
@@ -484,7 +397,7 @@ pub enum ScopeDef { | |||
484 | PerNs(PerNs), | 397 | PerNs(PerNs), |
485 | ImplSelfType(ImplId), | 398 | ImplSelfType(ImplId), |
486 | AdtSelfType(AdtId), | 399 | AdtSelfType(AdtId), |
487 | GenericParam(TypeParamId), | 400 | GenericParam(GenericParamId), |
488 | Local(PatId), | 401 | Local(PatId), |
489 | } | 402 | } |
490 | 403 | ||
@@ -508,14 +421,14 @@ impl Scope { | |||
508 | seen.insert((name.clone(), scope)); | 421 | seen.insert((name.clone(), scope)); |
509 | f(name.clone(), ScopeDef::PerNs(scope)); | 422 | f(name.clone(), ScopeDef::PerNs(scope)); |
510 | }); | 423 | }); |
511 | m.crate_def_map.extern_prelude.iter().for_each(|(name, &def)| { | 424 | m.crate_def_map.extern_prelude().for_each(|(name, &def)| { |
512 | f(name.clone(), ScopeDef::PerNs(PerNs::types(def, Visibility::Public))); | 425 | f(name.clone(), ScopeDef::PerNs(PerNs::types(def, Visibility::Public))); |
513 | }); | 426 | }); |
514 | BUILTIN_SCOPE.iter().for_each(|(name, &def)| { | 427 | BUILTIN_SCOPE.iter().for_each(|(name, &def)| { |
515 | f(name.clone(), ScopeDef::PerNs(def)); | 428 | f(name.clone(), ScopeDef::PerNs(def)); |
516 | }); | 429 | }); |
517 | if let Some(prelude) = m.crate_def_map.prelude { | 430 | if let Some(prelude) = m.crate_def_map.prelude() { |
518 | let prelude_def_map = db.crate_def_map(prelude.krate); | 431 | let prelude_def_map = prelude.def_map(db); |
519 | prelude_def_map[prelude.local_id].scope.entries().for_each(|(name, def)| { | 432 | prelude_def_map[prelude.local_id].scope.entries().for_each(|(name, def)| { |
520 | let seen_tuple = (name.clone(), def); | 433 | let seen_tuple = (name.clone(), def); |
521 | if !seen.contains(&seen_tuple) { | 434 | if !seen.contains(&seen_tuple) { |
@@ -524,18 +437,21 @@ impl Scope { | |||
524 | }); | 437 | }); |
525 | } | 438 | } |
526 | } | 439 | } |
527 | Scope::LocalItemsScope(body) => body.item_scope.entries().for_each(|(name, def)| { | 440 | &Scope::GenericParams { ref params, def: parent } => { |
528 | f(name.clone(), ScopeDef::PerNs(def)); | ||
529 | }), | ||
530 | Scope::GenericParams { params, def } => { | ||
531 | for (local_id, param) in params.types.iter() { | 441 | for (local_id, param) in params.types.iter() { |
532 | if let Some(name) = ¶m.name { | 442 | if let Some(ref name) = param.name { |
533 | f( | 443 | let id = TypeParamId { local_id, parent }; |
534 | name.clone(), | 444 | f(name.clone(), ScopeDef::GenericParam(id.into())) |
535 | ScopeDef::GenericParam(TypeParamId { local_id, parent: *def }), | ||
536 | ) | ||
537 | } | 445 | } |
538 | } | 446 | } |
447 | for (local_id, param) in params.consts.iter() { | ||
448 | let id = ConstParamId { local_id, parent }; | ||
449 | f(param.name.clone(), ScopeDef::GenericParam(id.into())) | ||
450 | } | ||
451 | for (local_id, param) in params.lifetimes.iter() { | ||
452 | let id = LifetimeParamId { local_id, parent }; | ||
453 | f(param.name.clone(), ScopeDef::GenericParam(id.into())) | ||
454 | } | ||
539 | } | 455 | } |
540 | Scope::ImplDefScope(i) => { | 456 | Scope::ImplDefScope(i) => { |
541 | f(name![Self], ScopeDef::ImplSelfType(*i)); | 457 | f(name![Self], ScopeDef::ImplSelfType(*i)); |
@@ -564,10 +480,19 @@ pub fn resolver_for_scope( | |||
564 | scope_id: Option<ScopeId>, | 480 | scope_id: Option<ScopeId>, |
565 | ) -> Resolver { | 481 | ) -> Resolver { |
566 | let mut r = owner.resolver(db); | 482 | let mut r = owner.resolver(db); |
567 | r = r.push_local_items_scope(db.body(owner)); | ||
568 | let scopes = db.expr_scopes(owner); | 483 | let scopes = db.expr_scopes(owner); |
569 | let scope_chain = scopes.scope_chain(scope_id).collect::<Vec<_>>(); | 484 | let scope_chain = scopes.scope_chain(scope_id).collect::<Vec<_>>(); |
570 | for scope in scope_chain.into_iter().rev() { | 485 | for scope in scope_chain.into_iter().rev() { |
486 | if let Some(block) = scopes.block(scope) { | ||
487 | if let Some(def_map) = db.block_def_map(block) { | ||
488 | let root = def_map.root(); | ||
489 | r = r.push_module_scope(def_map, root); | ||
490 | // FIXME: This adds as many module scopes as there are blocks, but resolving in each | ||
491 | // already traverses all parents, so this is O(n²). I think we could only store the | ||
492 | // innermost module scope instead? | ||
493 | } | ||
494 | } | ||
495 | |||
571 | r = r.push_expr_scope(owner, Arc::clone(&scopes), scope); | 496 | r = r.push_expr_scope(owner, Arc::clone(&scopes), scope); |
572 | } | 497 | } |
573 | r | 498 | r |
@@ -588,18 +513,10 @@ impl Resolver { | |||
588 | self.push_scope(Scope::ImplDefScope(impl_def)) | 513 | self.push_scope(Scope::ImplDefScope(impl_def)) |
589 | } | 514 | } |
590 | 515 | ||
591 | fn push_module_scope( | 516 | fn push_module_scope(self, crate_def_map: Arc<DefMap>, module_id: LocalModuleId) -> Resolver { |
592 | self, | ||
593 | crate_def_map: Arc<CrateDefMap>, | ||
594 | module_id: LocalModuleId, | ||
595 | ) -> Resolver { | ||
596 | self.push_scope(Scope::ModuleScope(ModuleItemMap { crate_def_map, module_id })) | 517 | self.push_scope(Scope::ModuleScope(ModuleItemMap { crate_def_map, module_id })) |
597 | } | 518 | } |
598 | 519 | ||
599 | fn push_local_items_scope(self, body: Arc<Body>) -> Resolver { | ||
600 | self.push_scope(Scope::LocalItemsScope(body)) | ||
601 | } | ||
602 | |||
603 | fn push_expr_scope( | 520 | fn push_expr_scope( |
604 | self, | 521 | self, |
605 | owner: DefWithBodyId, | 522 | owner: DefWithBodyId, |
@@ -610,6 +527,85 @@ impl Resolver { | |||
610 | } | 527 | } |
611 | } | 528 | } |
612 | 529 | ||
530 | impl ModuleItemMap { | ||
531 | fn resolve_path_in_value_ns( | ||
532 | &self, | ||
533 | db: &dyn DefDatabase, | ||
534 | path: &ModPath, | ||
535 | ) -> Option<ResolveValueResult> { | ||
536 | let (module_def, idx) = | ||
537 | self.crate_def_map.resolve_path(db, self.module_id, &path, BuiltinShadowMode::Other); | ||
538 | match idx { | ||
539 | None => { | ||
540 | let value = to_value_ns(module_def)?; | ||
541 | Some(ResolveValueResult::ValueNs(value)) | ||
542 | } | ||
543 | Some(idx) => { | ||
544 | let ty = match module_def.take_types()? { | ||
545 | ModuleDefId::AdtId(it) => TypeNs::AdtId(it), | ||
546 | ModuleDefId::TraitId(it) => TypeNs::TraitId(it), | ||
547 | ModuleDefId::TypeAliasId(it) => TypeNs::TypeAliasId(it), | ||
548 | ModuleDefId::BuiltinType(it) => TypeNs::BuiltinType(it), | ||
549 | |||
550 | ModuleDefId::ModuleId(_) | ||
551 | | ModuleDefId::FunctionId(_) | ||
552 | | ModuleDefId::EnumVariantId(_) | ||
553 | | ModuleDefId::ConstId(_) | ||
554 | | ModuleDefId::StaticId(_) => return None, | ||
555 | }; | ||
556 | Some(ResolveValueResult::Partial(ty, idx)) | ||
557 | } | ||
558 | } | ||
559 | } | ||
560 | |||
561 | fn resolve_path_in_type_ns( | ||
562 | &self, | ||
563 | db: &dyn DefDatabase, | ||
564 | path: &ModPath, | ||
565 | ) -> Option<(TypeNs, Option<usize>)> { | ||
566 | let (module_def, idx) = | ||
567 | self.crate_def_map.resolve_path(db, self.module_id, &path, BuiltinShadowMode::Other); | ||
568 | let res = to_type_ns(module_def)?; | ||
569 | Some((res, idx)) | ||
570 | } | ||
571 | } | ||
572 | |||
573 | fn to_value_ns(per_ns: PerNs) -> Option<ValueNs> { | ||
574 | let res = match per_ns.take_values()? { | ||
575 | ModuleDefId::FunctionId(it) => ValueNs::FunctionId(it), | ||
576 | ModuleDefId::AdtId(AdtId::StructId(it)) => ValueNs::StructId(it), | ||
577 | ModuleDefId::EnumVariantId(it) => ValueNs::EnumVariantId(it), | ||
578 | ModuleDefId::ConstId(it) => ValueNs::ConstId(it), | ||
579 | ModuleDefId::StaticId(it) => ValueNs::StaticId(it), | ||
580 | |||
581 | ModuleDefId::AdtId(AdtId::EnumId(_)) | ||
582 | | ModuleDefId::AdtId(AdtId::UnionId(_)) | ||
583 | | ModuleDefId::TraitId(_) | ||
584 | | ModuleDefId::TypeAliasId(_) | ||
585 | | ModuleDefId::BuiltinType(_) | ||
586 | | ModuleDefId::ModuleId(_) => return None, | ||
587 | }; | ||
588 | Some(res) | ||
589 | } | ||
590 | |||
591 | fn to_type_ns(per_ns: PerNs) -> Option<TypeNs> { | ||
592 | let res = match per_ns.take_types()? { | ||
593 | ModuleDefId::AdtId(it) => TypeNs::AdtId(it), | ||
594 | ModuleDefId::EnumVariantId(it) => TypeNs::EnumVariantId(it), | ||
595 | |||
596 | ModuleDefId::TypeAliasId(it) => TypeNs::TypeAliasId(it), | ||
597 | ModuleDefId::BuiltinType(it) => TypeNs::BuiltinType(it), | ||
598 | |||
599 | ModuleDefId::TraitId(it) => TypeNs::TraitId(it), | ||
600 | |||
601 | ModuleDefId::FunctionId(_) | ||
602 | | ModuleDefId::ConstId(_) | ||
603 | | ModuleDefId::StaticId(_) | ||
604 | | ModuleDefId::ModuleId(_) => return None, | ||
605 | }; | ||
606 | Some(res) | ||
607 | } | ||
608 | |||
613 | pub trait HasResolver: Copy { | 609 | pub trait HasResolver: Copy { |
614 | /// Builds a resolver for type references inside this def. | 610 | /// Builds a resolver for type references inside this def. |
615 | fn resolver(self, db: &dyn DefDatabase) -> Resolver; | 611 | fn resolver(self, db: &dyn DefDatabase) -> Resolver; |
@@ -617,7 +613,7 @@ pub trait HasResolver: Copy { | |||
617 | 613 | ||
618 | impl HasResolver for ModuleId { | 614 | impl HasResolver for ModuleId { |
619 | fn resolver(self, db: &dyn DefDatabase) -> Resolver { | 615 | fn resolver(self, db: &dyn DefDatabase) -> Resolver { |
620 | let def_map = db.crate_def_map(self.krate); | 616 | let def_map = self.def_map(db); |
621 | Resolver::default().push_module_scope(def_map, self.local_id) | 617 | Resolver::default().push_module_scope(def_map, self.local_id) |
622 | } | 618 | } |
623 | } | 619 | } |