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.rs75
1 files changed, 36 insertions, 39 deletions
diff --git a/crates/ra_hir_def/src/resolver.rs b/crates/ra_hir_def/src/resolver.rs
index 7b5c3ec06..b56de44dd 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, ImplId, LocalModuleId, Lookup, ModuleDefId, ModuleId, StaticId, StructId,
22 TraitId, TypeAliasId,
22}; 23};
23 24
24#[derive(Debug, Clone, Default)] 25#[derive(Debug, Clone, Default)]
@@ -30,7 +31,7 @@ pub struct Resolver {
30#[derive(Debug, Clone)] 31#[derive(Debug, Clone)]
31pub(crate) struct ModuleItemMap { 32pub(crate) struct 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)]
@@ -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,18 +306,18 @@ 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.get_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 {
@@ -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
@@ -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?
@@ -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,24 +484,24 @@ 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 let module = match def {
510 AdtId::StructId(it) => it.0.module(db), 507 AdtId::StructId(it) => it.0.module(db),
@@ -520,13 +517,13 @@ impl<T: Into<AdtId>> HasResolver for T {
520} 517}
521 518
522impl HasResolver for FunctionId { 519impl HasResolver for FunctionId {
523 fn resolver(self, db: &impl DefDatabase2) -> Resolver { 520 fn resolver(self, db: &impl DefDatabase) -> Resolver {
524 self.lookup(db).container.resolver(db).push_generic_params_scope(db, self.into()) 521 self.lookup(db).container.resolver(db).push_generic_params_scope(db, self.into())
525 } 522 }
526} 523}
527 524
528impl HasResolver for DefWithBodyId { 525impl HasResolver for DefWithBodyId {
529 fn resolver(self, db: &impl DefDatabase2) -> Resolver { 526 fn resolver(self, db: &impl DefDatabase) -> Resolver {
530 match self { 527 match self {
531 DefWithBodyId::ConstId(c) => c.resolver(db), 528 DefWithBodyId::ConstId(c) => c.resolver(db),
532 DefWithBodyId::FunctionId(f) => f.resolver(db), 529 DefWithBodyId::FunctionId(f) => f.resolver(db),
@@ -536,25 +533,25 @@ impl HasResolver for DefWithBodyId {
536} 533}
537 534
538impl HasResolver for ConstId { 535impl HasResolver for ConstId {
539 fn resolver(self, db: &impl DefDatabase2) -> Resolver { 536 fn resolver(self, db: &impl DefDatabase) -> Resolver {
540 self.lookup(db).container.resolver(db) 537 self.lookup(db).container.resolver(db)
541 } 538 }
542} 539}
543 540
544impl HasResolver for StaticId { 541impl HasResolver for StaticId {
545 fn resolver(self, db: &impl DefDatabase2) -> Resolver { 542 fn resolver(self, db: &impl DefDatabase) -> Resolver {
546 self.module(db).resolver(db) 543 self.module(db).resolver(db)
547 } 544 }
548} 545}
549 546
550impl HasResolver for TypeAliasId { 547impl HasResolver for TypeAliasId {
551 fn resolver(self, db: &impl DefDatabase2) -> Resolver { 548 fn resolver(self, db: &impl DefDatabase) -> Resolver {
552 self.lookup(db).container.resolver(db).push_generic_params_scope(db, self.into()) 549 self.lookup(db).container.resolver(db).push_generic_params_scope(db, self.into())
553 } 550 }
554} 551}
555 552
556impl HasResolver for ContainerId { 553impl HasResolver for ContainerId {
557 fn resolver(self, db: &impl DefDatabase2) -> Resolver { 554 fn resolver(self, db: &impl DefDatabase) -> Resolver {
558 match self { 555 match self {
559 ContainerId::TraitId(it) => it.resolver(db), 556 ContainerId::TraitId(it) => it.resolver(db),
560 ContainerId::ImplId(it) => it.resolver(db), 557 ContainerId::ImplId(it) => it.resolver(db),
@@ -564,7 +561,7 @@ impl HasResolver for ContainerId {
564} 561}
565 562
566impl HasResolver for GenericDefId { 563impl HasResolver for GenericDefId {
567 fn resolver(self, db: &impl DefDatabase2) -> Resolver { 564 fn resolver(self, db: &impl DefDatabase) -> Resolver {
568 match self { 565 match self {
569 GenericDefId::FunctionId(inner) => inner.resolver(db), 566 GenericDefId::FunctionId(inner) => inner.resolver(db),
570 GenericDefId::AdtId(adt) => adt.resolver(db), 567 GenericDefId::AdtId(adt) => adt.resolver(db),
@@ -578,7 +575,7 @@ impl HasResolver for GenericDefId {
578} 575}
579 576
580impl HasResolver for ImplId { 577impl HasResolver for ImplId {
581 fn resolver(self, db: &impl DefDatabase2) -> Resolver { 578 fn resolver(self, db: &impl DefDatabase) -> Resolver {
582 self.module(db) 579 self.module(db)
583 .resolver(db) 580 .resolver(db)
584 .push_generic_params_scope(db, self.into()) 581 .push_generic_params_scope(db, self.into())