diff options
author | Florian Diebold <[email protected]> | 2019-11-30 11:35:37 +0000 |
---|---|---|
committer | Florian Diebold <[email protected]> | 2019-11-30 11:57:32 +0000 |
commit | cf6809645e2327e20edd30eb535d4f06fa116b5c (patch) | |
tree | d39c0827865f5e82d82da94bc595580ad811502b /crates/ra_hir_ty/src/lower.rs | |
parent | 7cecd0f331419439417f98d92b839c9aaa06ed86 (diff) |
Handle cycles in impl types better
- impl Trait<Self> for S is allowed
- impl Trait for S<Self> is an invalid cycle, but we can add cycle recovery for
it in Salsa now
Diffstat (limited to 'crates/ra_hir_ty/src/lower.rs')
-rw-r--r-- | crates/ra_hir_ty/src/lower.rs | 35 |
1 files changed, 21 insertions, 14 deletions
diff --git a/crates/ra_hir_ty/src/lower.rs b/crates/ra_hir_ty/src/lower.rs index 091c60f4f..a646406f1 100644 --- a/crates/ra_hir_ty/src/lower.rs +++ b/crates/ra_hir_ty/src/lower.rs | |||
@@ -27,8 +27,8 @@ use crate::{ | |||
27 | all_super_traits, associated_type_by_name_including_super_traits, make_mut_slice, | 27 | all_super_traits, associated_type_by_name_including_super_traits, make_mut_slice, |
28 | variant_data, | 28 | variant_data, |
29 | }, | 29 | }, |
30 | FnSig, GenericPredicate, ImplTy, ProjectionPredicate, ProjectionTy, Substs, TraitEnvironment, | 30 | FnSig, GenericPredicate, ProjectionPredicate, ProjectionTy, Substs, TraitEnvironment, TraitRef, |
31 | TraitRef, Ty, TypeCtor, TypeWalk, | 31 | Ty, TypeCtor, TypeWalk, |
32 | }; | 32 | }; |
33 | 33 | ||
34 | impl Ty { | 34 | impl Ty { |
@@ -179,7 +179,7 @@ impl Ty { | |||
179 | let name = resolved_segment.name.clone(); | 179 | let name = resolved_segment.name.clone(); |
180 | Ty::Param { idx, name } | 180 | Ty::Param { idx, name } |
181 | } | 181 | } |
182 | TypeNs::SelfType(impl_id) => db.impl_ty(impl_id).self_type().clone(), | 182 | TypeNs::SelfType(impl_id) => db.impl_self_ty(impl_id).clone(), |
183 | TypeNs::AdtSelfType(adt) => db.ty(adt.into()), | 183 | TypeNs::AdtSelfType(adt) => db.ty(adt.into()), |
184 | 184 | ||
185 | TypeNs::AdtId(it) => Ty::from_hir_path_inner(db, resolver, resolved_segment, it.into()), | 185 | TypeNs::AdtId(it) => Ty::from_hir_path_inner(db, resolver, resolved_segment, it.into()), |
@@ -743,17 +743,24 @@ pub(crate) fn value_ty_query(db: &impl HirDatabase, def: ValueTyDefId) -> Ty { | |||
743 | } | 743 | } |
744 | } | 744 | } |
745 | 745 | ||
746 | pub(crate) fn impl_ty_query(db: &impl HirDatabase, impl_id: ImplId) -> ImplTy { | 746 | pub(crate) fn impl_self_ty_query(db: &impl HirDatabase, impl_id: ImplId) -> Ty { |
747 | let impl_data = db.impl_data(impl_id); | 747 | let impl_data = db.impl_data(impl_id); |
748 | let resolver = impl_id.resolver(db); | 748 | let resolver = impl_id.resolver(db); |
749 | let self_ty = Ty::from_hir(db, &resolver, &impl_data.target_type); | 749 | Ty::from_hir(db, &resolver, &impl_data.target_type) |
750 | match impl_data.target_trait.as_ref() { | 750 | } |
751 | Some(trait_ref) => { | 751 | |
752 | match TraitRef::from_hir(db, &resolver, trait_ref, Some(self_ty.clone())) { | 752 | pub(crate) fn impl_self_ty_recover( |
753 | Some(it) => ImplTy::TraitRef(it), | 753 | _db: &impl HirDatabase, |
754 | None => ImplTy::Inherent(self_ty), | 754 | _cycle: &[String], |
755 | } | 755 | _impl_id: &ImplId, |
756 | } | 756 | ) -> Ty { |
757 | None => ImplTy::Inherent(self_ty), | 757 | Ty::Unknown |
758 | } | 758 | } |
759 | |||
760 | pub(crate) fn impl_trait_query(db: &impl HirDatabase, impl_id: ImplId) -> Option<TraitRef> { | ||
761 | let impl_data = db.impl_data(impl_id); | ||
762 | let resolver = impl_id.resolver(db); | ||
763 | let self_ty = db.impl_self_ty(impl_id); | ||
764 | let target_trait = impl_data.target_trait.as_ref()?; | ||
765 | TraitRef::from_hir(db, &resolver, target_trait, Some(self_ty.clone())) | ||
759 | } | 766 | } |