aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--crates/ra_hir/src/ty/infer.rs27
-rw-r--r--crates/ra_hir/src/ty/tests.rs12
2 files changed, 27 insertions, 12 deletions
diff --git a/crates/ra_hir/src/ty/infer.rs b/crates/ra_hir/src/ty/infer.rs
index 74fc77cfb..675df4a22 100644
--- a/crates/ra_hir/src/ty/infer.rs
+++ b/crates/ra_hir/src/ty/infer.rs
@@ -412,11 +412,18 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
412 ty 412 ty
413 } 413 }
414 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.
415 fn normalize_associated_types_in(&mut self, ty: Ty) -> Ty { 421 fn normalize_associated_types_in(&mut self, ty: Ty) -> Ty {
422 let ty = self.resolve_ty_as_possible(&mut vec![], ty);
416 ty.fold(&mut |ty| match ty { 423 ty.fold(&mut |ty| match ty {
417 Ty::Projection(proj_ty) => self.normalize_projection_ty(proj_ty), 424 Ty::Projection(proj_ty) => self.normalize_projection_ty(proj_ty),
418 Ty::UnselectedProjection(proj_ty) => { 425 Ty::UnselectedProjection(proj_ty) => {
419 // FIXME 426 // FIXME use Chalk's unselected projection support
420 Ty::UnselectedProjection(proj_ty) 427 Ty::UnselectedProjection(proj_ty)
421 } 428 }
422 _ => ty, 429 _ => ty,
@@ -569,6 +576,7 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
569 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);
570 let ty = ty.subst(&substs); 577 let ty = ty.subst(&substs);
571 let ty = self.insert_type_vars(ty); 578 let ty = self.insert_type_vars(ty);
579 let ty = self.normalize_associated_types_in(ty);
572 Some(ty) 580 Some(ty)
573 } 581 }
574 Resolution::LocalBinding(pat) => { 582 Resolution::LocalBinding(pat) => {
@@ -690,6 +698,7 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
690 .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)))
691 .map_or(Ty::Unknown, |field| field.ty(self.db)) 699 .map_or(Ty::Unknown, |field| field.ty(self.db))
692 .subst(&substs); 700 .subst(&substs);
701 let expected_ty = self.normalize_associated_types_in(expected_ty);
693 self.infer_pat(subpat, &expected_ty, default_bm); 702 self.infer_pat(subpat, &expected_ty, default_bm);
694 } 703 }
695 704
@@ -717,6 +726,7 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
717 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));
718 let expected_ty = 727 let expected_ty =
719 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);
720 self.infer_pat(subpat.pat, &expected_ty, default_bm); 730 self.infer_pat(subpat.pat, &expected_ty, default_bm);
721 } 731 }
722 732
@@ -947,9 +957,11 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
947 self.unify(&expected_receiver_ty, &actual_receiver_ty); 957 self.unify(&expected_receiver_ty, &actual_receiver_ty);
948 958
949 let param_iter = param_tys.into_iter().chain(repeat(Ty::Unknown)); 959 let param_iter = param_tys.into_iter().chain(repeat(Ty::Unknown));
950 for (arg, param) in args.iter().zip(param_iter) { 960 for (arg, param_ty) in args.iter().zip(param_iter) {
951 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));
952 } 963 }
964 let ret_ty = self.normalize_associated_types_in(ret_ty);
953 ret_ty 965 ret_ty
954 } 966 }
955 967
@@ -1040,9 +1052,11 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
1040 }; 1052 };
1041 self.register_obligations_for_call(&callee_ty); 1053 self.register_obligations_for_call(&callee_ty);
1042 let param_iter = param_tys.into_iter().chain(repeat(Ty::Unknown)); 1054 let param_iter = param_tys.into_iter().chain(repeat(Ty::Unknown));
1043 for (arg, param) in args.iter().zip(param_iter) { 1055 for (arg, param_ty) in args.iter().zip(param_iter) {
1044 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));
1045 } 1058 }
1059 let ret_ty = self.normalize_associated_types_in(ret_ty);
1046 ret_ty 1060 ret_ty
1047 } 1061 }
1048 Expr::MethodCall { receiver, args, method_name, generic_args } => self 1062 Expr::MethodCall { receiver, args, method_name, generic_args } => self
@@ -1140,7 +1154,8 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
1140 _ => None, 1154 _ => None,
1141 }) 1155 })
1142 .unwrap_or(Ty::Unknown); 1156 .unwrap_or(Ty::Unknown);
1143 self.insert_type_vars(ty) 1157 let ty = self.insert_type_vars(ty);
1158 self.normalize_associated_types_in(ty)
1144 } 1159 }
1145 Expr::Await { expr } => { 1160 Expr::Await { expr } => {
1146 let inner_ty = self.infer_expr(*expr, &Expectation::none()); 1161 let inner_ty = self.infer_expr(*expr, &Expectation::none());
diff --git a/crates/ra_hir/src/ty/tests.rs b/crates/ra_hir/src/ty/tests.rs
index 01b358335..e6a09cc67 100644
--- a/crates/ra_hir/src/ty/tests.rs
+++ b/crates/ra_hir/src/ty/tests.rs
@@ -2515,10 +2515,10 @@ fn test<T: Iterable>() {
2515 @r###" 2515 @r###"
2516 2516
2517 ⋮[108; 227) '{ ...ter; }': () 2517 ⋮[108; 227) '{ ...ter; }': ()
2518 ⋮[118; 119) 'x': <S as Iterable>::Item 2518 ⋮[118; 119) 'x': u32
2519 ⋮[145; 146) '1': <S as Iterable>::Item 2519 ⋮[145; 146) '1': u32
2520 ⋮[156; 157) 'y': <T as Iterable>::Item 2520 ⋮[156; 157) 'y': {unknown}
2521 ⋮[183; 192) 'no_matter': <T as Iterable>::Item 2521 ⋮[183; 192) 'no_matter': {unknown}
2522 ⋮[202; 203) 'z': {unknown} 2522 ⋮[202; 203) 'z': {unknown}
2523 ⋮[215; 224) 'no_matter': {unknown} 2523 ⋮[215; 224) 'no_matter': {unknown}
2524 "### 2524 "###
@@ -2552,9 +2552,9 @@ fn test() {
2552 ⋮[205; 209) 'foo1': fn foo1<S>(T) -> {unknown} 2552 ⋮[205; 209) 'foo1': fn foo1<S>(T) -> {unknown}
2553 ⋮[205; 212) 'foo1(S)': {unknown} 2553 ⋮[205; 212) 'foo1(S)': {unknown}
2554 ⋮[210; 211) 'S': S 2554 ⋮[210; 211) 'S': S
2555 ⋮[222; 223) 'y': <S as Iterable>::Item 2555 ⋮[222; 223) 'y': u32
2556 ⋮[226; 230) 'foo2': fn foo2<S>(T) -> <T as Iterable>::Item 2556 ⋮[226; 230) 'foo2': fn foo2<S>(T) -> <T as Iterable>::Item
2557 ⋮[226; 233) 'foo2(S)': <S as Iterable>::Item 2557 ⋮[226; 233) 'foo2(S)': u32
2558 ⋮[231; 232) 'S': S 2558 ⋮[231; 232) 'S': S
2559 "### 2559 "###
2560 ); 2560 );