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.rs200
1 files changed, 85 insertions, 115 deletions
diff --git a/crates/ra_hir_def/src/resolver.rs b/crates/ra_hir_def/src/resolver.rs
index 840785baa..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, UnionId, 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>(
@@ -369,47 +370,6 @@ impl Resolver {
369 } 370 }
370} 371}
371 372
372impl Resolver {
373 pub(crate) fn push_scope(mut self, scope: Scope) -> Resolver {
374 self.scopes.push(scope);
375 self
376 }
377
378 pub(crate) fn push_generic_params_scope(
379 self,
380 db: &impl DefDatabase2,
381 def: GenericDefId,
382 ) -> Resolver {
383 let params = db.generic_params(def);
384 if params.params.is_empty() {
385 self
386 } else {
387 self.push_scope(Scope::GenericParams { def, params })
388 }
389 }
390
391 pub(crate) fn push_impl_block_scope(self, impl_block: ImplId) -> Resolver {
392 self.push_scope(Scope::ImplBlockScope(impl_block))
393 }
394
395 pub(crate) fn push_module_scope(
396 self,
397 crate_def_map: Arc<CrateDefMap>,
398 module_id: CrateModuleId,
399 ) -> Resolver {
400 self.push_scope(Scope::ModuleScope(ModuleItemMap { crate_def_map, module_id }))
401 }
402
403 pub(crate) fn push_expr_scope(
404 self,
405 owner: DefWithBodyId,
406 expr_scopes: Arc<ExprScopes>,
407 scope_id: ScopeId,
408 ) -> Resolver {
409 self.push_scope(Scope::ExprScope(ExprScope { owner, expr_scopes, scope_id }))
410 }
411}
412
413pub enum ScopeDef { 373pub enum ScopeDef {
414 PerNs(PerNs), 374 PerNs(PerNs),
415 ImplSelfType(ImplId), 375 ImplSelfType(ImplId),
@@ -419,7 +379,7 @@ pub enum ScopeDef {
419} 379}
420 380
421impl Scope { 381impl Scope {
422 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)) {
423 match self { 383 match self {
424 Scope::ModuleScope(m) => { 384 Scope::ModuleScope(m) => {
425 // FIXME: should we provide `self` here? 385 // FIXME: should we provide `self` here?
@@ -435,10 +395,10 @@ impl Scope {
435 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_)| {
436 f(name.clone(), ScopeDef::PerNs(PerNs::macros(macro_))); 396 f(name.clone(), ScopeDef::PerNs(PerNs::macros(macro_)));
437 }); 397 });
438 m.crate_def_map.extern_prelude().iter().for_each(|(name, &def)| { 398 m.crate_def_map.extern_prelude.iter().for_each(|(name, &def)| {
439 f(name.clone(), ScopeDef::PerNs(PerNs::types(def.into()))); 399 f(name.clone(), ScopeDef::PerNs(PerNs::types(def.into())));
440 }); 400 });
441 if let Some(prelude) = m.crate_def_map.prelude() { 401 if let Some(prelude) = m.crate_def_map.prelude {
442 let prelude_def_map = db.crate_def_map(prelude.krate); 402 let prelude_def_map = db.crate_def_map(prelude.krate);
443 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)| {
444 f(name.clone(), ScopeDef::PerNs(res.def)); 404 f(name.clone(), ScopeDef::PerNs(res.def));
@@ -466,17 +426,13 @@ impl Scope {
466} 426}
467 427
468// 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?
469pub fn resolver_for_expr( 429pub fn resolver_for_expr(db: &impl DefDatabase, owner: DefWithBodyId, expr_id: ExprId) -> Resolver {
470 db: &impl DefDatabase2,
471 owner: DefWithBodyId,
472 expr_id: ExprId,
473) -> Resolver {
474 let scopes = db.expr_scopes(owner); 430 let scopes = db.expr_scopes(owner);
475 resolver_for_scope(db, owner, scopes.scope_for(expr_id)) 431 resolver_for_scope(db, owner, scopes.scope_for(expr_id))
476} 432}
477 433
478pub fn resolver_for_scope( 434pub fn resolver_for_scope(
479 db: &impl DefDatabase2, 435 db: &impl DefDatabase,
480 owner: DefWithBodyId, 436 owner: DefWithBodyId,
481 scope_id: Option<ScopeId>, 437 scope_id: Option<ScopeId>,
482) -> Resolver { 438) -> Resolver {
@@ -489,65 +445,79 @@ pub fn resolver_for_scope(
489 r 445 r
490} 446}
491 447
448impl Resolver {
449 fn push_scope(mut self, scope: Scope) -> Resolver {
450 self.scopes.push(scope);
451 self
452 }
453
454 fn push_generic_params_scope(self, db: &impl DefDatabase, def: GenericDefId) -> Resolver {
455 let params = db.generic_params(def);
456 if params.params.is_empty() {
457 self
458 } else {
459 self.push_scope(Scope::GenericParams { def, params })
460 }
461 }
462
463 fn push_impl_block_scope(self, impl_block: ImplId) -> Resolver {
464 self.push_scope(Scope::ImplBlockScope(impl_block))
465 }
466
467 fn push_module_scope(
468 self,
469 crate_def_map: Arc<CrateDefMap>,
470 module_id: LocalModuleId,
471 ) -> Resolver {
472 self.push_scope(Scope::ModuleScope(ModuleItemMap { crate_def_map, module_id }))
473 }
474
475 fn push_expr_scope(
476 self,
477 owner: DefWithBodyId,
478 expr_scopes: Arc<ExprScopes>,
479 scope_id: ScopeId,
480 ) -> Resolver {
481 self.push_scope(Scope::ExprScope(ExprScope { owner, expr_scopes, scope_id }))
482 }
483}
484
492pub trait HasResolver { 485pub trait HasResolver {
493 /// Builds a resolver for type references inside this def. 486 /// Builds a resolver for type references inside this def.
494 fn resolver(self, db: &impl DefDatabase2) -> Resolver; 487 fn resolver(self, db: &impl DefDatabase) -> Resolver;
495} 488}
496 489
497impl HasResolver for ModuleId { 490impl HasResolver for ModuleId {
498 fn resolver(self, db: &impl DefDatabase2) -> Resolver { 491 fn resolver(self, db: &impl DefDatabase) -> Resolver {
499 let def_map = db.crate_def_map(self.krate); 492 let def_map = db.crate_def_map(self.krate);
500 Resolver::default().push_module_scope(def_map, self.module_id) 493 Resolver::default().push_module_scope(def_map, self.module_id)
501 } 494 }
502} 495}
503 496
504impl HasResolver for TraitId { 497impl HasResolver for TraitId {
505 fn resolver(self, db: &impl DefDatabase2) -> Resolver { 498 fn resolver(self, db: &impl DefDatabase) -> Resolver {
506 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())
507 } 500 }
508} 501}
509 502
510impl HasResolver for AdtId { 503impl<T: Into<AdtId>> HasResolver for T {
511 fn resolver(self, db: &impl DefDatabase2) -> Resolver { 504 fn resolver(self, db: &impl DefDatabase) -> Resolver {
512 let module = match self { 505 let def = self.into();
513 AdtId::StructId(it) => it.0.module(db), 506 def.module(db)
514 AdtId::UnionId(it) => it.0.module(db),
515 AdtId::EnumId(it) => it.module(db),
516 };
517
518 module
519 .resolver(db) 507 .resolver(db)
520 .push_generic_params_scope(db, self.into()) 508 .push_generic_params_scope(db, def.into())
521 .push_scope(Scope::AdtScope(self.into())) 509 .push_scope(Scope::AdtScope(def))
522 }
523}
524
525impl HasResolver for StructId {
526 fn resolver(self, db: &impl DefDatabase2) -> Resolver {
527 AdtId::from(self).resolver(db)
528 }
529}
530
531impl HasResolver for UnionId {
532 fn resolver(self, db: &impl DefDatabase2) -> Resolver {
533 AdtId::from(self).resolver(db)
534 }
535}
536
537impl HasResolver for EnumId {
538 fn resolver(self, db: &impl DefDatabase2) -> Resolver {
539 AdtId::from(self).resolver(db)
540 } 510 }
541} 511}
542 512
543impl HasResolver for FunctionId { 513impl HasResolver for FunctionId {
544 fn resolver(self, db: &impl DefDatabase2) -> Resolver { 514 fn resolver(self, db: &impl DefDatabase) -> Resolver {
545 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())
546 } 516 }
547} 517}
548 518
549impl HasResolver for DefWithBodyId { 519impl HasResolver for DefWithBodyId {
550 fn resolver(self, db: &impl DefDatabase2) -> Resolver { 520 fn resolver(self, db: &impl DefDatabase) -> Resolver {
551 match self { 521 match self {
552 DefWithBodyId::ConstId(c) => c.resolver(db), 522 DefWithBodyId::ConstId(c) => c.resolver(db),
553 DefWithBodyId::FunctionId(f) => f.resolver(db), 523 DefWithBodyId::FunctionId(f) => f.resolver(db),
@@ -557,25 +527,25 @@ impl HasResolver for DefWithBodyId {
557} 527}
558 528
559impl HasResolver for ConstId { 529impl HasResolver for ConstId {
560 fn resolver(self, db: &impl DefDatabase2) -> Resolver { 530 fn resolver(self, db: &impl DefDatabase) -> Resolver {
561 self.lookup(db).container.resolver(db) 531 self.lookup(db).container.resolver(db)
562 } 532 }
563} 533}
564 534
565impl HasResolver for StaticId { 535impl HasResolver for StaticId {
566 fn resolver(self, db: &impl DefDatabase2) -> Resolver { 536 fn resolver(self, db: &impl DefDatabase) -> Resolver {
567 self.module(db).resolver(db) 537 self.lookup(db).container.resolver(db)
568 } 538 }
569} 539}
570 540
571impl HasResolver for TypeAliasId { 541impl HasResolver for TypeAliasId {
572 fn resolver(self, db: &impl DefDatabase2) -> Resolver { 542 fn resolver(self, db: &impl DefDatabase) -> Resolver {
573 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())
574 } 544 }
575} 545}
576 546
577impl HasResolver for ContainerId { 547impl HasResolver for ContainerId {
578 fn resolver(self, db: &impl DefDatabase2) -> Resolver { 548 fn resolver(self, db: &impl DefDatabase) -> Resolver {
579 match self { 549 match self {
580 ContainerId::TraitId(it) => it.resolver(db), 550 ContainerId::TraitId(it) => it.resolver(db),
581 ContainerId::ImplId(it) => it.resolver(db), 551 ContainerId::ImplId(it) => it.resolver(db),
@@ -585,7 +555,7 @@ impl HasResolver for ContainerId {
585} 555}
586 556
587impl HasResolver for GenericDefId { 557impl HasResolver for GenericDefId {
588 fn resolver(self, db: &impl DefDatabase2) -> Resolver { 558 fn resolver(self, db: &impl DefDatabase) -> Resolver {
589 match self { 559 match self {
590 GenericDefId::FunctionId(inner) => inner.resolver(db), 560 GenericDefId::FunctionId(inner) => inner.resolver(db),
591 GenericDefId::AdtId(adt) => adt.resolver(db), 561 GenericDefId::AdtId(adt) => adt.resolver(db),
@@ -599,7 +569,7 @@ impl HasResolver for GenericDefId {
599} 569}
600 570
601impl HasResolver for ImplId { 571impl HasResolver for ImplId {
602 fn resolver(self, db: &impl DefDatabase2) -> Resolver { 572 fn resolver(self, db: &impl DefDatabase) -> Resolver {
603 self.module(db) 573 self.module(db)
604 .resolver(db) 574 .resolver(db)
605 .push_generic_params_scope(db, self.into()) 575 .push_generic_params_scope(db, self.into())