mirror of
https://github.com/rust-lang/rust-analyzer
synced 2024-11-15 01:17:27 +00:00
Add helper for resolving associated type of trait in infer
This commit is contained in:
parent
16cf6bcf4b
commit
95dc2de8e9
2 changed files with 25 additions and 47 deletions
|
@ -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
|
||||
|
|
|
@ -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 } => {
|
||||
|
|
Loading…
Reference in a new issue