diff options
Diffstat (limited to 'crates/ra_hir/src/code_model.rs')
-rw-r--r-- | crates/ra_hir/src/code_model.rs | 61 |
1 files changed, 2 insertions, 59 deletions
diff --git a/crates/ra_hir/src/code_model.rs b/crates/ra_hir/src/code_model.rs index 821f919d4..9578c20b0 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, |
@@ -737,64 +737,7 @@ impl Trait { | |||
737 | } | 737 | } |
738 | 738 | ||
739 | pub fn items(self, db: &impl DefDatabase) -> Vec<AssocItem> { | 739 | pub fn items(self, db: &impl DefDatabase) -> Vec<AssocItem> { |
740 | db.trait_data(self.id).items.iter().map(|it| (*it).into()).collect() | 740 | db.trait_data(self.id).items.iter().map(|(_name, it)| (*it).into()).collect() |
741 | } | ||
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> { | ||
786 | let trait_data = db.trait_data(self.id); | ||
787 | let res = | ||
788 | trait_data.associated_types().map(TypeAlias::from).find(|t| &t.name(db) == name)?; | ||
789 | Some(res) | ||
790 | } | ||
791 | |||
792 | pub fn associated_type_by_name_including_super_traits( | ||
793 | self, | ||
794 | db: &impl HirDatabase, | ||
795 | name: &Name, | ||
796 | ) -> Option<TypeAlias> { | ||
797 | self.all_super_traits(db).into_iter().find_map(|t| t.associated_type_by_name(db, name)) | ||
798 | } | 741 | } |
799 | 742 | ||
800 | pub fn trait_ref(self, db: &impl HirDatabase) -> TraitRef { | 743 | pub fn trait_ref(self, db: &impl HirDatabase) -> TraitRef { |