aboutsummaryrefslogtreecommitdiff
path: root/crates/hir_ty/src/infer
diff options
context:
space:
mode:
Diffstat (limited to 'crates/hir_ty/src/infer')
-rw-r--r--crates/hir_ty/src/infer/coerce.rs12
-rw-r--r--crates/hir_ty/src/infer/expr.rs49
-rw-r--r--crates/hir_ty/src/infer/pat.rs9
-rw-r--r--crates/hir_ty/src/infer/unify.rs7
4 files changed, 40 insertions, 37 deletions
diff --git a/crates/hir_ty/src/infer/coerce.rs b/crates/hir_ty/src/infer/coerce.rs
index 765a02b1c..03b97e7db 100644
--- a/crates/hir_ty/src/infer/coerce.rs
+++ b/crates/hir_ty/src/infer/coerce.rs
@@ -76,17 +76,17 @@ impl<'a> InferenceContext<'a> {
76 // way around first would mean we make the type variable `!`, instead of 76 // way around first would mean we make the type variable `!`, instead of
77 // just marking it as possibly diverging. 77 // just marking it as possibly diverging.
78 if self.coerce(&ty2, &ty1) { 78 if self.coerce(&ty2, &ty1) {
79 ty1.clone() 79 ty1
80 } else if self.coerce(&ty1, &ty2) { 80 } else if self.coerce(&ty1, &ty2) {
81 ty2.clone() 81 ty2
82 } else { 82 } else {
83 if let Some(id) = id { 83 if let Some(id) = id {
84 self.result 84 self.result
85 .type_mismatches 85 .type_mismatches
86 .insert(id.into(), TypeMismatch { expected: ty1.clone(), actual: ty2.clone() }); 86 .insert(id.into(), TypeMismatch { expected: ty1.clone(), actual: ty2 });
87 } 87 }
88 cov_mark::hit!(coerce_merge_fail_fallback); 88 cov_mark::hit!(coerce_merge_fail_fallback);
89 ty1.clone() 89 ty1
90 } 90 }
91 } 91 }
92 92
@@ -183,7 +183,7 @@ impl<'a> InferenceContext<'a> {
183 // details of coercion errors though, so I think it's useful to leave 183 // details of coercion errors though, so I think it's useful to leave
184 // the structure like it is. 184 // the structure like it is.
185 185
186 let canonicalized = self.canonicalize(from_ty.clone()); 186 let canonicalized = self.canonicalize(from_ty);
187 let autoderef = autoderef::autoderef( 187 let autoderef = autoderef::autoderef(
188 self.db, 188 self.db,
189 self.resolver.krate(), 189 self.resolver.krate(),
@@ -389,7 +389,7 @@ impl<'a> InferenceContext<'a> {
389 // The CoerceUnsized trait should have two generic params: Self and T. 389 // The CoerceUnsized trait should have two generic params: Self and T.
390 return Err(TypeError); 390 return Err(TypeError);
391 } 391 }
392 b.push(coerce_from.clone()).push(to_ty.clone()).build() 392 b.push(coerce_from).push(to_ty.clone()).build()
393 }; 393 };
394 394
395 let goal: InEnvironment<DomainGoal> = 395 let goal: InEnvironment<DomainGoal> =
diff --git a/crates/hir_ty/src/infer/expr.rs b/crates/hir_ty/src/infer/expr.rs
index 08c05c67c..41ef45326 100644
--- a/crates/hir_ty/src/infer/expr.rs
+++ b/crates/hir_ty/src/infer/expr.rs
@@ -44,7 +44,7 @@ impl<'a> InferenceContext<'a> {
44 if !could_unify { 44 if !could_unify {
45 self.result.type_mismatches.insert( 45 self.result.type_mismatches.insert(
46 tgt_expr.into(), 46 tgt_expr.into(),
47 TypeMismatch { expected: expected_ty.clone(), actual: ty.clone() }, 47 TypeMismatch { expected: expected_ty, actual: ty.clone() },
48 ); 48 );
49 } 49 }
50 } 50 }
@@ -57,15 +57,14 @@ impl<'a> InferenceContext<'a> {
57 let ty = self.infer_expr_inner(expr, &expected); 57 let ty = self.infer_expr_inner(expr, &expected);
58 let ty = if let Some(target) = expected.only_has_type(&mut self.table) { 58 let ty = if let Some(target) = expected.only_has_type(&mut self.table) {
59 if !self.coerce(&ty, &target) { 59 if !self.coerce(&ty, &target) {
60 self.result.type_mismatches.insert( 60 self.result
61 expr.into(), 61 .type_mismatches
62 TypeMismatch { expected: target.clone(), actual: ty.clone() }, 62 .insert(expr.into(), TypeMismatch { expected: target, actual: ty.clone() });
63 );
64 // Return actual type when type mismatch. 63 // Return actual type when type mismatch.
65 // This is needed for diagnostic when return type mismatch. 64 // This is needed for diagnostic when return type mismatch.
66 ty 65 ty
67 } else { 66 } else {
68 target.clone() 67 target
69 } 68 }
70 } else { 69 } else {
71 ty 70 ty
@@ -120,7 +119,7 @@ impl<'a> InferenceContext<'a> {
120 } 119 }
121 120
122 fn infer_expr_inner(&mut self, tgt_expr: ExprId, expected: &Expectation) -> Ty { 121 fn infer_expr_inner(&mut self, tgt_expr: ExprId, expected: &Expectation) -> Ty {
123 self.db.check_canceled(); 122 self.db.unwind_if_cancelled();
124 123
125 let body = Arc::clone(&self.body); // avoid borrow checker problem 124 let body = Arc::clone(&self.body); // avoid borrow checker problem
126 let ty = match &body[tgt_expr] { 125 let ty = match &body[tgt_expr] {
@@ -805,7 +804,7 @@ impl<'a> InferenceContext<'a> {
805 None => self.table.new_float_var(), 804 None => self.table.new_float_var(),
806 }, 805 },
807 }, 806 },
808 Expr::MacroStmts { tail } => self.infer_expr(*tail, expected), 807 Expr::MacroStmts { tail } => self.infer_expr_inner(*tail, expected),
809 }; 808 };
810 // use a new type variable if we got unknown here 809 // use a new type variable if we got unknown here
811 let ty = self.insert_type_vars_shallow(ty); 810 let ty = self.insert_type_vars_shallow(ty);
@@ -891,17 +890,21 @@ impl<'a> InferenceContext<'a> {
891 method_name, 890 method_name,
892 ) 891 )
893 }); 892 });
894 let (derefed_receiver_ty, method_ty, def_generics) = match resolved { 893 let (derefed_receiver_ty, method_ty, substs) = match resolved {
895 Some((ty, func)) => { 894 Some((ty, func)) => {
896 let ty = canonicalized_receiver.decanonicalize_ty(ty); 895 let ty = canonicalized_receiver.decanonicalize_ty(ty);
897 self.write_method_resolution(tgt_expr, func); 896 let generics = generics(self.db.upcast(), func.into());
898 (ty, self.db.value_ty(func.into()), Some(generics(self.db.upcast(), func.into()))) 897 let substs = self.substs_for_method_call(generics, generic_args, &ty);
898 self.write_method_resolution(tgt_expr, func, substs.clone());
899 (ty, self.db.value_ty(func.into()), substs)
899 } 900 }
900 None => (receiver_ty, Binders::empty(&Interner, self.err_ty()), None), 901 None => (
902 receiver_ty,
903 Binders::empty(&Interner, self.err_ty()),
904 Substitution::empty(&Interner),
905 ),
901 }; 906 };
902 let substs = self.substs_for_method_call(def_generics, generic_args, &derefed_receiver_ty);
903 let method_ty = method_ty.substitute(&Interner, &substs); 907 let method_ty = method_ty.substitute(&Interner, &substs);
904 let method_ty = self.insert_type_vars(method_ty);
905 self.register_obligations_for_call(&method_ty); 908 self.register_obligations_for_call(&method_ty);
906 let (expected_receiver_ty, param_tys, ret_ty) = match method_ty.callable_sig(self.db) { 909 let (expected_receiver_ty, param_tys, ret_ty) = match method_ty.callable_sig(self.db) {
907 Some(sig) => { 910 Some(sig) => {
@@ -950,23 +953,21 @@ impl<'a> InferenceContext<'a> {
950 953
951 fn substs_for_method_call( 954 fn substs_for_method_call(
952 &mut self, 955 &mut self,
953 def_generics: Option<Generics>, 956 def_generics: Generics,
954 generic_args: Option<&GenericArgs>, 957 generic_args: Option<&GenericArgs>,
955 receiver_ty: &Ty, 958 receiver_ty: &Ty,
956 ) -> Substitution { 959 ) -> Substitution {
957 let (parent_params, self_params, type_params, impl_trait_params) = 960 let (parent_params, self_params, type_params, impl_trait_params) =
958 def_generics.as_ref().map_or((0, 0, 0, 0), |g| g.provenance_split()); 961 def_generics.provenance_split();
959 assert_eq!(self_params, 0); // method shouldn't have another Self param 962 assert_eq!(self_params, 0); // method shouldn't have another Self param
960 let total_len = parent_params + type_params + impl_trait_params; 963 let total_len = parent_params + type_params + impl_trait_params;
961 let mut substs = Vec::with_capacity(total_len); 964 let mut substs = Vec::with_capacity(total_len);
962 // Parent arguments are unknown, except for the receiver type 965 // Parent arguments are unknown, except for the receiver type
963 if let Some(parent_generics) = def_generics.as_ref().map(|p| p.iter_parent()) { 966 for (_id, param) in def_generics.iter_parent() {
964 for (_id, param) in parent_generics { 967 if param.provenance == hir_def::generics::TypeParamProvenance::TraitSelf {
965 if param.provenance == hir_def::generics::TypeParamProvenance::TraitSelf { 968 substs.push(receiver_ty.clone());
966 substs.push(receiver_ty.clone()); 969 } else {
967 } else { 970 substs.push(self.table.new_type_var());
968 substs.push(self.err_ty());
969 }
970 } 971 }
971 } 972 }
972 // handle provided type arguments 973 // handle provided type arguments
@@ -989,7 +990,7 @@ impl<'a> InferenceContext<'a> {
989 }; 990 };
990 let supplied_params = substs.len(); 991 let supplied_params = substs.len();
991 for _ in supplied_params..total_len { 992 for _ in supplied_params..total_len {
992 substs.push(self.err_ty()); 993 substs.push(self.table.new_type_var());
993 } 994 }
994 assert_eq!(substs.len(), total_len); 995 assert_eq!(substs.len(), total_len);
995 Substitution::from_iter(&Interner, substs) 996 Substitution::from_iter(&Interner, substs)
diff --git a/crates/hir_ty/src/infer/pat.rs b/crates/hir_ty/src/infer/pat.rs
index 9c8e3b6ae..83e0a7a9e 100644
--- a/crates/hir_ty/src/infer/pat.rs
+++ b/crates/hir_ty/src/infer/pat.rs
@@ -196,7 +196,7 @@ impl<'a> InferenceContext<'a> {
196 let inner_ty = if let Some(subpat) = subpat { 196 let inner_ty = if let Some(subpat) = subpat {
197 self.infer_pat(*subpat, &expected, default_bm) 197 self.infer_pat(*subpat, &expected, default_bm)
198 } else { 198 } else {
199 expected.clone() 199 expected
200 }; 200 };
201 let inner_ty = self.insert_type_vars_shallow(inner_ty); 201 let inner_ty = self.insert_type_vars_shallow(inner_ty);
202 202
@@ -266,10 +266,9 @@ impl<'a> InferenceContext<'a> {
266 // use a new type variable if we got error type here 266 // use a new type variable if we got error type here
267 let ty = self.insert_type_vars_shallow(ty); 267 let ty = self.insert_type_vars_shallow(ty);
268 if !self.unify(&ty, &expected) { 268 if !self.unify(&ty, &expected) {
269 self.result.type_mismatches.insert( 269 self.result
270 pat.into(), 270 .type_mismatches
271 TypeMismatch { expected: expected.clone(), actual: ty.clone() }, 271 .insert(pat.into(), TypeMismatch { expected: expected, actual: ty.clone() });
272 );
273 } 272 }
274 self.write_pat_ty(pat, ty.clone()); 273 self.write_pat_ty(pat, ty.clone());
275 ty 274 ty
diff --git a/crates/hir_ty/src/infer/unify.rs b/crates/hir_ty/src/infer/unify.rs
index f8233cac3..ea5684229 100644
--- a/crates/hir_ty/src/infer/unify.rs
+++ b/crates/hir_ty/src/infer/unify.rs
@@ -295,8 +295,11 @@ impl<'a> InferenceTable<'a> {
295 .expect("fold failed unexpectedly") 295 .expect("fold failed unexpectedly")
296 } 296 }
297 297
298 pub(crate) fn resolve_ty_completely(&mut self, ty: Ty) -> Ty { 298 pub(crate) fn resolve_completely<T>(&mut self, t: T) -> T::Result
299 self.resolve_with_fallback(ty, |_, _, d, _| d) 299 where
300 T: HasInterner<Interner = Interner> + Fold<Interner>,
301 {
302 self.resolve_with_fallback(t, |_, _, d, _| d)
300 } 303 }
301 304
302 /// Unify two types and register new trait goals that arise from that. 305 /// Unify two types and register new trait goals that arise from that.