diff options
Diffstat (limited to 'crates/ra_hir_ty/src')
-rw-r--r-- | crates/ra_hir_ty/src/lib.rs | 52 |
1 files changed, 52 insertions, 0 deletions
diff --git a/crates/ra_hir_ty/src/lib.rs b/crates/ra_hir_ty/src/lib.rs index 9d4d6aaa4..25ab9d872 100644 --- a/crates/ra_hir_ty/src/lib.rs +++ b/crates/ra_hir_ty/src/lib.rs | |||
@@ -877,6 +877,58 @@ impl Ty { | |||
877 | _ => None, | 877 | _ => None, |
878 | } | 878 | } |
879 | } | 879 | } |
880 | |||
881 | pub fn impl_trait_ref(&self, db: &dyn HirDatabase) -> Option<TraitRef> { | ||
882 | match self { | ||
883 | Ty::Opaque(opaque_ty) => { | ||
884 | let predicates = match opaque_ty.opaque_ty_id { | ||
885 | OpaqueTyId::ReturnTypeImplTrait(func, idx) => { | ||
886 | db.return_type_impl_traits(func).map(|it| { | ||
887 | let data = (*it) | ||
888 | .as_ref() | ||
889 | .map(|rpit| rpit.impl_traits[idx as usize].bounds.clone()); | ||
890 | data.clone().subst(&opaque_ty.parameters) | ||
891 | }) | ||
892 | } | ||
893 | }; | ||
894 | |||
895 | predicates.and_then(|it| { | ||
896 | it.value.iter().find_map(|pred| match pred { | ||
897 | GenericPredicate::Implemented(tr) => Some(tr.clone()), | ||
898 | _ => None, | ||
899 | }) | ||
900 | }) | ||
901 | } | ||
902 | Ty::Placeholder(id) => { | ||
903 | let generic_params = db.generic_params(id.parent); | ||
904 | let param_data = &generic_params.types[id.local_id]; | ||
905 | match param_data.provenance { | ||
906 | hir_def::generics::TypeParamProvenance::ArgumentImplTrait => db | ||
907 | .generic_predicates_for_param(*id) | ||
908 | .into_iter() | ||
909 | .map(|pred| pred.value.clone()) | ||
910 | .find_map(|pred| match pred { | ||
911 | GenericPredicate::Implemented(tr) => Some(tr.clone()), | ||
912 | _ => None, | ||
913 | }), | ||
914 | _ => None, | ||
915 | } | ||
916 | } | ||
917 | _ => None, | ||
918 | } | ||
919 | } | ||
920 | |||
921 | pub fn associated_type_parent_trait(&self, db: &dyn HirDatabase) -> Option<TraitId> { | ||
922 | match self { | ||
923 | Ty::Apply(ApplicationTy { ctor: TypeCtor::AssociatedType(type_alias_id), .. }) => { | ||
924 | match type_alias_id.lookup(db.upcast()).container { | ||
925 | AssocContainerId::TraitId(trait_id) => Some(trait_id), | ||
926 | _ => None, | ||
927 | } | ||
928 | } | ||
929 | _ => None, | ||
930 | } | ||
931 | } | ||
880 | } | 932 | } |
881 | 933 | ||
882 | /// This allows walking structures that contain types to do something with those | 934 | /// This allows walking structures that contain types to do something with those |