aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_hir/src/code_model.rs
diff options
context:
space:
mode:
Diffstat (limited to 'crates/ra_hir/src/code_model.rs')
-rw-r--r--crates/ra_hir/src/code_model.rs53
1 files changed, 7 insertions, 46 deletions
diff --git a/crates/ra_hir/src/code_model.rs b/crates/ra_hir/src/code_model.rs
index 821f919d4..9930cff66 100644
--- a/crates/ra_hir/src/code_model.rs
+++ b/crates/ra_hir/src/code_model.rs
@@ -9,7 +9,7 @@ use hir_def::{
9 builtin_type::BuiltinType, 9 builtin_type::BuiltinType,
10 docs::Documentation, 10 docs::Documentation,
11 per_ns::PerNs, 11 per_ns::PerNs,
12 resolver::{HasResolver, TypeNs}, 12 resolver::HasResolver,
13 type_ref::{Mutability, TypeRef}, 13 type_ref::{Mutability, TypeRef},
14 AdtId, AstItemDef, ConstId, ContainerId, DefWithBodyId, EnumId, FunctionId, GenericDefId, 14 AdtId, AstItemDef, ConstId, ContainerId, DefWithBodyId, EnumId, FunctionId, GenericDefId,
15 HasModule, ImplId, LocalEnumVariantId, LocalImportId, LocalModuleId, LocalStructFieldId, 15 HasModule, ImplId, LocalEnumVariantId, LocalImportId, LocalModuleId, LocalStructFieldId,
@@ -28,8 +28,8 @@ use crate::{
28 expr::{BindingAnnotation, Body, BodySourceMap, ExprValidator, Pat, PatId}, 28 expr::{BindingAnnotation, Body, BodySourceMap, ExprValidator, Pat, PatId},
29 ty::display::HirFormatter, 29 ty::display::HirFormatter,
30 ty::{ 30 ty::{
31 self, InEnvironment, InferenceResult, Namespace, TraitEnvironment, TraitRef, Ty, TypeCtor, 31 self, utils::all_super_traits, InEnvironment, InferenceResult, Namespace, TraitEnvironment,
32 TypeWalk, 32 TraitRef, Ty, TypeCtor, TypeWalk,
33 }, 33 },
34 CallableDef, Either, HirDisplay, Name, Source, 34 CallableDef, Either, HirDisplay, Name, Source,
35}; 35};
@@ -740,48 +740,6 @@ impl Trait {
740 db.trait_data(self.id).items.iter().map(|it| (*it).into()).collect() 740 db.trait_data(self.id).items.iter().map(|it| (*it).into()).collect()
741 } 741 }
742 742
743 fn direct_super_traits(self, db: &impl HirDatabase) -> Vec<Trait> {
744 let resolver = self.id.resolver(db);
745 // returning the iterator directly doesn't easily work because of
746 // lifetime problems, but since there usually shouldn't be more than a
747 // few direct traits this should be fine (we could even use some kind of
748 // SmallVec if performance is a concern)
749 db.generic_params(self.id.into())
750 .where_predicates
751 .iter()
752 .filter_map(|pred| match &pred.type_ref {
753 TypeRef::Path(p) if p.as_ident() == Some(&name::SELF_TYPE) => pred.bound.as_path(),
754 _ => None,
755 })
756 .filter_map(|path| match resolver.resolve_path_in_type_ns_fully(db, path) {
757 Some(TypeNs::TraitId(t)) => Some(t),
758 _ => None,
759 })
760 .map(Trait::from)
761 .collect()
762 }
763
764 /// Returns an iterator over the whole super trait hierarchy (including the
765 /// trait itself).
766 pub fn all_super_traits(self, db: &impl HirDatabase) -> Vec<Trait> {
767 // we need to take care a bit here to avoid infinite loops in case of cycles
768 // (i.e. if we have `trait A: B; trait B: A;`)
769 let mut result = vec![self];
770 let mut i = 0;
771 while i < result.len() {
772 let t = result[i];
773 // yeah this is quadratic, but trait hierarchies should be flat
774 // enough that this doesn't matter
775 for tt in t.direct_super_traits(db) {
776 if !result.contains(&tt) {
777 result.push(tt);
778 }
779 }
780 i += 1;
781 }
782 result
783 }
784
785 pub fn associated_type_by_name(self, db: &impl DefDatabase, name: &Name) -> Option<TypeAlias> { 743 pub fn associated_type_by_name(self, db: &impl DefDatabase, name: &Name) -> Option<TypeAlias> {
786 let trait_data = db.trait_data(self.id); 744 let trait_data = db.trait_data(self.id);
787 let res = 745 let res =
@@ -794,7 +752,10 @@ impl Trait {
794 db: &impl HirDatabase, 752 db: &impl HirDatabase,
795 name: &Name, 753 name: &Name,
796 ) -> Option<TypeAlias> { 754 ) -> Option<TypeAlias> {
797 self.all_super_traits(db).into_iter().find_map(|t| t.associated_type_by_name(db, name)) 755 all_super_traits(db, self.id)
756 .into_iter()
757 .map(Trait::from)
758 .find_map(|t| t.associated_type_by_name(db, name))
798 } 759 }
799 760
800 pub fn trait_ref(self, db: &impl HirDatabase) -> TraitRef { 761 pub fn trait_ref(self, db: &impl HirDatabase) -> TraitRef {