diff options
Diffstat (limited to 'crates/hir_ty/src/infer')
-rw-r--r-- | crates/hir_ty/src/infer/coerce.rs | 12 | ||||
-rw-r--r-- | crates/hir_ty/src/infer/expr.rs | 49 | ||||
-rw-r--r-- | crates/hir_ty/src/infer/pat.rs | 9 | ||||
-rw-r--r-- | crates/hir_ty/src/infer/unify.rs | 7 |
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. |