From dbc14f9d570e5bc1ddae05e9ccd8f163082b3cac Mon Sep 17 00:00:00 2001 From: Florian Diebold Date: Fri, 31 Jan 2020 15:17:48 +0100 Subject: First stab at desugaring bounds for APIT --- crates/ra_hir_def/src/generics.rs | 27 +++++++++++++++++++++++---- 1 file changed, 23 insertions(+), 4 deletions(-) (limited to 'crates/ra_hir_def') diff --git a/crates/ra_hir_def/src/generics.rs b/crates/ra_hir_def/src/generics.rs index 7553d8a87..e4e616519 100644 --- a/crates/ra_hir_def/src/generics.rs +++ b/crates/ra_hir_def/src/generics.rs @@ -53,10 +53,17 @@ pub struct GenericParams { /// associated type bindings like `Iterator`. #[derive(Clone, PartialEq, Eq, Debug)] pub struct WherePredicate { - pub type_ref: TypeRef, + pub target: WherePredicateTarget, pub bound: TypeBound, } +#[derive(Clone, PartialEq, Eq, Debug)] +pub enum WherePredicateTarget { + TypeRef(TypeRef), + /// For desugared where predicates that can directly refer to a type param. + TypeParam(LocalTypeParamId) +} + type SourceMap = ArenaMap>; impl GenericParams { @@ -190,18 +197,24 @@ impl GenericParams { return; } let bound = TypeBound::from_ast(bound); - self.where_predicates.push(WherePredicate { type_ref, bound }); + self.where_predicates.push(WherePredicate { target: WherePredicateTarget::TypeRef(type_ref), bound }); } fn fill_implicit_impl_trait_args(&mut self, type_ref: &TypeRef) { type_ref.walk(&mut |type_ref| { - if let TypeRef::ImplTrait(_) = type_ref { + if let TypeRef::ImplTrait(bounds) = type_ref { let param = TypeParamData { name: None, default: None, provenance: TypeParamProvenance::ArgumentImplTrait, }; - let _param_id = self.types.alloc(param); + let param_id = self.types.alloc(param); + for bound in bounds { + self.where_predicates.push(WherePredicate { + target: WherePredicateTarget::TypeParam(param_id), + bound: bound.clone() + }); + } } }); } @@ -211,6 +224,12 @@ impl GenericParams { .iter() .find_map(|(id, p)| if p.name.as_ref() == Some(name) { Some(id) } else { None }) } + + pub fn find_trait_self_param(&self) -> Option { + self.types + .iter() + .find_map(|(id, p)| if p.provenance == TypeParamProvenance::TraitSelf { Some(id) } else { None }) + } } impl HasChildSource for GenericDefId { -- cgit v1.2.3