aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_hir_def/src/resolver.rs
diff options
context:
space:
mode:
Diffstat (limited to 'crates/ra_hir_def/src/resolver.rs')
-rw-r--r--crates/ra_hir_def/src/resolver.rs101
1 files changed, 46 insertions, 55 deletions
diff --git a/crates/ra_hir_def/src/resolver.rs b/crates/ra_hir_def/src/resolver.rs
index 7b5c3ec06..95b3c926d 100644
--- a/crates/ra_hir_def/src/resolver.rs
+++ b/crates/ra_hir_def/src/resolver.rs
@@ -11,14 +11,15 @@ use rustc_hash::FxHashSet;
11use crate::{ 11use crate::{
12 body::scope::{ExprScopes, ScopeId}, 12 body::scope::{ExprScopes, ScopeId},
13 builtin_type::BuiltinType, 13 builtin_type::BuiltinType,
14 db::DefDatabase2, 14 db::DefDatabase,
15 expr::{ExprId, PatId}, 15 expr::{ExprId, PatId},
16 generics::GenericParams, 16 generics::GenericParams,
17 nameres::{per_ns::PerNs, CrateDefMap}, 17 nameres::CrateDefMap,
18 path::{Path, PathKind}, 18 path::{Path, PathKind},
19 AdtId, AstItemDef, ConstId, ContainerId, CrateModuleId, DefWithBodyId, EnumId, EnumVariantId, 19 per_ns::PerNs,
20 FunctionId, GenericDefId, ImplId, Lookup, ModuleDefId, ModuleId, StaticId, StructId, TraitId, 20 AdtId, AstItemDef, ConstId, ContainerId, DefWithBodyId, EnumId, EnumVariantId, FunctionId,
21 TypeAliasId, 21 GenericDefId, HasModule, ImplId, LocalModuleId, Lookup, ModuleDefId, ModuleId, StaticId,
22 StructId, TraitId, TypeAliasId,
22}; 23};
23 24
24#[derive(Debug, Clone, Default)] 25#[derive(Debug, Clone, Default)]
@@ -28,20 +29,20 @@ pub struct Resolver {
28 29
29// FIXME how to store these best 30// FIXME how to store these best
30#[derive(Debug, Clone)] 31#[derive(Debug, Clone)]
31pub(crate) struct ModuleItemMap { 32struct ModuleItemMap {
32 crate_def_map: Arc<CrateDefMap>, 33 crate_def_map: Arc<CrateDefMap>,
33 module_id: CrateModuleId, 34 module_id: LocalModuleId,
34} 35}
35 36
36#[derive(Debug, Clone)] 37#[derive(Debug, Clone)]
37pub(crate) struct ExprScope { 38struct ExprScope {
38 owner: DefWithBodyId, 39 owner: DefWithBodyId,
39 expr_scopes: Arc<ExprScopes>, 40 expr_scopes: Arc<ExprScopes>,
40 scope_id: ScopeId, 41 scope_id: ScopeId,
41} 42}
42 43
43#[derive(Debug, Clone)] 44#[derive(Debug, Clone)]
44pub(crate) enum Scope { 45enum Scope {
45 /// All the items and imported names of a module 46 /// All the items and imported names of a module
46 ModuleScope(ModuleItemMap), 47 ModuleScope(ModuleItemMap),
47 /// Brings the generic parameters of an item into scope 48 /// Brings the generic parameters of an item into scope
@@ -87,7 +88,7 @@ pub enum ValueNs {
87 88
88impl Resolver { 89impl Resolver {
89 /// Resolve known trait from std, like `std::futures::Future` 90 /// Resolve known trait from std, like `std::futures::Future`
90 pub fn resolve_known_trait(&self, db: &impl DefDatabase2, path: &Path) -> Option<TraitId> { 91 pub fn resolve_known_trait(&self, db: &impl DefDatabase, path: &Path) -> Option<TraitId> {
91 let res = self.resolve_module_path(db, path).take_types()?; 92 let res = self.resolve_module_path(db, path).take_types()?;
92 match res { 93 match res {
93 ModuleDefId::TraitId(it) => Some(it), 94 ModuleDefId::TraitId(it) => Some(it),
@@ -96,7 +97,7 @@ impl Resolver {
96 } 97 }
97 98
98 /// Resolve known struct from std, like `std::boxed::Box` 99 /// Resolve known struct from std, like `std::boxed::Box`
99 pub fn resolve_known_struct(&self, db: &impl DefDatabase2, path: &Path) -> Option<StructId> { 100 pub fn resolve_known_struct(&self, db: &impl DefDatabase, path: &Path) -> Option<StructId> {
100 let res = self.resolve_module_path(db, path).take_types()?; 101 let res = self.resolve_module_path(db, path).take_types()?;
101 match res { 102 match res {
102 ModuleDefId::AdtId(AdtId::StructId(it)) => Some(it), 103 ModuleDefId::AdtId(AdtId::StructId(it)) => Some(it),
@@ -105,7 +106,7 @@ impl Resolver {
105 } 106 }
106 107
107 /// Resolve known enum from std, like `std::result::Result` 108 /// Resolve known enum from std, like `std::result::Result`
108 pub fn resolve_known_enum(&self, db: &impl DefDatabase2, path: &Path) -> Option<EnumId> { 109 pub fn resolve_known_enum(&self, db: &impl DefDatabase, path: &Path) -> Option<EnumId> {
109 let res = self.resolve_module_path(db, path).take_types()?; 110 let res = self.resolve_module_path(db, path).take_types()?;
110 match res { 111 match res {
111 ModuleDefId::AdtId(AdtId::EnumId(it)) => Some(it), 112 ModuleDefId::AdtId(AdtId::EnumId(it)) => Some(it),
@@ -114,7 +115,7 @@ impl Resolver {
114 } 115 }
115 116
116 /// pub only for source-binder 117 /// pub only for source-binder
117 pub fn resolve_module_path(&self, db: &impl DefDatabase2, path: &Path) -> PerNs { 118 pub fn resolve_module_path(&self, db: &impl DefDatabase, path: &Path) -> PerNs {
118 let (item_map, module) = match self.module() { 119 let (item_map, module) = match self.module() {
119 Some(it) => it, 120 Some(it) => it,
120 None => return PerNs::none(), 121 None => return PerNs::none(),
@@ -128,7 +129,7 @@ impl Resolver {
128 129
129 pub fn resolve_path_in_type_ns( 130 pub fn resolve_path_in_type_ns(
130 &self, 131 &self,
131 db: &impl DefDatabase2, 132 db: &impl DefDatabase,
132 path: &Path, 133 path: &Path,
133 ) -> Option<(TypeNs, Option<usize>)> { 134 ) -> Option<(TypeNs, Option<usize>)> {
134 if path.is_type_relative() { 135 if path.is_type_relative() {
@@ -184,7 +185,7 @@ impl Resolver {
184 185
185 pub fn resolve_path_in_type_ns_fully( 186 pub fn resolve_path_in_type_ns_fully(
186 &self, 187 &self,
187 db: &impl DefDatabase2, 188 db: &impl DefDatabase,
188 path: &Path, 189 path: &Path,
189 ) -> Option<TypeNs> { 190 ) -> Option<TypeNs> {
190 let (res, unresolved) = self.resolve_path_in_type_ns(db, path)?; 191 let (res, unresolved) = self.resolve_path_in_type_ns(db, path)?;
@@ -196,7 +197,7 @@ impl Resolver {
196 197
197 pub fn resolve_path_in_value_ns<'p>( 198 pub fn resolve_path_in_value_ns<'p>(
198 &self, 199 &self,
199 db: &impl DefDatabase2, 200 db: &impl DefDatabase,
200 path: &'p Path, 201 path: &'p Path,
201 ) -> Option<ResolveValueResult> { 202 ) -> Option<ResolveValueResult> {
202 if path.is_type_relative() { 203 if path.is_type_relative() {
@@ -296,7 +297,7 @@ impl Resolver {
296 297
297 pub fn resolve_path_in_value_ns_fully( 298 pub fn resolve_path_in_value_ns_fully(
298 &self, 299 &self,
299 db: &impl DefDatabase2, 300 db: &impl DefDatabase,
300 path: &Path, 301 path: &Path,
301 ) -> Option<ValueNs> { 302 ) -> Option<ValueNs> {
302 match self.resolve_path_in_value_ns(db, path)? { 303 match self.resolve_path_in_value_ns(db, path)? {
@@ -305,22 +306,22 @@ impl Resolver {
305 } 306 }
306 } 307 }
307 308
308 pub fn resolve_path_as_macro(&self, db: &impl DefDatabase2, path: &Path) -> Option<MacroDefId> { 309 pub fn resolve_path_as_macro(&self, db: &impl DefDatabase, path: &Path) -> Option<MacroDefId> {
309 let (item_map, module) = self.module()?; 310 let (item_map, module) = self.module()?;
310 item_map.resolve_path(db, module, path).0.get_macros() 311 item_map.resolve_path(db, module, path).0.take_macros()
311 } 312 }
312 313
313 pub fn process_all_names(&self, db: &impl DefDatabase2, f: &mut dyn FnMut(Name, ScopeDef)) { 314 pub fn process_all_names(&self, db: &impl DefDatabase, f: &mut dyn FnMut(Name, ScopeDef)) {
314 for scope in self.scopes.iter().rev() { 315 for scope in self.scopes.iter().rev() {
315 scope.process_names(db, f); 316 scope.process_names(db, f);
316 } 317 }
317 } 318 }
318 319
319 pub fn traits_in_scope(&self, db: &impl DefDatabase2) -> FxHashSet<TraitId> { 320 pub fn traits_in_scope(&self, db: &impl DefDatabase) -> FxHashSet<TraitId> {
320 let mut traits = FxHashSet::default(); 321 let mut traits = FxHashSet::default();
321 for scope in &self.scopes { 322 for scope in &self.scopes {
322 if let Scope::ModuleScope(m) = scope { 323 if let Scope::ModuleScope(m) = scope {
323 if let Some(prelude) = m.crate_def_map.prelude() { 324 if let Some(prelude) = m.crate_def_map.prelude {
324 let prelude_def_map = db.crate_def_map(prelude.krate); 325 let prelude_def_map = db.crate_def_map(prelude.krate);
325 traits.extend(prelude_def_map[prelude.module_id].scope.traits()); 326 traits.extend(prelude_def_map[prelude.module_id].scope.traits());
326 } 327 }
@@ -330,7 +331,7 @@ impl Resolver {
330 traits 331 traits
331 } 332 }
332 333
333 fn module(&self) -> Option<(&CrateDefMap, CrateModuleId)> { 334 fn module(&self) -> Option<(&CrateDefMap, LocalModuleId)> {
334 self.scopes.iter().rev().find_map(|scope| match scope { 335 self.scopes.iter().rev().find_map(|scope| match scope {
335 Scope::ModuleScope(m) => Some((&*m.crate_def_map, m.module_id)), 336 Scope::ModuleScope(m) => Some((&*m.crate_def_map, m.module_id)),
336 337
@@ -339,7 +340,7 @@ impl Resolver {
339 } 340 }
340 341
341 pub fn krate(&self) -> Option<CrateId> { 342 pub fn krate(&self) -> Option<CrateId> {
342 self.module().map(|t| t.0.krate()) 343 self.module().map(|t| t.0.krate)
343 } 344 }
344 345
345 pub fn where_predicates_in_scope<'a>( 346 pub fn where_predicates_in_scope<'a>(
@@ -378,7 +379,7 @@ pub enum ScopeDef {
378} 379}
379 380
380impl Scope { 381impl Scope {
381 fn process_names(&self, db: &impl DefDatabase2, f: &mut dyn FnMut(Name, ScopeDef)) { 382 fn process_names(&self, db: &impl DefDatabase, f: &mut dyn FnMut(Name, ScopeDef)) {
382 match self { 383 match self {
383 Scope::ModuleScope(m) => { 384 Scope::ModuleScope(m) => {
384 // FIXME: should we provide `self` here? 385 // FIXME: should we provide `self` here?
@@ -394,10 +395,10 @@ impl Scope {
394 m.crate_def_map[m.module_id].scope.legacy_macros().for_each(|(name, macro_)| { 395 m.crate_def_map[m.module_id].scope.legacy_macros().for_each(|(name, macro_)| {
395 f(name.clone(), ScopeDef::PerNs(PerNs::macros(macro_))); 396 f(name.clone(), ScopeDef::PerNs(PerNs::macros(macro_)));
396 }); 397 });
397 m.crate_def_map.extern_prelude().iter().for_each(|(name, &def)| { 398 m.crate_def_map.extern_prelude.iter().for_each(|(name, &def)| {
398 f(name.clone(), ScopeDef::PerNs(PerNs::types(def.into()))); 399 f(name.clone(), ScopeDef::PerNs(PerNs::types(def.into())));
399 }); 400 });
400 if let Some(prelude) = m.crate_def_map.prelude() { 401 if let Some(prelude) = m.crate_def_map.prelude {
401 let prelude_def_map = db.crate_def_map(prelude.krate); 402 let prelude_def_map = db.crate_def_map(prelude.krate);
402 prelude_def_map[prelude.module_id].scope.entries().for_each(|(name, res)| { 403 prelude_def_map[prelude.module_id].scope.entries().for_each(|(name, res)| {
403 f(name.clone(), ScopeDef::PerNs(res.def)); 404 f(name.clone(), ScopeDef::PerNs(res.def));
@@ -425,17 +426,13 @@ impl Scope {
425} 426}
426 427
427// needs arbitrary_self_types to be a method... or maybe move to the def? 428// needs arbitrary_self_types to be a method... or maybe move to the def?
428pub fn resolver_for_expr( 429pub fn resolver_for_expr(db: &impl DefDatabase, owner: DefWithBodyId, expr_id: ExprId) -> Resolver {
429 db: &impl DefDatabase2,
430 owner: DefWithBodyId,
431 expr_id: ExprId,
432) -> Resolver {
433 let scopes = db.expr_scopes(owner); 430 let scopes = db.expr_scopes(owner);
434 resolver_for_scope(db, owner, scopes.scope_for(expr_id)) 431 resolver_for_scope(db, owner, scopes.scope_for(expr_id))
435} 432}
436 433
437pub fn resolver_for_scope( 434pub fn resolver_for_scope(
438 db: &impl DefDatabase2, 435 db: &impl DefDatabase,
439 owner: DefWithBodyId, 436 owner: DefWithBodyId,
440 scope_id: Option<ScopeId>, 437 scope_id: Option<ScopeId>,
441) -> Resolver { 438) -> Resolver {
@@ -454,7 +451,7 @@ impl Resolver {
454 self 451 self
455 } 452 }
456 453
457 fn push_generic_params_scope(self, db: &impl DefDatabase2, def: GenericDefId) -> Resolver { 454 fn push_generic_params_scope(self, db: &impl DefDatabase, def: GenericDefId) -> Resolver {
458 let params = db.generic_params(def); 455 let params = db.generic_params(def);
459 if params.params.is_empty() { 456 if params.params.is_empty() {
460 self 457 self
@@ -470,7 +467,7 @@ impl Resolver {
470 fn push_module_scope( 467 fn push_module_scope(
471 self, 468 self,
472 crate_def_map: Arc<CrateDefMap>, 469 crate_def_map: Arc<CrateDefMap>,
473 module_id: CrateModuleId, 470 module_id: LocalModuleId,
474 ) -> Resolver { 471 ) -> Resolver {
475 self.push_scope(Scope::ModuleScope(ModuleItemMap { crate_def_map, module_id })) 472 self.push_scope(Scope::ModuleScope(ModuleItemMap { crate_def_map, module_id }))
476 } 473 }
@@ -487,32 +484,26 @@ impl Resolver {
487 484
488pub trait HasResolver { 485pub trait HasResolver {
489 /// Builds a resolver for type references inside this def. 486 /// Builds a resolver for type references inside this def.
490 fn resolver(self, db: &impl DefDatabase2) -> Resolver; 487 fn resolver(self, db: &impl DefDatabase) -> Resolver;
491} 488}
492 489
493impl HasResolver for ModuleId { 490impl HasResolver for ModuleId {
494 fn resolver(self, db: &impl DefDatabase2) -> Resolver { 491 fn resolver(self, db: &impl DefDatabase) -> Resolver {
495 let def_map = db.crate_def_map(self.krate); 492 let def_map = db.crate_def_map(self.krate);
496 Resolver::default().push_module_scope(def_map, self.module_id) 493 Resolver::default().push_module_scope(def_map, self.module_id)
497 } 494 }
498} 495}
499 496
500impl HasResolver for TraitId { 497impl HasResolver for TraitId {
501 fn resolver(self, db: &impl DefDatabase2) -> Resolver { 498 fn resolver(self, db: &impl DefDatabase) -> Resolver {
502 self.module(db).resolver(db).push_generic_params_scope(db, self.into()) 499 self.module(db).resolver(db).push_generic_params_scope(db, self.into())
503 } 500 }
504} 501}
505 502
506impl<T: Into<AdtId>> HasResolver for T { 503impl<T: Into<AdtId>> HasResolver for T {
507 fn resolver(self, db: &impl DefDatabase2) -> Resolver { 504 fn resolver(self, db: &impl DefDatabase) -> Resolver {
508 let def = self.into(); 505 let def = self.into();
509 let module = match def { 506 def.module(db)
510 AdtId::StructId(it) => it.0.module(db),
511 AdtId::UnionId(it) => it.0.module(db),
512 AdtId::EnumId(it) => it.module(db),
513 };
514
515 module
516 .resolver(db) 507 .resolver(db)
517 .push_generic_params_scope(db, def.into()) 508 .push_generic_params_scope(db, def.into())
518 .push_scope(Scope::AdtScope(def)) 509 .push_scope(Scope::AdtScope(def))
@@ -520,13 +511,13 @@ impl<T: Into<AdtId>> HasResolver for T {
520} 511}
521 512
522impl HasResolver for FunctionId { 513impl HasResolver for FunctionId {
523 fn resolver(self, db: &impl DefDatabase2) -> Resolver { 514 fn resolver(self, db: &impl DefDatabase) -> Resolver {
524 self.lookup(db).container.resolver(db).push_generic_params_scope(db, self.into()) 515 self.lookup(db).container.resolver(db).push_generic_params_scope(db, self.into())
525 } 516 }
526} 517}
527 518
528impl HasResolver for DefWithBodyId { 519impl HasResolver for DefWithBodyId {
529 fn resolver(self, db: &impl DefDatabase2) -> Resolver { 520 fn resolver(self, db: &impl DefDatabase) -> Resolver {
530 match self { 521 match self {
531 DefWithBodyId::ConstId(c) => c.resolver(db), 522 DefWithBodyId::ConstId(c) => c.resolver(db),
532 DefWithBodyId::FunctionId(f) => f.resolver(db), 523 DefWithBodyId::FunctionId(f) => f.resolver(db),
@@ -536,25 +527,25 @@ impl HasResolver for DefWithBodyId {
536} 527}
537 528
538impl HasResolver for ConstId { 529impl HasResolver for ConstId {
539 fn resolver(self, db: &impl DefDatabase2) -> Resolver { 530 fn resolver(self, db: &impl DefDatabase) -> Resolver {
540 self.lookup(db).container.resolver(db) 531 self.lookup(db).container.resolver(db)
541 } 532 }
542} 533}
543 534
544impl HasResolver for StaticId { 535impl HasResolver for StaticId {
545 fn resolver(self, db: &impl DefDatabase2) -> Resolver { 536 fn resolver(self, db: &impl DefDatabase) -> Resolver {
546 self.module(db).resolver(db) 537 self.lookup(db).container.resolver(db)
547 } 538 }
548} 539}
549 540
550impl HasResolver for TypeAliasId { 541impl HasResolver for TypeAliasId {
551 fn resolver(self, db: &impl DefDatabase2) -> Resolver { 542 fn resolver(self, db: &impl DefDatabase) -> Resolver {
552 self.lookup(db).container.resolver(db).push_generic_params_scope(db, self.into()) 543 self.lookup(db).container.resolver(db).push_generic_params_scope(db, self.into())
553 } 544 }
554} 545}
555 546
556impl HasResolver for ContainerId { 547impl HasResolver for ContainerId {
557 fn resolver(self, db: &impl DefDatabase2) -> Resolver { 548 fn resolver(self, db: &impl DefDatabase) -> Resolver {
558 match self { 549 match self {
559 ContainerId::TraitId(it) => it.resolver(db), 550 ContainerId::TraitId(it) => it.resolver(db),
560 ContainerId::ImplId(it) => it.resolver(db), 551 ContainerId::ImplId(it) => it.resolver(db),
@@ -564,7 +555,7 @@ impl HasResolver for ContainerId {
564} 555}
565 556
566impl HasResolver for GenericDefId { 557impl HasResolver for GenericDefId {
567 fn resolver(self, db: &impl DefDatabase2) -> Resolver { 558 fn resolver(self, db: &impl DefDatabase) -> Resolver {
568 match self { 559 match self {
569 GenericDefId::FunctionId(inner) => inner.resolver(db), 560 GenericDefId::FunctionId(inner) => inner.resolver(db),
570 GenericDefId::AdtId(adt) => adt.resolver(db), 561 GenericDefId::AdtId(adt) => adt.resolver(db),
@@ -578,7 +569,7 @@ impl HasResolver for GenericDefId {
578} 569}
579 570
580impl HasResolver for ImplId { 571impl HasResolver for ImplId {
581 fn resolver(self, db: &impl DefDatabase2) -> Resolver { 572 fn resolver(self, db: &impl DefDatabase) -> Resolver {
582 self.module(db) 573 self.module(db)
583 .resolver(db) 574 .resolver(db)
584 .push_generic_params_scope(db, self.into()) 575 .push_generic_params_scope(db, self.into())