aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_hir/src/ty/infer.rs
diff options
context:
space:
mode:
Diffstat (limited to 'crates/ra_hir/src/ty/infer.rs')
-rw-r--r--crates/ra_hir/src/ty/infer.rs47
1 files changed, 41 insertions, 6 deletions
diff --git a/crates/ra_hir/src/ty/infer.rs b/crates/ra_hir/src/ty/infer.rs
index 594c5bc79..675df4a22 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> {
245 &self.resolver, 245 &self.resolver,
246 type_ref, 246 type_ref,
247 ); 247 );
248 self.insert_type_vars(ty) 248 let ty = self.insert_type_vars(ty);
249 self.normalize_associated_types_in(ty)
249 } 250 }
250 251
251 fn unify_substs(&mut self, substs1: &Substs, substs2: &Substs, depth: usize) -> bool { 252 fn unify_substs(&mut self, substs1: &Substs, substs2: &Substs, depth: usize) -> bool {
@@ -411,6 +412,32 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
411 ty 412 ty
412 } 413 }
413 414
415 /// Recurses through the given type, normalizing associated types mentioned
416 /// in it by replacing them by type variables and registering obligations to
417 /// resolve later. This should be done once for every type we get from some
418 /// type annotation (e.g. from a let type annotation, field type or function
419 /// call). `make_ty` handles this already, but e.g. for field types we need
420 /// to do it as well.
421 fn normalize_associated_types_in(&mut self, ty: Ty) -> Ty {
422 let ty = self.resolve_ty_as_possible(&mut vec![], ty);
423 ty.fold(&mut |ty| match ty {
424 Ty::Projection(proj_ty) => self.normalize_projection_ty(proj_ty),
425 Ty::UnselectedProjection(proj_ty) => {
426 // FIXME use Chalk's unselected projection support
427 Ty::UnselectedProjection(proj_ty)
428 }
429 _ => ty,
430 })
431 }
432
433 fn normalize_projection_ty(&mut self, proj_ty: ProjectionTy) -> Ty {
434 let var = self.new_type_var();
435 let predicate = ProjectionPredicate { projection_ty: proj_ty.clone(), ty: var.clone() };
436 let obligation = Obligation::Projection(predicate);
437 self.obligations.push(obligation);
438 var
439 }
440
414 /// Resolves the type completely; type variables without known type are 441 /// Resolves the type completely; type variables without known type are
415 /// replaced by Ty::Unknown. 442 /// replaced by Ty::Unknown.
416 fn resolve_ty_completely(&mut self, tv_stack: &mut Vec<TypeVarId>, ty: Ty) -> Ty { 443 fn resolve_ty_completely(&mut self, tv_stack: &mut Vec<TypeVarId>, ty: Ty) -> Ty {
@@ -549,6 +576,7 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
549 let substs = Ty::substs_from_path(self.db, &self.resolver, path, typable); 576 let substs = Ty::substs_from_path(self.db, &self.resolver, path, typable);
550 let ty = ty.subst(&substs); 577 let ty = ty.subst(&substs);
551 let ty = self.insert_type_vars(ty); 578 let ty = self.insert_type_vars(ty);
579 let ty = self.normalize_associated_types_in(ty);
552 Some(ty) 580 Some(ty)
553 } 581 }
554 Resolution::LocalBinding(pat) => { 582 Resolution::LocalBinding(pat) => {
@@ -670,6 +698,7 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
670 .and_then(|d| d.field(self.db, &Name::tuple_field_name(i))) 698 .and_then(|d| d.field(self.db, &Name::tuple_field_name(i)))
671 .map_or(Ty::Unknown, |field| field.ty(self.db)) 699 .map_or(Ty::Unknown, |field| field.ty(self.db))
672 .subst(&substs); 700 .subst(&substs);
701 let expected_ty = self.normalize_associated_types_in(expected_ty);
673 self.infer_pat(subpat, &expected_ty, default_bm); 702 self.infer_pat(subpat, &expected_ty, default_bm);
674 } 703 }
675 704
@@ -697,6 +726,7 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
697 let matching_field = def.and_then(|it| it.field(self.db, &subpat.name)); 726 let matching_field = def.and_then(|it| it.field(self.db, &subpat.name));
698 let expected_ty = 727 let expected_ty =
699 matching_field.map_or(Ty::Unknown, |field| field.ty(self.db)).subst(&substs); 728 matching_field.map_or(Ty::Unknown, |field| field.ty(self.db)).subst(&substs);
729 let expected_ty = self.normalize_associated_types_in(expected_ty);
700 self.infer_pat(subpat.pat, &expected_ty, default_bm); 730 self.infer_pat(subpat.pat, &expected_ty, default_bm);
701 } 731 }
702 732
@@ -927,9 +957,11 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
927 self.unify(&expected_receiver_ty, &actual_receiver_ty); 957 self.unify(&expected_receiver_ty, &actual_receiver_ty);
928 958
929 let param_iter = param_tys.into_iter().chain(repeat(Ty::Unknown)); 959 let param_iter = param_tys.into_iter().chain(repeat(Ty::Unknown));
930 for (arg, param) in args.iter().zip(param_iter) { 960 for (arg, param_ty) in args.iter().zip(param_iter) {
931 self.infer_expr(*arg, &Expectation::has_type(param)); 961 let param_ty = self.normalize_associated_types_in(param_ty);
962 self.infer_expr(*arg, &Expectation::has_type(param_ty));
932 } 963 }
964 let ret_ty = self.normalize_associated_types_in(ret_ty);
933 ret_ty 965 ret_ty
934 } 966 }
935 967
@@ -1020,9 +1052,11 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
1020 }; 1052 };
1021 self.register_obligations_for_call(&callee_ty); 1053 self.register_obligations_for_call(&callee_ty);
1022 let param_iter = param_tys.into_iter().chain(repeat(Ty::Unknown)); 1054 let param_iter = param_tys.into_iter().chain(repeat(Ty::Unknown));
1023 for (arg, param) in args.iter().zip(param_iter) { 1055 for (arg, param_ty) in args.iter().zip(param_iter) {
1024 self.infer_expr(*arg, &Expectation::has_type(param)); 1056 let param_ty = self.normalize_associated_types_in(param_ty);
1057 self.infer_expr(*arg, &Expectation::has_type(param_ty));
1025 } 1058 }
1059 let ret_ty = self.normalize_associated_types_in(ret_ty);
1026 ret_ty 1060 ret_ty
1027 } 1061 }
1028 Expr::MethodCall { receiver, args, method_name, generic_args } => self 1062 Expr::MethodCall { receiver, args, method_name, generic_args } => self
@@ -1120,7 +1154,8 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
1120 _ => None, 1154 _ => None,
1121 }) 1155 })
1122 .unwrap_or(Ty::Unknown); 1156 .unwrap_or(Ty::Unknown);
1123 self.insert_type_vars(ty) 1157 let ty = self.insert_type_vars(ty);
1158 self.normalize_associated_types_in(ty)
1124 } 1159 }
1125 Expr::Await { expr } => { 1160 Expr::Await { expr } => {
1126 let inner_ty = self.infer_expr(*expr, &Expectation::none()); 1161 let inner_ty = self.infer_expr(*expr, &Expectation::none());