From 95dc2de8e979264e1c76ce5594e8a63547a7956e Mon Sep 17 00:00:00 2001 From: Emil Lauridsen Date: Fri, 13 Dec 2019 12:44:07 +0100 Subject: Add helper for resolving associated type of trait in infer --- crates/ra_hir_ty/src/infer.rs | 18 +++++++++++++ crates/ra_hir_ty/src/infer/expr.rs | 54 +++++--------------------------------- 2 files changed, 25 insertions(+), 47 deletions(-) diff --git a/crates/ra_hir_ty/src/infer.rs b/crates/ra_hir_ty/src/infer.rs index d16f1eb46..62d5c8803 100644 --- a/crates/ra_hir_ty/src/infer.rs +++ b/crates/ra_hir_ty/src/infer.rs @@ -338,6 +338,24 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { self.table.resolve_ty_shallow(ty) } + fn resolve_associated_type(&mut self, inner_ty: Ty, assoc_ty: Option) -> Ty { + match assoc_ty { + Some(res_assoc_ty) => { + let ty = self.table.new_type_var(); + let projection = ProjectionPredicate { + ty: ty.clone(), + projection_ty: ProjectionTy { + associated_ty: res_assoc_ty, + parameters: Substs::single(inner_ty), + }, + }; + self.obligations.push(Obligation::Projection(projection)); + self.resolve_ty_as_possible(ty) + } + None => Ty::Unknown, + } + } + /// Recurses through the given type, normalizing associated types mentioned /// in it by replacing them by type variables and registering obligations to /// resolve later. This should be done once for every type we get from some diff --git a/crates/ra_hir_ty/src/infer/expr.rs b/crates/ra_hir_ty/src/infer/expr.rs index 2c296987c..6110f5abd 100644 --- a/crates/ra_hir_ty/src/infer/expr.rs +++ b/crates/ra_hir_ty/src/infer/expr.rs @@ -19,8 +19,8 @@ use crate::{ method_resolution, op, traits::InEnvironment, utils::{generics, variant_data, Generics}, - CallableDef, InferTy, IntTy, Mutability, Obligation, ProjectionPredicate, ProjectionTy, Substs, - TraitRef, Ty, TypeCtor, TypeWalk, Uncertain, + ApplicationTy, CallableDef, InferTy, IntTy, Mutability, Obligation, Substs, TraitRef, Ty, + TypeCtor, TypeWalk, Uncertain, }; use super::{BindingMode, Expectation, InferenceContext, InferenceDiagnostic, TypeMismatch}; @@ -95,21 +95,8 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { Expr::For { iterable, body, pat } => { let iterable_ty = self.infer_expr(*iterable, &Expectation::none()); - let pat_ty = match self.resolve_into_iter_item() { - Some(into_iter_item_alias) => { - let pat_ty = self.table.new_type_var(); - let projection = ProjectionPredicate { - ty: pat_ty.clone(), - projection_ty: ProjectionTy { - associated_ty: into_iter_item_alias, - parameters: Substs::single(iterable_ty), - }, - }; - self.obligations.push(Obligation::Projection(projection)); - self.resolve_ty_as_possible(pat_ty) - } - None => Ty::Unknown, - }; + let pat_ty = + self.resolve_associated_type(iterable_ty, self.resolve_into_iter_item()); self.infer_pat(*pat, &pat_ty, BindingMode::default()); self.infer_expr(*body, &Expectation::has_type(Ty::unit())); @@ -284,40 +271,13 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { } Expr::Await { expr } => { let inner_ty = self.infer_expr_inner(*expr, &Expectation::none()); - let ty = match self.resolve_future_future_output() { - Some(future_future_output_alias) => { - let ty = self.table.new_type_var(); - let projection = ProjectionPredicate { - ty: ty.clone(), - projection_ty: ProjectionTy { - associated_ty: future_future_output_alias, - parameters: Substs::single(inner_ty), - }, - }; - self.obligations.push(Obligation::Projection(projection)); - self.resolve_ty_as_possible(ty) - } - None => Ty::Unknown, - }; + let ty = + self.resolve_associated_type(inner_ty, self.resolve_future_future_output()); ty } Expr::Try { expr } => { let inner_ty = self.infer_expr_inner(*expr, &Expectation::none()); - let ty = match self.resolve_ops_try_ok() { - Some(ops_try_ok_alias) => { - let ty = self.table.new_type_var(); - let projection = ProjectionPredicate { - ty: ty.clone(), - projection_ty: ProjectionTy { - associated_ty: ops_try_ok_alias, - parameters: Substs::single(inner_ty), - }, - }; - self.obligations.push(Obligation::Projection(projection)); - self.resolve_ty_as_possible(ty) - } - None => Ty::Unknown, - }; + let ty = self.resolve_associated_type(inner_ty, self.resolve_ops_try_ok()); ty } Expr::Cast { expr, type_ref } => { -- cgit v1.2.3