From 6265497523469990ce39e6817423c35a17055a54 Mon Sep 17 00:00:00 2001 From: Florian Diebold Date: Wed, 7 Aug 2019 22:06:09 +0200 Subject: Normalize associated types during inference --- crates/ra_hir/src/ty/infer.rs | 22 +++++++++++++++++++++- crates/ra_hir/src/ty/lower.rs | 5 ----- crates/ra_hir/src/ty/traits/chalk.rs | 7 ++++--- 3 files changed, 25 insertions(+), 9 deletions(-) (limited to 'crates/ra_hir/src/ty') diff --git a/crates/ra_hir/src/ty/infer.rs b/crates/ra_hir/src/ty/infer.rs index 594c5bc79..74fc77cfb 100644 --- a/crates/ra_hir/src/ty/infer.rs +++ b/crates/ra_hir/src/ty/infer.rs @@ -245,7 +245,8 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { &self.resolver, type_ref, ); - self.insert_type_vars(ty) + let ty = self.insert_type_vars(ty); + self.normalize_associated_types_in(ty) } fn unify_substs(&mut self, substs1: &Substs, substs2: &Substs, depth: usize) -> bool { @@ -411,6 +412,25 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { ty } + fn normalize_associated_types_in(&mut self, ty: Ty) -> Ty { + ty.fold(&mut |ty| match ty { + Ty::Projection(proj_ty) => self.normalize_projection_ty(proj_ty), + Ty::UnselectedProjection(proj_ty) => { + // FIXME + Ty::UnselectedProjection(proj_ty) + } + _ => ty, + }) + } + + fn normalize_projection_ty(&mut self, proj_ty: ProjectionTy) -> Ty { + let var = self.new_type_var(); + let predicate = ProjectionPredicate { projection_ty: proj_ty.clone(), ty: var.clone() }; + let obligation = Obligation::Projection(predicate); + self.obligations.push(obligation); + var + } + /// Resolves the type completely; type variables without known type are /// replaced by Ty::Unknown. fn resolve_ty_completely(&mut self, tv_stack: &mut Vec, ty: Ty) -> Ty { diff --git a/crates/ra_hir/src/ty/lower.rs b/crates/ra_hir/src/ty/lower.rs index 24ec77fcf..debedcbb8 100644 --- a/crates/ra_hir/src/ty/lower.rs +++ b/crates/ra_hir/src/ty/lower.rs @@ -117,11 +117,6 @@ impl Ty { return Ty::Unknown; } }; - eprintln!( - "assoc ty: {:?}, parameters: {:?}", - associated_ty.name(db), - trait_ref.substs - ); // FIXME handle type parameters on the segment Ty::Projection(ProjectionTy { associated_ty, parameters: trait_ref.substs }) } else { diff --git a/crates/ra_hir/src/ty/traits/chalk.rs b/crates/ra_hir/src/ty/traits/chalk.rs index 21055dcfd..e669f835b 100644 --- a/crates/ra_hir/src/ty/traits/chalk.rs +++ b/crates/ra_hir/src/ty/traits/chalk.rs @@ -402,11 +402,12 @@ where &self, projection: &'p chalk_ir::ProjectionTy, ) -> (Arc, &'p [Parameter], &'p [Parameter]) { - debug!("split_projection {:?}", projection); - unimplemented!() + let proj_ty: ProjectionTy = from_chalk(self.db, projection.clone()); + debug!("split_projection {:?} = {}", projection, proj_ty.display(self.db)); + // we don't support GATs, so I think this should always be correct currently + (self.db.associated_ty_data(projection.associated_ty_id), &projection.parameters, &[]) } fn custom_clauses(&self) -> Vec { - debug!("custom_clauses"); vec![] } fn all_structs(&self) -> Vec { -- cgit v1.2.3