diff options
Diffstat (limited to 'crates/ra_hir/src/ty/infer.rs')
-rw-r--r-- | crates/ra_hir/src/ty/infer.rs | 529 |
1 files changed, 436 insertions, 93 deletions
diff --git a/crates/ra_hir/src/ty/infer.rs b/crates/ra_hir/src/ty/infer.rs index 76b4b6faa..db3377357 100644 --- a/crates/ra_hir/src/ty/infer.rs +++ b/crates/ra_hir/src/ty/infer.rs | |||
@@ -14,7 +14,7 @@ | |||
14 | //! the `ena` crate, which is extracted from rustc. | 14 | //! the `ena` crate, which is extracted from rustc. |
15 | 15 | ||
16 | use std::borrow::Cow; | 16 | use std::borrow::Cow; |
17 | use std::iter::repeat; | 17 | use std::iter::{repeat, repeat_with}; |
18 | use std::mem; | 18 | use std::mem; |
19 | use std::ops::Index; | 19 | use std::ops::Index; |
20 | use std::sync::Arc; | 20 | use std::sync::Arc; |
@@ -42,6 +42,7 @@ use crate::{ | |||
42 | RecordFieldPat, Statement, UnaryOp, | 42 | RecordFieldPat, Statement, UnaryOp, |
43 | }, | 43 | }, |
44 | generics::{GenericParams, HasGenericParams}, | 44 | generics::{GenericParams, HasGenericParams}, |
45 | lang_item::LangItemTarget, | ||
45 | name, | 46 | name, |
46 | nameres::Namespace, | 47 | nameres::Namespace, |
47 | path::{known, GenericArg, GenericArgs}, | 48 | path::{known, GenericArg, GenericArgs}, |
@@ -188,6 +189,21 @@ struct InferenceContext<'a, D: HirDatabase> { | |||
188 | result: InferenceResult, | 189 | result: InferenceResult, |
189 | /// The return type of the function being inferred. | 190 | /// The return type of the function being inferred. |
190 | return_ty: Ty, | 191 | return_ty: Ty, |
192 | |||
193 | /// Impls of `CoerceUnsized` used in coercion. | ||
194 | /// (from_ty_ctor, to_ty_ctor) => coerce_generic_index | ||
195 | // FIXME: Use trait solver for this. | ||
196 | // Chalk seems unable to work well with builtin impl of `Unsize` now. | ||
197 | coerce_unsized_map: FxHashMap<(TypeCtor, TypeCtor), usize>, | ||
198 | } | ||
199 | |||
200 | macro_rules! ty_app { | ||
201 | ($ctor:pat, $param:pat) => { | ||
202 | Ty::Apply(ApplicationTy { ctor: $ctor, parameters: $param }) | ||
203 | }; | ||
204 | ($ctor:pat) => { | ||
205 | ty_app!($ctor, _) | ||
206 | }; | ||
191 | } | 207 | } |
192 | 208 | ||
193 | impl<'a, D: HirDatabase> InferenceContext<'a, D> { | 209 | impl<'a, D: HirDatabase> InferenceContext<'a, D> { |
@@ -198,12 +214,52 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { | |||
198 | obligations: Vec::default(), | 214 | obligations: Vec::default(), |
199 | return_ty: Ty::Unknown, // set in collect_fn_signature | 215 | return_ty: Ty::Unknown, // set in collect_fn_signature |
200 | trait_env: lower::trait_env(db, &resolver), | 216 | trait_env: lower::trait_env(db, &resolver), |
217 | coerce_unsized_map: Self::init_coerce_unsized_map(db, &resolver), | ||
201 | db, | 218 | db, |
202 | body, | 219 | body, |
203 | resolver, | 220 | resolver, |
204 | } | 221 | } |
205 | } | 222 | } |
206 | 223 | ||
224 | fn init_coerce_unsized_map( | ||
225 | db: &'a D, | ||
226 | resolver: &Resolver, | ||
227 | ) -> FxHashMap<(TypeCtor, TypeCtor), usize> { | ||
228 | let krate = resolver.krate().unwrap(); | ||
229 | let impls = match db.lang_item(krate, "coerce_unsized".into()) { | ||
230 | Some(LangItemTarget::Trait(trait_)) => db.impls_for_trait(krate, trait_), | ||
231 | _ => return FxHashMap::default(), | ||
232 | }; | ||
233 | |||
234 | impls | ||
235 | .iter() | ||
236 | .filter_map(|impl_block| { | ||
237 | // `CoerseUnsized` has one generic parameter for the target type. | ||
238 | let trait_ref = impl_block.target_trait_ref(db)?; | ||
239 | let cur_from_ty = trait_ref.substs.0.get(0)?; | ||
240 | let cur_to_ty = trait_ref.substs.0.get(1)?; | ||
241 | |||
242 | match (&cur_from_ty, cur_to_ty) { | ||
243 | (ty_app!(ctor1, st1), ty_app!(ctor2, st2)) => { | ||
244 | // FIXME: We return the first non-equal bound as the type parameter to coerce to unsized type. | ||
245 | // This works for smart-pointer-like coercion, which covers all impls from std. | ||
246 | st1.iter().zip(st2.iter()).enumerate().find_map(|(i, (ty1, ty2))| { | ||
247 | match (ty1, ty2) { | ||
248 | (Ty::Param { idx: p1, .. }, Ty::Param { idx: p2, .. }) | ||
249 | if p1 != p2 => | ||
250 | { | ||
251 | Some(((*ctor1, *ctor2), i)) | ||
252 | } | ||
253 | _ => None, | ||
254 | } | ||
255 | }) | ||
256 | } | ||
257 | _ => None, | ||
258 | } | ||
259 | }) | ||
260 | .collect() | ||
261 | } | ||
262 | |||
207 | fn resolve_all(mut self) -> InferenceResult { | 263 | fn resolve_all(mut self) -> InferenceResult { |
208 | // FIXME resolve obligations as well (use Guidance if necessary) | 264 | // FIXME resolve obligations as well (use Guidance if necessary) |
209 | let mut result = mem::replace(&mut self.result, InferenceResult::default()); | 265 | let mut result = mem::replace(&mut self.result, InferenceResult::default()); |
@@ -278,27 +334,45 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { | |||
278 | let ty1 = self.resolve_ty_shallow(ty1); | 334 | let ty1 = self.resolve_ty_shallow(ty1); |
279 | let ty2 = self.resolve_ty_shallow(ty2); | 335 | let ty2 = self.resolve_ty_shallow(ty2); |
280 | match (&*ty1, &*ty2) { | 336 | match (&*ty1, &*ty2) { |
281 | (Ty::Unknown, _) | (_, Ty::Unknown) => true, | ||
282 | (Ty::Apply(a_ty1), Ty::Apply(a_ty2)) if a_ty1.ctor == a_ty2.ctor => { | 337 | (Ty::Apply(a_ty1), Ty::Apply(a_ty2)) if a_ty1.ctor == a_ty2.ctor => { |
283 | self.unify_substs(&a_ty1.parameters, &a_ty2.parameters, depth + 1) | 338 | self.unify_substs(&a_ty1.parameters, &a_ty2.parameters, depth + 1) |
284 | } | 339 | } |
340 | _ => self.unify_inner_trivial(&ty1, &ty2), | ||
341 | } | ||
342 | } | ||
343 | |||
344 | fn unify_inner_trivial(&mut self, ty1: &Ty, ty2: &Ty) -> bool { | ||
345 | match (ty1, ty2) { | ||
346 | (Ty::Unknown, _) | (_, Ty::Unknown) => true, | ||
347 | |||
285 | (Ty::Infer(InferTy::TypeVar(tv1)), Ty::Infer(InferTy::TypeVar(tv2))) | 348 | (Ty::Infer(InferTy::TypeVar(tv1)), Ty::Infer(InferTy::TypeVar(tv2))) |
286 | | (Ty::Infer(InferTy::IntVar(tv1)), Ty::Infer(InferTy::IntVar(tv2))) | 349 | | (Ty::Infer(InferTy::IntVar(tv1)), Ty::Infer(InferTy::IntVar(tv2))) |
287 | | (Ty::Infer(InferTy::FloatVar(tv1)), Ty::Infer(InferTy::FloatVar(tv2))) => { | 350 | | (Ty::Infer(InferTy::FloatVar(tv1)), Ty::Infer(InferTy::FloatVar(tv2))) |
351 | | ( | ||
352 | Ty::Infer(InferTy::MaybeNeverTypeVar(tv1)), | ||
353 | Ty::Infer(InferTy::MaybeNeverTypeVar(tv2)), | ||
354 | ) => { | ||
288 | // both type vars are unknown since we tried to resolve them | 355 | // both type vars are unknown since we tried to resolve them |
289 | self.var_unification_table.union(*tv1, *tv2); | 356 | self.var_unification_table.union(*tv1, *tv2); |
290 | true | 357 | true |
291 | } | 358 | } |
359 | |||
360 | // The order of MaybeNeverTypeVar matters here. | ||
361 | // Unifying MaybeNeverTypeVar and TypeVar will let the latter become MaybeNeverTypeVar. | ||
362 | // Unifying MaybeNeverTypeVar and other concrete type will let the former become it. | ||
292 | (Ty::Infer(InferTy::TypeVar(tv)), other) | 363 | (Ty::Infer(InferTy::TypeVar(tv)), other) |
293 | | (other, Ty::Infer(InferTy::TypeVar(tv))) | 364 | | (other, Ty::Infer(InferTy::TypeVar(tv))) |
294 | | (Ty::Infer(InferTy::IntVar(tv)), other) | 365 | | (Ty::Infer(InferTy::MaybeNeverTypeVar(tv)), other) |
295 | | (other, Ty::Infer(InferTy::IntVar(tv))) | 366 | | (other, Ty::Infer(InferTy::MaybeNeverTypeVar(tv))) |
296 | | (Ty::Infer(InferTy::FloatVar(tv)), other) | 367 | | (Ty::Infer(InferTy::IntVar(tv)), other @ ty_app!(TypeCtor::Int(_))) |
297 | | (other, Ty::Infer(InferTy::FloatVar(tv))) => { | 368 | | (other @ ty_app!(TypeCtor::Int(_)), Ty::Infer(InferTy::IntVar(tv))) |
369 | | (Ty::Infer(InferTy::FloatVar(tv)), other @ ty_app!(TypeCtor::Float(_))) | ||
370 | | (other @ ty_app!(TypeCtor::Float(_)), Ty::Infer(InferTy::FloatVar(tv))) => { | ||
298 | // the type var is unknown since we tried to resolve it | 371 | // the type var is unknown since we tried to resolve it |
299 | self.var_unification_table.union_value(*tv, TypeVarValue::Known(other.clone())); | 372 | self.var_unification_table.union_value(*tv, TypeVarValue::Known(other.clone())); |
300 | true | 373 | true |
301 | } | 374 | } |
375 | |||
302 | _ => false, | 376 | _ => false, |
303 | } | 377 | } |
304 | } | 378 | } |
@@ -315,6 +389,12 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { | |||
315 | Ty::Infer(InferTy::FloatVar(self.var_unification_table.new_key(TypeVarValue::Unknown))) | 389 | Ty::Infer(InferTy::FloatVar(self.var_unification_table.new_key(TypeVarValue::Unknown))) |
316 | } | 390 | } |
317 | 391 | ||
392 | fn new_maybe_never_type_var(&mut self) -> Ty { | ||
393 | Ty::Infer(InferTy::MaybeNeverTypeVar( | ||
394 | self.var_unification_table.new_key(TypeVarValue::Unknown), | ||
395 | )) | ||
396 | } | ||
397 | |||
318 | /// Replaces Ty::Unknown by a new type var, so we can maybe still infer it. | 398 | /// Replaces Ty::Unknown by a new type var, so we can maybe still infer it. |
319 | fn insert_type_vars_shallow(&mut self, ty: Ty) -> Ty { | 399 | fn insert_type_vars_shallow(&mut self, ty: Ty) -> Ty { |
320 | match ty { | 400 | match ty { |
@@ -795,17 +875,304 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { | |||
795 | ret_ty | 875 | ret_ty |
796 | } | 876 | } |
797 | 877 | ||
798 | /// This is similar to unify, but it makes the first type coerce to the | 878 | /// Infer type of expression with possibly implicit coerce to the expected type. |
799 | /// second one. | 879 | /// Return the type after possible coercion. |
800 | fn coerce(&mut self, from_ty: &Ty, to_ty: &Ty) -> bool { | 880 | fn infer_expr_coerce(&mut self, expr: ExprId, expected: &Expectation) -> Ty { |
801 | if is_never(from_ty) { | 881 | let ty = self.infer_expr_inner(expr, &expected); |
802 | // ! coerces to any type | 882 | let ty = if !self.coerce(&ty, &expected.ty) { |
803 | true | 883 | self.result |
884 | .type_mismatches | ||
885 | .insert(expr, TypeMismatch { expected: expected.ty.clone(), actual: ty.clone() }); | ||
886 | // Return actual type when type mismatch. | ||
887 | // This is needed for diagnostic when return type mismatch. | ||
888 | ty | ||
889 | } else if expected.ty == Ty::Unknown { | ||
890 | ty | ||
804 | } else { | 891 | } else { |
805 | self.unify(from_ty, to_ty) | 892 | expected.ty.clone() |
893 | }; | ||
894 | |||
895 | self.resolve_ty_as_possible(&mut vec![], ty) | ||
896 | } | ||
897 | |||
898 | /// Merge two types from different branches, with possible implicit coerce. | ||
899 | /// | ||
900 | /// Note that it is only possible that one type are coerced to another. | ||
901 | /// Coercing both types to another least upper bound type is not possible in rustc, | ||
902 | /// which will simply result in "incompatible types" error. | ||
903 | fn coerce_merge_branch<'t>(&mut self, ty1: &Ty, ty2: &Ty) -> Ty { | ||
904 | if self.coerce(ty1, ty2) { | ||
905 | ty2.clone() | ||
906 | } else if self.coerce(ty2, ty1) { | ||
907 | ty1.clone() | ||
908 | } else { | ||
909 | tested_by!(coerce_merge_fail_fallback); | ||
910 | // For incompatible types, we use the latter one as result | ||
911 | // to be better recovery for `if` without `else`. | ||
912 | ty2.clone() | ||
913 | } | ||
914 | } | ||
915 | |||
916 | /// Unify two types, but may coerce the first one to the second one | ||
917 | /// using "implicit coercion rules" if needed. | ||
918 | /// | ||
919 | /// See: https://doc.rust-lang.org/nomicon/coercions.html | ||
920 | fn coerce(&mut self, from_ty: &Ty, to_ty: &Ty) -> bool { | ||
921 | let from_ty = self.resolve_ty_shallow(from_ty).into_owned(); | ||
922 | let to_ty = self.resolve_ty_shallow(to_ty); | ||
923 | self.coerce_inner(from_ty, &to_ty) | ||
924 | } | ||
925 | |||
926 | fn coerce_inner(&mut self, mut from_ty: Ty, to_ty: &Ty) -> bool { | ||
927 | match (&from_ty, to_ty) { | ||
928 | // Never type will make type variable to fallback to Never Type instead of Unknown. | ||
929 | (ty_app!(TypeCtor::Never), Ty::Infer(InferTy::TypeVar(tv))) => { | ||
930 | let var = self.new_maybe_never_type_var(); | ||
931 | self.var_unification_table.union_value(*tv, TypeVarValue::Known(var)); | ||
932 | return true; | ||
933 | } | ||
934 | (ty_app!(TypeCtor::Never), _) => return true, | ||
935 | |||
936 | // Trivial cases, this should go after `never` check to | ||
937 | // avoid infer result type to be never | ||
938 | _ => { | ||
939 | if self.unify_inner_trivial(&from_ty, &to_ty) { | ||
940 | return true; | ||
941 | } | ||
942 | } | ||
943 | } | ||
944 | |||
945 | // Pointer weakening and function to pointer | ||
946 | match (&mut from_ty, to_ty) { | ||
947 | // `*mut T`, `&mut T, `&T`` -> `*const T` | ||
948 | // `&mut T` -> `&T` | ||
949 | // `&mut T` -> `*mut T` | ||
950 | (ty_app!(c1@TypeCtor::RawPtr(_)), ty_app!(c2@TypeCtor::RawPtr(Mutability::Shared))) | ||
951 | | (ty_app!(c1@TypeCtor::Ref(_)), ty_app!(c2@TypeCtor::RawPtr(Mutability::Shared))) | ||
952 | | (ty_app!(c1@TypeCtor::Ref(_)), ty_app!(c2@TypeCtor::Ref(Mutability::Shared))) | ||
953 | | (ty_app!(c1@TypeCtor::Ref(Mutability::Mut)), ty_app!(c2@TypeCtor::RawPtr(_))) => { | ||
954 | *c1 = *c2; | ||
955 | } | ||
956 | |||
957 | // Illegal mutablity conversion | ||
958 | ( | ||
959 | ty_app!(TypeCtor::RawPtr(Mutability::Shared)), | ||
960 | ty_app!(TypeCtor::RawPtr(Mutability::Mut)), | ||
961 | ) | ||
962 | | ( | ||
963 | ty_app!(TypeCtor::Ref(Mutability::Shared)), | ||
964 | ty_app!(TypeCtor::Ref(Mutability::Mut)), | ||
965 | ) => return false, | ||
966 | |||
967 | // `{function_type}` -> `fn()` | ||
968 | (ty_app!(TypeCtor::FnDef(_)), ty_app!(TypeCtor::FnPtr { .. })) => { | ||
969 | match from_ty.callable_sig(self.db) { | ||
970 | None => return false, | ||
971 | Some(sig) => { | ||
972 | let num_args = sig.params_and_return.len() as u16 - 1; | ||
973 | from_ty = | ||
974 | Ty::apply(TypeCtor::FnPtr { num_args }, Substs(sig.params_and_return)); | ||
975 | } | ||
976 | } | ||
977 | } | ||
978 | |||
979 | _ => {} | ||
980 | } | ||
981 | |||
982 | if let Some(ret) = self.try_coerce_unsized(&from_ty, &to_ty) { | ||
983 | return ret; | ||
984 | } | ||
985 | |||
986 | // Auto Deref if cannot coerce | ||
987 | match (&from_ty, to_ty) { | ||
988 | // FIXME: DerefMut | ||
989 | (ty_app!(TypeCtor::Ref(_), st1), ty_app!(TypeCtor::Ref(_), st2)) => { | ||
990 | self.unify_autoderef_behind_ref(&st1[0], &st2[0]) | ||
991 | } | ||
992 | |||
993 | // Otherwise, normal unify | ||
994 | _ => self.unify(&from_ty, to_ty), | ||
995 | } | ||
996 | } | ||
997 | |||
998 | /// Coerce a type using `from_ty: CoerceUnsized<ty_ty>` | ||
999 | /// | ||
1000 | /// See: https://doc.rust-lang.org/nightly/std/marker/trait.CoerceUnsized.html | ||
1001 | fn try_coerce_unsized(&mut self, from_ty: &Ty, to_ty: &Ty) -> Option<bool> { | ||
1002 | let (ctor1, st1, ctor2, st2) = match (from_ty, to_ty) { | ||
1003 | (ty_app!(ctor1, st1), ty_app!(ctor2, st2)) => (ctor1, st1, ctor2, st2), | ||
1004 | _ => return None, | ||
1005 | }; | ||
1006 | |||
1007 | let coerce_generic_index = *self.coerce_unsized_map.get(&(*ctor1, *ctor2))?; | ||
1008 | |||
1009 | // Check `Unsize` first | ||
1010 | match self.check_unsize_and_coerce( | ||
1011 | st1.0.get(coerce_generic_index)?, | ||
1012 | st2.0.get(coerce_generic_index)?, | ||
1013 | 0, | ||
1014 | ) { | ||
1015 | Some(true) => {} | ||
1016 | ret => return ret, | ||
1017 | } | ||
1018 | |||
1019 | let ret = st1 | ||
1020 | .iter() | ||
1021 | .zip(st2.iter()) | ||
1022 | .enumerate() | ||
1023 | .filter(|&(idx, _)| idx != coerce_generic_index) | ||
1024 | .all(|(_, (ty1, ty2))| self.unify(ty1, ty2)); | ||
1025 | |||
1026 | Some(ret) | ||
1027 | } | ||
1028 | |||
1029 | /// Check if `from_ty: Unsize<to_ty>`, and coerce to `to_ty` if it holds. | ||
1030 | /// | ||
1031 | /// It should not be directly called. It is only used by `try_coerce_unsized`. | ||
1032 | /// | ||
1033 | /// See: https://doc.rust-lang.org/nightly/std/marker/trait.Unsize.html | ||
1034 | fn check_unsize_and_coerce(&mut self, from_ty: &Ty, to_ty: &Ty, depth: usize) -> Option<bool> { | ||
1035 | if depth > 1000 { | ||
1036 | panic!("Infinite recursion in coercion"); | ||
1037 | } | ||
1038 | |||
1039 | match (&from_ty, &to_ty) { | ||
1040 | // `[T; N]` -> `[T]` | ||
1041 | (ty_app!(TypeCtor::Array, st1), ty_app!(TypeCtor::Slice, st2)) => { | ||
1042 | Some(self.unify(&st1[0], &st2[0])) | ||
1043 | } | ||
1044 | |||
1045 | // `T` -> `dyn Trait` when `T: Trait` | ||
1046 | (_, Ty::Dyn(_)) => { | ||
1047 | // FIXME: Check predicates | ||
1048 | Some(true) | ||
1049 | } | ||
1050 | |||
1051 | // `(..., T)` -> `(..., U)` when `T: Unsize<U>` | ||
1052 | ( | ||
1053 | ty_app!(TypeCtor::Tuple { cardinality: len1 }, st1), | ||
1054 | ty_app!(TypeCtor::Tuple { cardinality: len2 }, st2), | ||
1055 | ) => { | ||
1056 | if len1 != len2 || *len1 == 0 { | ||
1057 | return None; | ||
1058 | } | ||
1059 | |||
1060 | match self.check_unsize_and_coerce( | ||
1061 | st1.last().unwrap(), | ||
1062 | st2.last().unwrap(), | ||
1063 | depth + 1, | ||
1064 | ) { | ||
1065 | Some(true) => {} | ||
1066 | ret => return ret, | ||
1067 | } | ||
1068 | |||
1069 | let ret = st1[..st1.len() - 1] | ||
1070 | .iter() | ||
1071 | .zip(&st2[..st2.len() - 1]) | ||
1072 | .all(|(ty1, ty2)| self.unify(ty1, ty2)); | ||
1073 | |||
1074 | Some(ret) | ||
1075 | } | ||
1076 | |||
1077 | // Foo<..., T, ...> is Unsize<Foo<..., U, ...>> if: | ||
1078 | // - T: Unsize<U> | ||
1079 | // - Foo is a struct | ||
1080 | // - Only the last field of Foo has a type involving T | ||
1081 | // - T is not part of the type of any other fields | ||
1082 | // - Bar<T>: Unsize<Bar<U>>, if the last field of Foo has type Bar<T> | ||
1083 | ( | ||
1084 | ty_app!(TypeCtor::Adt(Adt::Struct(struct1)), st1), | ||
1085 | ty_app!(TypeCtor::Adt(Adt::Struct(struct2)), st2), | ||
1086 | ) if struct1 == struct2 => { | ||
1087 | let fields = struct1.fields(self.db); | ||
1088 | let (last_field, prev_fields) = fields.split_last()?; | ||
1089 | |||
1090 | // Get the generic parameter involved in the last field. | ||
1091 | let unsize_generic_index = { | ||
1092 | let mut index = None; | ||
1093 | let mut multiple_param = false; | ||
1094 | last_field.ty(self.db).walk(&mut |ty| match ty { | ||
1095 | &Ty::Param { idx, .. } => { | ||
1096 | if index.is_none() { | ||
1097 | index = Some(idx); | ||
1098 | } else if Some(idx) != index { | ||
1099 | multiple_param = true; | ||
1100 | } | ||
1101 | } | ||
1102 | _ => {} | ||
1103 | }); | ||
1104 | |||
1105 | if multiple_param { | ||
1106 | return None; | ||
1107 | } | ||
1108 | index? | ||
1109 | }; | ||
1110 | |||
1111 | // Check other fields do not involve it. | ||
1112 | let mut multiple_used = false; | ||
1113 | prev_fields.iter().for_each(|field| { | ||
1114 | field.ty(self.db).walk(&mut |ty| match ty { | ||
1115 | &Ty::Param { idx, .. } if idx == unsize_generic_index => { | ||
1116 | multiple_used = true | ||
1117 | } | ||
1118 | _ => {} | ||
1119 | }) | ||
1120 | }); | ||
1121 | if multiple_used { | ||
1122 | return None; | ||
1123 | } | ||
1124 | |||
1125 | let unsize_generic_index = unsize_generic_index as usize; | ||
1126 | |||
1127 | // Check `Unsize` first | ||
1128 | match self.check_unsize_and_coerce( | ||
1129 | st1.get(unsize_generic_index)?, | ||
1130 | st2.get(unsize_generic_index)?, | ||
1131 | depth + 1, | ||
1132 | ) { | ||
1133 | Some(true) => {} | ||
1134 | ret => return ret, | ||
1135 | } | ||
1136 | |||
1137 | // Then unify other parameters | ||
1138 | let ret = st1 | ||
1139 | .iter() | ||
1140 | .zip(st2.iter()) | ||
1141 | .enumerate() | ||
1142 | .filter(|&(idx, _)| idx != unsize_generic_index) | ||
1143 | .all(|(_, (ty1, ty2))| self.unify(ty1, ty2)); | ||
1144 | |||
1145 | Some(ret) | ||
1146 | } | ||
1147 | |||
1148 | _ => None, | ||
806 | } | 1149 | } |
807 | } | 1150 | } |
808 | 1151 | ||
1152 | /// Unify `from_ty` to `to_ty` with optional auto Deref | ||
1153 | /// | ||
1154 | /// Note that the parameters are already stripped the outer reference. | ||
1155 | fn unify_autoderef_behind_ref(&mut self, from_ty: &Ty, to_ty: &Ty) -> bool { | ||
1156 | let canonicalized = self.canonicalizer().canonicalize_ty(from_ty.clone()); | ||
1157 | let to_ty = self.resolve_ty_shallow(&to_ty); | ||
1158 | // FIXME: Auto DerefMut | ||
1159 | for derefed_ty in | ||
1160 | autoderef::autoderef(self.db, &self.resolver.clone(), canonicalized.value.clone()) | ||
1161 | { | ||
1162 | let derefed_ty = canonicalized.decanonicalize_ty(derefed_ty.value); | ||
1163 | match (&*self.resolve_ty_shallow(&derefed_ty), &*to_ty) { | ||
1164 | // Stop when constructor matches. | ||
1165 | (ty_app!(from_ctor, st1), ty_app!(to_ctor, st2)) if from_ctor == to_ctor => { | ||
1166 | // It will not recurse to `coerce`. | ||
1167 | return self.unify_substs(st1, st2, 0); | ||
1168 | } | ||
1169 | _ => {} | ||
1170 | } | ||
1171 | } | ||
1172 | |||
1173 | false | ||
1174 | } | ||
1175 | |||
809 | fn infer_expr(&mut self, tgt_expr: ExprId, expected: &Expectation) -> Ty { | 1176 | fn infer_expr(&mut self, tgt_expr: ExprId, expected: &Expectation) -> Ty { |
810 | let ty = self.infer_expr_inner(tgt_expr, expected); | 1177 | let ty = self.infer_expr_inner(tgt_expr, expected); |
811 | let could_unify = self.unify(&ty, &expected.ty); | 1178 | let could_unify = self.unify(&ty, &expected.ty); |
@@ -828,15 +1195,12 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { | |||
828 | self.infer_expr(*condition, &Expectation::has_type(Ty::simple(TypeCtor::Bool))); | 1195 | self.infer_expr(*condition, &Expectation::has_type(Ty::simple(TypeCtor::Bool))); |
829 | 1196 | ||
830 | let then_ty = self.infer_expr_inner(*then_branch, &expected); | 1197 | let then_ty = self.infer_expr_inner(*then_branch, &expected); |
831 | self.coerce(&then_ty, &expected.ty); | ||
832 | |||
833 | let else_ty = match else_branch { | 1198 | let else_ty = match else_branch { |
834 | Some(else_branch) => self.infer_expr_inner(*else_branch, &expected), | 1199 | Some(else_branch) => self.infer_expr_inner(*else_branch, &expected), |
835 | None => Ty::unit(), | 1200 | None => Ty::unit(), |
836 | }; | 1201 | }; |
837 | self.coerce(&else_ty, &expected.ty); | ||
838 | 1202 | ||
839 | expected.ty.clone() | 1203 | self.coerce_merge_branch(&then_ty, &else_ty) |
840 | } | 1204 | } |
841 | Expr::Block { statements, tail } => self.infer_block(statements, *tail, expected), | 1205 | Expr::Block { statements, tail } => self.infer_block(statements, *tail, expected), |
842 | Expr::TryBlock { body } => { | 1206 | Expr::TryBlock { body } => { |
@@ -932,13 +1296,8 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { | |||
932 | .infer_method_call(tgt_expr, *receiver, &args, &method_name, generic_args.as_ref()), | 1296 | .infer_method_call(tgt_expr, *receiver, &args, &method_name, generic_args.as_ref()), |
933 | Expr::Match { expr, arms } => { | 1297 | Expr::Match { expr, arms } => { |
934 | let input_ty = self.infer_expr(*expr, &Expectation::none()); | 1298 | let input_ty = self.infer_expr(*expr, &Expectation::none()); |
935 | let expected = if expected.ty == Ty::Unknown { | ||
936 | Expectation::has_type(self.new_type_var()) | ||
937 | } else { | ||
938 | expected.clone() | ||
939 | }; | ||
940 | 1299 | ||
941 | let mut arm_tys = Vec::with_capacity(arms.len()); | 1300 | let mut result_ty = self.new_maybe_never_type_var(); |
942 | 1301 | ||
943 | for arm in arms { | 1302 | for arm in arms { |
944 | for &pat in &arm.pats { | 1303 | for &pat in &arm.pats { |
@@ -950,16 +1309,12 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { | |||
950 | &Expectation::has_type(Ty::simple(TypeCtor::Bool)), | 1309 | &Expectation::has_type(Ty::simple(TypeCtor::Bool)), |
951 | ); | 1310 | ); |
952 | } | 1311 | } |
953 | arm_tys.push(self.infer_expr_inner(arm.expr, &expected)); | ||
954 | } | ||
955 | |||
956 | let lub_ty = calculate_least_upper_bound(expected.ty, &arm_tys); | ||
957 | 1312 | ||
958 | for arm_ty in &arm_tys { | 1313 | let arm_ty = self.infer_expr_inner(arm.expr, &expected); |
959 | self.coerce(arm_ty, &lub_ty); | 1314 | result_ty = self.coerce_merge_branch(&result_ty, &arm_ty); |
960 | } | 1315 | } |
961 | 1316 | ||
962 | lub_ty | 1317 | result_ty |
963 | } | 1318 | } |
964 | Expr::Path(p) => { | 1319 | Expr::Path(p) => { |
965 | // FIXME this could be more efficient... | 1320 | // FIXME this could be more efficient... |
@@ -986,6 +1341,8 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { | |||
986 | self.write_variant_resolution(tgt_expr.into(), variant); | 1341 | self.write_variant_resolution(tgt_expr.into(), variant); |
987 | } | 1342 | } |
988 | 1343 | ||
1344 | self.unify(&ty, &expected.ty); | ||
1345 | |||
989 | let substs = ty.substs().unwrap_or_else(Substs::empty); | 1346 | let substs = ty.substs().unwrap_or_else(Substs::empty); |
990 | for (field_idx, field) in fields.iter().enumerate() { | 1347 | for (field_idx, field) in fields.iter().enumerate() { |
991 | let field_ty = def_id | 1348 | let field_ty = def_id |
@@ -1001,7 +1358,7 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { | |||
1001 | }) | 1358 | }) |
1002 | .map_or(Ty::Unknown, |field| field.ty(self.db)) | 1359 | .map_or(Ty::Unknown, |field| field.ty(self.db)) |
1003 | .subst(&substs); | 1360 | .subst(&substs); |
1004 | self.infer_expr(field.expr, &Expectation::has_type(field_ty)); | 1361 | self.infer_expr_coerce(field.expr, &Expectation::has_type(field_ty)); |
1005 | } | 1362 | } |
1006 | if let Some(expr) = spread { | 1363 | if let Some(expr) = spread { |
1007 | self.infer_expr(*expr, &Expectation::has_type(ty.clone())); | 1364 | self.infer_expr(*expr, &Expectation::has_type(ty.clone())); |
@@ -1171,35 +1528,41 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { | |||
1171 | Ty::Unknown | 1528 | Ty::Unknown |
1172 | } | 1529 | } |
1173 | Expr::Tuple { exprs } => { | 1530 | Expr::Tuple { exprs } => { |
1174 | let mut ty_vec = Vec::with_capacity(exprs.len()); | 1531 | let mut tys = match &expected.ty { |
1175 | for arg in exprs.iter() { | 1532 | ty_app!(TypeCtor::Tuple { .. }, st) => st |
1176 | ty_vec.push(self.infer_expr(*arg, &Expectation::none())); | 1533 | .iter() |
1534 | .cloned() | ||
1535 | .chain(repeat_with(|| self.new_type_var())) | ||
1536 | .take(exprs.len()) | ||
1537 | .collect::<Vec<_>>(), | ||
1538 | _ => (0..exprs.len()).map(|_| self.new_type_var()).collect(), | ||
1539 | }; | ||
1540 | |||
1541 | for (expr, ty) in exprs.iter().zip(tys.iter_mut()) { | ||
1542 | self.infer_expr_coerce(*expr, &Expectation::has_type(ty.clone())); | ||
1177 | } | 1543 | } |
1178 | 1544 | ||
1179 | Ty::apply( | 1545 | Ty::apply(TypeCtor::Tuple { cardinality: tys.len() as u16 }, Substs(tys.into())) |
1180 | TypeCtor::Tuple { cardinality: ty_vec.len() as u16 }, | ||
1181 | Substs(ty_vec.into()), | ||
1182 | ) | ||
1183 | } | 1546 | } |
1184 | Expr::Array(array) => { | 1547 | Expr::Array(array) => { |
1185 | let elem_ty = match &expected.ty { | 1548 | let elem_ty = match &expected.ty { |
1186 | Ty::Apply(a_ty) => match a_ty.ctor { | 1549 | ty_app!(TypeCtor::Array, st) | ty_app!(TypeCtor::Slice, st) => { |
1187 | TypeCtor::Slice | TypeCtor::Array => { | 1550 | st.as_single().clone() |
1188 | Ty::clone(&a_ty.parameters.as_single()) | 1551 | } |
1189 | } | ||
1190 | _ => self.new_type_var(), | ||
1191 | }, | ||
1192 | _ => self.new_type_var(), | 1552 | _ => self.new_type_var(), |
1193 | }; | 1553 | }; |
1194 | 1554 | ||
1195 | match array { | 1555 | match array { |
1196 | Array::ElementList(items) => { | 1556 | Array::ElementList(items) => { |
1197 | for expr in items.iter() { | 1557 | for expr in items.iter() { |
1198 | self.infer_expr(*expr, &Expectation::has_type(elem_ty.clone())); | 1558 | self.infer_expr_coerce(*expr, &Expectation::has_type(elem_ty.clone())); |
1199 | } | 1559 | } |
1200 | } | 1560 | } |
1201 | Array::Repeat { initializer, repeat } => { | 1561 | Array::Repeat { initializer, repeat } => { |
1202 | self.infer_expr(*initializer, &Expectation::has_type(elem_ty.clone())); | 1562 | self.infer_expr_coerce( |
1563 | *initializer, | ||
1564 | &Expectation::has_type(elem_ty.clone()), | ||
1565 | ); | ||
1203 | self.infer_expr( | 1566 | self.infer_expr( |
1204 | *repeat, | 1567 | *repeat, |
1205 | &Expectation::has_type(Ty::simple(TypeCtor::Int( | 1568 | &Expectation::has_type(Ty::simple(TypeCtor::Int( |
@@ -1246,14 +1609,19 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { | |||
1246 | Statement::Let { pat, type_ref, initializer } => { | 1609 | Statement::Let { pat, type_ref, initializer } => { |
1247 | let decl_ty = | 1610 | let decl_ty = |
1248 | type_ref.as_ref().map(|tr| self.make_ty(tr)).unwrap_or(Ty::Unknown); | 1611 | type_ref.as_ref().map(|tr| self.make_ty(tr)).unwrap_or(Ty::Unknown); |
1249 | let decl_ty = self.insert_type_vars(decl_ty); | ||
1250 | let ty = if let Some(expr) = initializer { | ||
1251 | let expr_ty = self.infer_expr(*expr, &Expectation::has_type(decl_ty)); | ||
1252 | expr_ty | ||
1253 | } else { | ||
1254 | decl_ty | ||
1255 | }; | ||
1256 | 1612 | ||
1613 | // Always use the declared type when specified | ||
1614 | let mut ty = decl_ty.clone(); | ||
1615 | |||
1616 | if let Some(expr) = initializer { | ||
1617 | let actual_ty = | ||
1618 | self.infer_expr_coerce(*expr, &Expectation::has_type(decl_ty.clone())); | ||
1619 | if decl_ty == Ty::Unknown { | ||
1620 | ty = actual_ty; | ||
1621 | } | ||
1622 | } | ||
1623 | |||
1624 | let ty = self.resolve_ty_as_possible(&mut vec![], ty); | ||
1257 | self.infer_pat(*pat, &ty, BindingMode::default()); | 1625 | self.infer_pat(*pat, &ty, BindingMode::default()); |
1258 | } | 1626 | } |
1259 | Statement::Expr(expr) => { | 1627 | Statement::Expr(expr) => { |
@@ -1261,9 +1629,13 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { | |||
1261 | } | 1629 | } |
1262 | } | 1630 | } |
1263 | } | 1631 | } |
1264 | let ty = | 1632 | |
1265 | if let Some(expr) = tail { self.infer_expr_inner(expr, expected) } else { Ty::unit() }; | 1633 | if let Some(expr) = tail { |
1266 | ty | 1634 | self.infer_expr_coerce(expr, expected) |
1635 | } else { | ||
1636 | self.coerce(&Ty::unit(), &expected.ty); | ||
1637 | Ty::unit() | ||
1638 | } | ||
1267 | } | 1639 | } |
1268 | 1640 | ||
1269 | fn check_call_arguments(&mut self, args: &[ExprId], param_tys: &[Ty]) { | 1641 | fn check_call_arguments(&mut self, args: &[ExprId], param_tys: &[Ty]) { |
@@ -1285,7 +1657,7 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { | |||
1285 | } | 1657 | } |
1286 | 1658 | ||
1287 | let param_ty = self.normalize_associated_types_in(param_ty); | 1659 | let param_ty = self.normalize_associated_types_in(param_ty); |
1288 | self.infer_expr(arg, &Expectation::has_type(param_ty)); | 1660 | self.infer_expr_coerce(arg, &Expectation::has_type(param_ty.clone())); |
1289 | } | 1661 | } |
1290 | } | 1662 | } |
1291 | } | 1663 | } |
@@ -1400,12 +1772,16 @@ pub enum InferTy { | |||
1400 | TypeVar(TypeVarId), | 1772 | TypeVar(TypeVarId), |
1401 | IntVar(TypeVarId), | 1773 | IntVar(TypeVarId), |
1402 | FloatVar(TypeVarId), | 1774 | FloatVar(TypeVarId), |
1775 | MaybeNeverTypeVar(TypeVarId), | ||
1403 | } | 1776 | } |
1404 | 1777 | ||
1405 | impl InferTy { | 1778 | impl InferTy { |
1406 | fn to_inner(self) -> TypeVarId { | 1779 | fn to_inner(self) -> TypeVarId { |
1407 | match self { | 1780 | match self { |
1408 | InferTy::TypeVar(ty) | InferTy::IntVar(ty) | InferTy::FloatVar(ty) => ty, | 1781 | InferTy::TypeVar(ty) |
1782 | | InferTy::IntVar(ty) | ||
1783 | | InferTy::FloatVar(ty) | ||
1784 | | InferTy::MaybeNeverTypeVar(ty) => ty, | ||
1409 | } | 1785 | } |
1410 | } | 1786 | } |
1411 | 1787 | ||
@@ -1418,6 +1794,7 @@ impl InferTy { | |||
1418 | InferTy::FloatVar(..) => Ty::simple(TypeCtor::Float( | 1794 | InferTy::FloatVar(..) => Ty::simple(TypeCtor::Float( |
1419 | primitive::UncertainFloatTy::Known(primitive::FloatTy::f64()), | 1795 | primitive::UncertainFloatTy::Known(primitive::FloatTy::f64()), |
1420 | )), | 1796 | )), |
1797 | InferTy::MaybeNeverTypeVar(..) => Ty::simple(TypeCtor::Never), | ||
1421 | } | 1798 | } |
1422 | } | 1799 | } |
1423 | } | 1800 | } |
@@ -1475,37 +1852,3 @@ mod diagnostics { | |||
1475 | } | 1852 | } |
1476 | } | 1853 | } |
1477 | } | 1854 | } |
1478 | |||
1479 | fn is_never(ty: &Ty) -> bool { | ||
1480 | if let Ty::Apply(ApplicationTy { ctor: TypeCtor::Never, .. }) = ty { | ||
1481 | true | ||
1482 | } else { | ||
1483 | false | ||
1484 | } | ||
1485 | } | ||
1486 | |||
1487 | fn calculate_least_upper_bound(expected_ty: Ty, actual_tys: &[Ty]) -> Ty { | ||
1488 | let mut all_never = true; | ||
1489 | let mut last_never_ty = None; | ||
1490 | let mut least_upper_bound = expected_ty; | ||
1491 | |||
1492 | for actual_ty in actual_tys { | ||
1493 | if is_never(actual_ty) { | ||
1494 | last_never_ty = Some(actual_ty.clone()); | ||
1495 | } else { | ||
1496 | all_never = false; | ||
1497 | least_upper_bound = match (actual_ty, &least_upper_bound) { | ||
1498 | (_, Ty::Unknown) | ||
1499 | | (Ty::Infer(_), Ty::Infer(InferTy::TypeVar(_))) | ||
1500 | | (Ty::Apply(_), _) => actual_ty.clone(), | ||
1501 | _ => least_upper_bound, | ||
1502 | } | ||
1503 | } | ||
1504 | } | ||
1505 | |||
1506 | if all_never && last_never_ty.is_some() { | ||
1507 | last_never_ty.unwrap() | ||
1508 | } else { | ||
1509 | least_upper_bound | ||
1510 | } | ||
1511 | } | ||