aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_hir/src/resolve.rs
diff options
context:
space:
mode:
authorSeivan Heidari <[email protected]>2019-11-21 00:11:41 +0000
committerSeivan Heidari <[email protected]>2019-11-21 00:11:41 +0000
commit358a1bcd708c622836723e5201b6de77cc9ff327 (patch)
treeaeff9c96a6059fa2b02e7c87ec88753bc7993d8d /crates/ra_hir/src/resolve.rs
parent1e2d090ab8a9bda18f148b894b7948eb05b976e6 (diff)
parent612a72fc4ea4376920f2a7da7b3c334227c1716c (diff)
Merge branch 'master' of https://github.com/rust-analyzer/rust-analyzer into feature/themes
Diffstat (limited to 'crates/ra_hir/src/resolve.rs')
-rw-r--r--crates/ra_hir/src/resolve.rs139
1 files changed, 124 insertions, 15 deletions
diff --git a/crates/ra_hir/src/resolve.rs b/crates/ra_hir/src/resolve.rs
index 79b92180a..eca8e0596 100644
--- a/crates/ra_hir/src/resolve.rs
+++ b/crates/ra_hir/src/resolve.rs
@@ -14,9 +14,9 @@ use crate::{
14 code_model::Crate, 14 code_model::Crate,
15 db::{DefDatabase, HirDatabase}, 15 db::{DefDatabase, HirDatabase},
16 expr::{ExprScopes, PatId, ScopeId}, 16 expr::{ExprScopes, PatId, ScopeId},
17 generics::GenericParams, 17 generics::{GenericParams, HasGenericParams},
18 Adt, Const, DefWithBody, Enum, EnumVariant, Function, ImplBlock, Local, MacroDef, ModuleDef, 18 Adt, Const, Container, DefWithBody, Enum, EnumVariant, Function, GenericDef, ImplBlock, Local,
19 PerNs, Static, Struct, Trait, TypeAlias, 19 MacroDef, Module, ModuleDef, PerNs, Static, Struct, Trait, TypeAlias,
20}; 20};
21 21
22#[derive(Debug, Clone, Default)] 22#[derive(Debug, Clone, Default)]
@@ -43,7 +43,7 @@ pub(crate) enum Scope {
43 /// All the items and imported names of a module 43 /// All the items and imported names of a module
44 ModuleScope(ModuleItemMap), 44 ModuleScope(ModuleItemMap),
45 /// Brings the generic parameters of an item into scope 45 /// Brings the generic parameters of an item into scope
46 GenericParams(Arc<GenericParams>), 46 GenericParams { def: GenericDef, params: Arc<GenericParams> },
47 /// Brings `Self` in `impl` block into scope 47 /// Brings `Self` in `impl` block into scope
48 ImplBlockScope(ImplBlock), 48 ImplBlockScope(ImplBlock),
49 /// Brings `Self` in enum, struct and union definitions into scope 49 /// Brings `Self` in enum, struct and union definitions into scope
@@ -141,9 +141,9 @@ impl Resolver {
141 for scope in self.scopes.iter().rev() { 141 for scope in self.scopes.iter().rev() {
142 match scope { 142 match scope {
143 Scope::ExprScope(_) => continue, 143 Scope::ExprScope(_) => continue,
144 Scope::GenericParams(_) | Scope::ImplBlockScope(_) if skip_to_mod => continue, 144 Scope::GenericParams { .. } | Scope::ImplBlockScope(_) if skip_to_mod => continue,
145 145
146 Scope::GenericParams(params) => { 146 Scope::GenericParams { params, .. } => {
147 if let Some(param) = params.find_by_name(first_name) { 147 if let Some(param) = params.find_by_name(first_name) {
148 let idx = if path.segments.len() == 1 { None } else { Some(1) }; 148 let idx = if path.segments.len() == 1 { None } else { Some(1) };
149 return Some((TypeNs::GenericParam(param.idx), idx)); 149 return Some((TypeNs::GenericParam(param.idx), idx));
@@ -212,7 +212,7 @@ impl Resolver {
212 match scope { 212 match scope {
213 Scope::AdtScope(_) 213 Scope::AdtScope(_)
214 | Scope::ExprScope(_) 214 | Scope::ExprScope(_)
215 | Scope::GenericParams(_) 215 | Scope::GenericParams { .. }
216 | Scope::ImplBlockScope(_) 216 | Scope::ImplBlockScope(_)
217 if skip_to_mod => 217 if skip_to_mod =>
218 { 218 {
@@ -232,13 +232,13 @@ impl Resolver {
232 } 232 }
233 Scope::ExprScope(_) => continue, 233 Scope::ExprScope(_) => continue,
234 234
235 Scope::GenericParams(params) if n_segments > 1 => { 235 Scope::GenericParams { params, .. } if n_segments > 1 => {
236 if let Some(param) = params.find_by_name(first_name) { 236 if let Some(param) = params.find_by_name(first_name) {
237 let ty = TypeNs::GenericParam(param.idx); 237 let ty = TypeNs::GenericParam(param.idx);
238 return Some(ResolveValueResult::Partial(ty, 1)); 238 return Some(ResolveValueResult::Partial(ty, 1));
239 } 239 }
240 } 240 }
241 Scope::GenericParams(_) => continue, 241 Scope::GenericParams { .. } => continue,
242 242
243 Scope::ImplBlockScope(impl_) if n_segments > 1 => { 243 Scope::ImplBlockScope(impl_) if n_segments > 1 => {
244 if first_name == &name::SELF_TYPE { 244 if first_name == &name::SELF_TYPE {
@@ -361,7 +361,7 @@ impl Resolver {
361 self.scopes 361 self.scopes
362 .iter() 362 .iter()
363 .filter_map(|scope| match scope { 363 .filter_map(|scope| match scope {
364 Scope::GenericParams(params) => Some(params), 364 Scope::GenericParams { params, .. } => Some(params),
365 _ => None, 365 _ => None,
366 }) 366 })
367 .flat_map(|params| params.where_predicates.iter()) 367 .flat_map(|params| params.where_predicates.iter())
@@ -369,7 +369,7 @@ impl Resolver {
369 369
370 pub(crate) fn generic_def(&self) -> Option<crate::generics::GenericDef> { 370 pub(crate) fn generic_def(&self) -> Option<crate::generics::GenericDef> {
371 self.scopes.iter().find_map(|scope| match scope { 371 self.scopes.iter().find_map(|scope| match scope {
372 Scope::GenericParams(params) => Some(params.def), 372 Scope::GenericParams { def, .. } => Some(*def),
373 _ => None, 373 _ => None,
374 }) 374 })
375 } 375 }
@@ -381,8 +381,17 @@ impl Resolver {
381 self 381 self
382 } 382 }
383 383
384 pub(crate) fn push_generic_params_scope(self, params: Arc<GenericParams>) -> Resolver { 384 pub(crate) fn push_generic_params_scope(
385 self.push_scope(Scope::GenericParams(params)) 385 self,
386 db: &impl DefDatabase,
387 def: GenericDef,
388 ) -> Resolver {
389 let params = def.generic_params(db);
390 if params.params.is_empty() {
391 self
392 } else {
393 self.push_scope(Scope::GenericParams { def, params })
394 }
386 } 395 }
387 396
388 pub(crate) fn push_impl_block_scope(self, impl_block: ImplBlock) -> Resolver { 397 pub(crate) fn push_impl_block_scope(self, impl_block: ImplBlock) -> Resolver {
@@ -457,8 +466,8 @@ impl Scope {
457 }); 466 });
458 } 467 }
459 } 468 }
460 Scope::GenericParams(gp) => { 469 Scope::GenericParams { params, .. } => {
461 for param in &gp.params { 470 for param in params.params.iter() {
462 f(param.name.clone(), ScopeDef::GenericParam(param.idx)) 471 f(param.name.clone(), ScopeDef::GenericParam(param.idx))
463 } 472 }
464 } 473 }
@@ -477,3 +486,103 @@ impl Scope {
477 } 486 }
478 } 487 }
479} 488}
489
490pub(crate) trait HasResolver {
491 /// Builds a resolver for type references inside this def.
492 fn resolver(self, db: &impl DefDatabase) -> Resolver;
493}
494
495impl HasResolver for Module {
496 fn resolver(self, db: &impl DefDatabase) -> Resolver {
497 let def_map = db.crate_def_map(self.id.krate);
498 Resolver::default().push_module_scope(def_map, self.id.module_id)
499 }
500}
501
502impl HasResolver for Trait {
503 fn resolver(self, db: &impl DefDatabase) -> Resolver {
504 self.module(db).resolver(db).push_generic_params_scope(db, self.into())
505 }
506}
507
508impl<T: Into<Adt>> HasResolver for T {
509 fn resolver(self, db: &impl DefDatabase) -> Resolver {
510 let def = self.into();
511 def.module(db)
512 .resolver(db)
513 .push_generic_params_scope(db, def.into())
514 .push_scope(Scope::AdtScope(def))
515 }
516}
517
518impl HasResolver for Function {
519 fn resolver(self, db: &impl DefDatabase) -> Resolver {
520 self.container(db)
521 .map(|c| c.resolver(db))
522 .unwrap_or_else(|| self.module(db).resolver(db))
523 .push_generic_params_scope(db, self.into())
524 }
525}
526
527impl HasResolver for DefWithBody {
528 fn resolver(self, db: &impl DefDatabase) -> Resolver {
529 match self {
530 DefWithBody::Const(c) => c.resolver(db),
531 DefWithBody::Function(f) => f.resolver(db),
532 DefWithBody::Static(s) => s.resolver(db),
533 }
534 }
535}
536
537impl HasResolver for Const {
538 fn resolver(self, db: &impl DefDatabase) -> Resolver {
539 self.container(db).map(|c| c.resolver(db)).unwrap_or_else(|| self.module(db).resolver(db))
540 }
541}
542
543impl HasResolver for Static {
544 fn resolver(self, db: &impl DefDatabase) -> Resolver {
545 self.module(db).resolver(db)
546 }
547}
548
549impl HasResolver for TypeAlias {
550 fn resolver(self, db: &impl DefDatabase) -> Resolver {
551 self.container(db)
552 .map(|ib| ib.resolver(db))
553 .unwrap_or_else(|| self.module(db).resolver(db))
554 .push_generic_params_scope(db, self.into())
555 }
556}
557
558impl HasResolver for Container {
559 fn resolver(self, db: &impl DefDatabase) -> Resolver {
560 match self {
561 Container::Trait(trait_) => trait_.resolver(db),
562 Container::ImplBlock(impl_block) => impl_block.resolver(db),
563 }
564 }
565}
566
567impl HasResolver for GenericDef {
568 fn resolver(self, db: &impl DefDatabase) -> crate::Resolver {
569 match self {
570 GenericDef::Function(inner) => inner.resolver(db),
571 GenericDef::Adt(adt) => adt.resolver(db),
572 GenericDef::Trait(inner) => inner.resolver(db),
573 GenericDef::TypeAlias(inner) => inner.resolver(db),
574 GenericDef::ImplBlock(inner) => inner.resolver(db),
575 GenericDef::EnumVariant(inner) => inner.parent_enum(db).resolver(db),
576 GenericDef::Const(inner) => inner.resolver(db),
577 }
578 }
579}
580
581impl HasResolver for ImplBlock {
582 fn resolver(self, db: &impl DefDatabase) -> Resolver {
583 self.module(db)
584 .resolver(db)
585 .push_generic_params_scope(db, self.into())
586 .push_impl_block_scope(self)
587 }
588}