Add helper for resolving associated type of trait in infer

This commit is contained in:
Emil Lauridsen 2019-12-13 12:44:07 +01:00
parent 16cf6bcf4b
commit 95dc2de8e9
2 changed files with 25 additions and 47 deletions

View file

@ -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<TypeAliasId>) -> 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

View file

@ -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 } => {