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 | 26 | ||||
-rw-r--r-- | crates/hir_ty/src/infer/pat.rs | 22 | ||||
-rw-r--r-- | crates/hir_ty/src/infer/unify.rs | 28 |
4 files changed, 46 insertions, 42 deletions
diff --git a/crates/hir_ty/src/infer/coerce.rs b/crates/hir_ty/src/infer/coerce.rs index 36670043a..137419264 100644 --- a/crates/hir_ty/src/infer/coerce.rs +++ b/crates/hir_ty/src/infer/coerce.rs | |||
@@ -71,7 +71,7 @@ impl<'a> InferenceContext<'a> { | |||
71 | } | 71 | } |
72 | 72 | ||
73 | // Pointer weakening and function to pointer | 73 | // Pointer weakening and function to pointer |
74 | match (&mut from_ty.0, to_ty.interned(&Interner)) { | 74 | match (from_ty.interned_mut(), to_ty.interned(&Interner)) { |
75 | // `*mut T` -> `*const T` | 75 | // `*mut T` -> `*const T` |
76 | // `&mut T` -> `&T` | 76 | // `&mut T` -> `&T` |
77 | (TyKind::Raw(m1, ..), TyKind::Raw(m2 @ Mutability::Not, ..)) | 77 | (TyKind::Raw(m1, ..), TyKind::Raw(m2 @ Mutability::Not, ..)) |
@@ -111,9 +111,7 @@ impl<'a> InferenceContext<'a> { | |||
111 | // Auto Deref if cannot coerce | 111 | // Auto Deref if cannot coerce |
112 | match (from_ty.interned(&Interner), to_ty.interned(&Interner)) { | 112 | match (from_ty.interned(&Interner), to_ty.interned(&Interner)) { |
113 | // FIXME: DerefMut | 113 | // FIXME: DerefMut |
114 | (TyKind::Ref(_, st1), TyKind::Ref(_, st2)) => { | 114 | (TyKind::Ref(_, st1), TyKind::Ref(_, st2)) => self.unify_autoderef_behind_ref(st1, st2), |
115 | self.unify_autoderef_behind_ref(&st1[0], &st2[0]) | ||
116 | } | ||
117 | 115 | ||
118 | // Otherwise, normal unify | 116 | // Otherwise, normal unify |
119 | _ => self.unify(&from_ty, to_ty), | 117 | _ => self.unify(&from_ty, to_ty), |
@@ -178,11 +176,7 @@ impl<'a> InferenceContext<'a> { | |||
178 | // Stop when constructor matches. | 176 | // Stop when constructor matches. |
179 | if from_ty.equals_ctor(&to_ty) { | 177 | if from_ty.equals_ctor(&to_ty) { |
180 | // It will not recurse to `coerce`. | 178 | // It will not recurse to `coerce`. |
181 | return match (from_ty.substs(), to_ty.substs()) { | 179 | return self.table.unify(&from_ty, &to_ty); |
182 | (Some(st1), Some(st2)) => self.table.unify_substs(st1, st2, 0), | ||
183 | (None, None) => true, | ||
184 | _ => false, | ||
185 | }; | ||
186 | } else if self.table.unify_inner_trivial(&derefed_ty, &to_ty, 0) { | 180 | } else if self.table.unify_inner_trivial(&derefed_ty, &to_ty, 0) { |
187 | return true; | 181 | return true; |
188 | } | 182 | } |
diff --git a/crates/hir_ty/src/infer/expr.rs b/crates/hir_ty/src/infer/expr.rs index 55163c963..f40dec17f 100644 --- a/crates/hir_ty/src/infer/expr.rs +++ b/crates/hir_ty/src/infer/expr.rs | |||
@@ -405,14 +405,13 @@ impl<'a> InferenceContext<'a> { | |||
405 | let substs = ty.substs().cloned().unwrap_or_else(Substs::empty); | 405 | let substs = ty.substs().cloned().unwrap_or_else(Substs::empty); |
406 | let field_types = def_id.map(|it| self.db.field_types(it)).unwrap_or_default(); | 406 | let field_types = def_id.map(|it| self.db.field_types(it)).unwrap_or_default(); |
407 | let variant_data = def_id.map(|it| variant_data(self.db.upcast(), it)); | 407 | let variant_data = def_id.map(|it| variant_data(self.db.upcast(), it)); |
408 | for (field_idx, field) in fields.iter().enumerate() { | 408 | for field in fields.iter() { |
409 | let field_def = | 409 | let field_def = |
410 | variant_data.as_ref().and_then(|it| match it.field(&field.name) { | 410 | variant_data.as_ref().and_then(|it| match it.field(&field.name) { |
411 | Some(local_id) => Some(FieldId { parent: def_id.unwrap(), local_id }), | 411 | Some(local_id) => Some(FieldId { parent: def_id.unwrap(), local_id }), |
412 | None => { | 412 | None => { |
413 | self.push_diagnostic(InferenceDiagnostic::NoSuchField { | 413 | self.push_diagnostic(InferenceDiagnostic::NoSuchField { |
414 | expr: tgt_expr, | 414 | expr: field.expr, |
415 | field: field_idx, | ||
416 | }); | 415 | }); |
417 | None | 416 | None |
418 | } | 417 | } |
@@ -504,8 +503,8 @@ impl<'a> InferenceContext<'a> { | |||
504 | }; | 503 | }; |
505 | let inner_ty = self.infer_expr_inner(*expr, &expectation); | 504 | let inner_ty = self.infer_expr_inner(*expr, &expectation); |
506 | match rawness { | 505 | match rawness { |
507 | Rawness::RawPtr => TyKind::Raw(mutability, Substs::single(inner_ty)), | 506 | Rawness::RawPtr => TyKind::Raw(mutability, inner_ty), |
508 | Rawness::Ref => TyKind::Ref(mutability, Substs::single(inner_ty)), | 507 | Rawness::Ref => TyKind::Ref(mutability, inner_ty), |
509 | } | 508 | } |
510 | .intern(&Interner) | 509 | .intern(&Interner) |
511 | } | 510 | } |
@@ -686,7 +685,7 @@ impl<'a> InferenceContext<'a> { | |||
686 | } | 685 | } |
687 | Expr::Array(array) => { | 686 | Expr::Array(array) => { |
688 | let elem_ty = match expected.ty.interned(&Interner) { | 687 | let elem_ty = match expected.ty.interned(&Interner) { |
689 | TyKind::Array(st) | TyKind::Slice(st) => st.as_single().clone(), | 688 | TyKind::Array(st) | TyKind::Slice(st) => st.clone(), |
690 | _ => self.table.new_type_var(), | 689 | _ => self.table.new_type_var(), |
691 | }; | 690 | }; |
692 | 691 | ||
@@ -710,18 +709,17 @@ impl<'a> InferenceContext<'a> { | |||
710 | } | 709 | } |
711 | } | 710 | } |
712 | 711 | ||
713 | TyKind::Array(Substs::single(elem_ty)).intern(&Interner) | 712 | TyKind::Array(elem_ty).intern(&Interner) |
714 | } | 713 | } |
715 | Expr::Literal(lit) => match lit { | 714 | Expr::Literal(lit) => match lit { |
716 | Literal::Bool(..) => TyKind::Scalar(Scalar::Bool).intern(&Interner), | 715 | Literal::Bool(..) => TyKind::Scalar(Scalar::Bool).intern(&Interner), |
717 | Literal::String(..) => { | 716 | Literal::String(..) => { |
718 | TyKind::Ref(Mutability::Not, Substs::single(TyKind::Str.intern(&Interner))) | 717 | TyKind::Ref(Mutability::Not, TyKind::Str.intern(&Interner)).intern(&Interner) |
719 | .intern(&Interner) | ||
720 | } | 718 | } |
721 | Literal::ByteString(..) => { | 719 | Literal::ByteString(..) => { |
722 | let byte_type = TyKind::Scalar(Scalar::Uint(UintTy::U8)).intern(&Interner); | 720 | let byte_type = TyKind::Scalar(Scalar::Uint(UintTy::U8)).intern(&Interner); |
723 | let array_type = TyKind::Array(Substs::single(byte_type)).intern(&Interner); | 721 | let array_type = TyKind::Array(byte_type).intern(&Interner); |
724 | TyKind::Ref(Mutability::Not, Substs::single(array_type)).intern(&Interner) | 722 | TyKind::Ref(Mutability::Not, array_type).intern(&Interner) |
725 | } | 723 | } |
726 | Literal::Char(..) => TyKind::Scalar(Scalar::Char).intern(&Interner), | 724 | Literal::Char(..) => TyKind::Scalar(Scalar::Char).intern(&Interner), |
727 | Literal::Int(_v, ty) => match ty { | 725 | Literal::Int(_v, ty) => match ty { |
@@ -800,7 +798,7 @@ impl<'a> InferenceContext<'a> { | |||
800 | // we don't even make an attempt at coercion | 798 | // we don't even make an attempt at coercion |
801 | self.table.new_maybe_never_var() | 799 | self.table.new_maybe_never_var() |
802 | } else { | 800 | } else { |
803 | self.coerce(&Ty::unit(), expected.coercion_target()); | 801 | self.coerce(&Ty::unit(), &expected.coercion_target()); |
804 | Ty::unit() | 802 | Ty::unit() |
805 | } | 803 | } |
806 | }; | 804 | }; |
@@ -855,9 +853,7 @@ impl<'a> InferenceContext<'a> { | |||
855 | // Apply autoref so the below unification works correctly | 853 | // Apply autoref so the below unification works correctly |
856 | // FIXME: return correct autorefs from lookup_method | 854 | // FIXME: return correct autorefs from lookup_method |
857 | let actual_receiver_ty = match expected_receiver_ty.as_reference() { | 855 | let actual_receiver_ty = match expected_receiver_ty.as_reference() { |
858 | Some((_, mutability)) => { | 856 | Some((_, mutability)) => TyKind::Ref(mutability, derefed_receiver_ty).intern(&Interner), |
859 | TyKind::Ref(mutability, Substs::single(derefed_receiver_ty)).intern(&Interner) | ||
860 | } | ||
861 | _ => derefed_receiver_ty, | 857 | _ => derefed_receiver_ty, |
862 | }; | 858 | }; |
863 | self.unify(&expected_receiver_ty, &actual_receiver_ty); | 859 | self.unify(&expected_receiver_ty, &actual_receiver_ty); |
diff --git a/crates/hir_ty/src/infer/pat.rs b/crates/hir_ty/src/infer/pat.rs index a16755cda..9e8ca18ef 100644 --- a/crates/hir_ty/src/infer/pat.rs +++ b/crates/hir_ty/src/infer/pat.rs | |||
@@ -158,12 +158,12 @@ impl<'a> InferenceContext<'a> { | |||
158 | if mutability != exp_mut { | 158 | if mutability != exp_mut { |
159 | // FIXME: emit type error? | 159 | // FIXME: emit type error? |
160 | } | 160 | } |
161 | inner_ty | 161 | inner_ty.clone() |
162 | } | 162 | } |
163 | _ => &Ty(TyKind::Unknown), | 163 | _ => self.result.standard_types.unknown.clone(), |
164 | }; | 164 | }; |
165 | let subty = self.infer_pat(*pat, expectation, default_bm); | 165 | let subty = self.infer_pat(*pat, &expectation, default_bm); |
166 | TyKind::Ref(mutability, Substs::single(subty)).intern(&Interner) | 166 | TyKind::Ref(mutability, subty).intern(&Interner) |
167 | } | 167 | } |
168 | Pat::TupleStruct { path: p, args: subpats, ellipsis } => self.infer_tuple_struct_pat( | 168 | Pat::TupleStruct { path: p, args: subpats, ellipsis } => self.infer_tuple_struct_pat( |
169 | p.as_ref(), | 169 | p.as_ref(), |
@@ -196,7 +196,7 @@ impl<'a> InferenceContext<'a> { | |||
196 | 196 | ||
197 | let bound_ty = match mode { | 197 | let bound_ty = match mode { |
198 | BindingMode::Ref(mutability) => { | 198 | BindingMode::Ref(mutability) => { |
199 | TyKind::Ref(mutability, Substs::single(inner_ty.clone())).intern(&Interner) | 199 | TyKind::Ref(mutability, inner_ty.clone()).intern(&Interner) |
200 | } | 200 | } |
201 | BindingMode::Move => inner_ty.clone(), | 201 | BindingMode::Move => inner_ty.clone(), |
202 | }; | 202 | }; |
@@ -206,8 +206,8 @@ impl<'a> InferenceContext<'a> { | |||
206 | } | 206 | } |
207 | Pat::Slice { prefix, slice, suffix } => { | 207 | Pat::Slice { prefix, slice, suffix } => { |
208 | let (container_ty, elem_ty): (fn(_) -> _, _) = match expected.interned(&Interner) { | 208 | let (container_ty, elem_ty): (fn(_) -> _, _) = match expected.interned(&Interner) { |
209 | TyKind::Array(st) => (TyKind::Array, st.as_single().clone()), | 209 | TyKind::Array(st) => (TyKind::Array, st.clone()), |
210 | TyKind::Slice(st) => (TyKind::Slice, st.as_single().clone()), | 210 | TyKind::Slice(st) => (TyKind::Slice, st.clone()), |
211 | _ => (TyKind::Slice, self.err_ty()), | 211 | _ => (TyKind::Slice, self.err_ty()), |
212 | }; | 212 | }; |
213 | 213 | ||
@@ -215,7 +215,7 @@ impl<'a> InferenceContext<'a> { | |||
215 | self.infer_pat(*pat_id, &elem_ty, default_bm); | 215 | self.infer_pat(*pat_id, &elem_ty, default_bm); |
216 | } | 216 | } |
217 | 217 | ||
218 | let pat_ty = container_ty(Substs::single(elem_ty)).intern(&Interner); | 218 | let pat_ty = container_ty(elem_ty).intern(&Interner); |
219 | if let Some(slice_pat_id) = slice { | 219 | if let Some(slice_pat_id) = slice { |
220 | self.infer_pat(*slice_pat_id, &pat_ty, default_bm); | 220 | self.infer_pat(*slice_pat_id, &pat_ty, default_bm); |
221 | } | 221 | } |
@@ -232,11 +232,11 @@ impl<'a> InferenceContext<'a> { | |||
232 | Pat::Box { inner } => match self.resolve_boxed_box() { | 232 | Pat::Box { inner } => match self.resolve_boxed_box() { |
233 | Some(box_adt) => { | 233 | Some(box_adt) => { |
234 | let inner_expected = match expected.as_adt() { | 234 | let inner_expected = match expected.as_adt() { |
235 | Some((adt, substs)) if adt == box_adt => substs.as_single(), | 235 | Some((adt, substs)) if adt == box_adt => substs.as_single().clone(), |
236 | _ => &Ty(TyKind::Unknown), | 236 | _ => self.result.standard_types.unknown.clone(), |
237 | }; | 237 | }; |
238 | 238 | ||
239 | let inner_ty = self.infer_pat(*inner, inner_expected, default_bm); | 239 | let inner_ty = self.infer_pat(*inner, &inner_expected, default_bm); |
240 | Ty::adt_ty(box_adt, Substs::single(inner_ty)) | 240 | Ty::adt_ty(box_adt, Substs::single(inner_ty)) |
241 | } | 241 | } |
242 | None => self.err_ty(), | 242 | None => self.err_ty(), |
diff --git a/crates/hir_ty/src/infer/unify.rs b/crates/hir_ty/src/infer/unify.rs index ebc612ca9..66f8fe8a3 100644 --- a/crates/hir_ty/src/infer/unify.rs +++ b/crates/hir_ty/src/infer/unify.rs | |||
@@ -7,8 +7,8 @@ use ena::unify::{InPlaceUnificationTable, NoError, UnifyKey, UnifyValue}; | |||
7 | 7 | ||
8 | use super::{InferenceContext, Obligation}; | 8 | use super::{InferenceContext, Obligation}; |
9 | use crate::{ | 9 | use crate::{ |
10 | BoundVar, Canonical, DebruijnIndex, GenericPredicate, InEnvironment, InferenceVar, Interner, | 10 | BoundVar, Canonical, DebruijnIndex, FnPointer, GenericPredicate, InEnvironment, InferenceVar, |
11 | Scalar, Substs, Ty, TyKind, TypeWalk, | 11 | Interner, Scalar, Substs, Ty, TyKind, TypeWalk, |
12 | }; | 12 | }; |
13 | 13 | ||
14 | impl<'a> InferenceContext<'a> { | 14 | impl<'a> InferenceContext<'a> { |
@@ -108,7 +108,7 @@ impl<T> Canonicalized<T> { | |||
108 | pub(super) fn decanonicalize_ty(&self, mut ty: Ty) -> Ty { | 108 | pub(super) fn decanonicalize_ty(&self, mut ty: Ty) -> Ty { |
109 | ty.walk_mut_binders( | 109 | ty.walk_mut_binders( |
110 | &mut |ty, binders| { | 110 | &mut |ty, binders| { |
111 | if let &mut TyKind::BoundVar(bound) = &mut ty.0 { | 111 | if let &mut TyKind::BoundVar(bound) = ty.interned_mut() { |
112 | if bound.debruijn >= binders { | 112 | if bound.debruijn >= binders { |
113 | let (v, k) = self.free_vars[bound.index]; | 113 | let (v, k) = self.free_vars[bound.index]; |
114 | *ty = TyKind::InferenceVar(v, k).intern(&Interner); | 114 | *ty = TyKind::InferenceVar(v, k).intern(&Interner); |
@@ -283,9 +283,23 @@ impl InferenceTable { | |||
283 | let ty1 = self.resolve_ty_shallow(ty1); | 283 | let ty1 = self.resolve_ty_shallow(ty1); |
284 | let ty2 = self.resolve_ty_shallow(ty2); | 284 | let ty2 = self.resolve_ty_shallow(ty2); |
285 | if ty1.equals_ctor(&ty2) { | 285 | if ty1.equals_ctor(&ty2) { |
286 | match (ty1.substs(), ty2.substs()) { | 286 | match (ty1.interned(&Interner), ty2.interned(&Interner)) { |
287 | (Some(st1), Some(st2)) => self.unify_substs(st1, st2, depth + 1), | 287 | (TyKind::Adt(_, substs1), TyKind::Adt(_, substs2)) |
288 | (None, None) => true, | 288 | | (TyKind::FnDef(_, substs1), TyKind::FnDef(_, substs2)) |
289 | | ( | ||
290 | TyKind::Function(FnPointer { substs: substs1, .. }), | ||
291 | TyKind::Function(FnPointer { substs: substs2, .. }), | ||
292 | ) | ||
293 | | (TyKind::Tuple(_, substs1), TyKind::Tuple(_, substs2)) | ||
294 | | (TyKind::OpaqueType(_, substs1), TyKind::OpaqueType(_, substs2)) | ||
295 | | (TyKind::AssociatedType(_, substs1), TyKind::AssociatedType(_, substs2)) | ||
296 | | (TyKind::Closure(.., substs1), TyKind::Closure(.., substs2)) => { | ||
297 | self.unify_substs(substs1, substs2, depth + 1) | ||
298 | } | ||
299 | (TyKind::Ref(_, ty1), TyKind::Ref(_, ty2)) | ||
300 | | (TyKind::Raw(_, ty1), TyKind::Raw(_, ty2)) | ||
301 | | (TyKind::Array(ty1), TyKind::Array(ty2)) | ||
302 | | (TyKind::Slice(ty1), TyKind::Slice(ty2)) => self.unify_inner(ty1, ty2, depth + 1), | ||
289 | _ => false, | 303 | _ => false, |
290 | } | 304 | } |
291 | } else { | 305 | } else { |
@@ -404,7 +418,7 @@ impl InferenceTable { | |||
404 | if i > 0 { | 418 | if i > 0 { |
405 | cov_mark::hit!(type_var_resolves_to_int_var); | 419 | cov_mark::hit!(type_var_resolves_to_int_var); |
406 | } | 420 | } |
407 | match &ty.0 { | 421 | match ty.interned(&Interner) { |
408 | TyKind::InferenceVar(tv, _) => { | 422 | TyKind::InferenceVar(tv, _) => { |
409 | let inner = tv.to_inner(); | 423 | let inner = tv.to_inner(); |
410 | match self.var_unification_table.inlined_probe_value(inner).known() { | 424 | match self.var_unification_table.inlined_probe_value(inner).known() { |