diff options
author | Florian Diebold <[email protected]> | 2021-03-13 13:44:51 +0000 |
---|---|---|
committer | Florian Diebold <[email protected]> | 2021-03-13 15:17:15 +0000 |
commit | 6c32bbf3ca5980fb33c1ea28dd1c5a1524ce81cb (patch) | |
tree | f81c7438f67de3c292a233887e56c7e99bcc0a01 /crates/hir_ty/src/infer/coerce.rs | |
parent | 7accf6bc37c059a83a58c82f463f02a02ed2226f (diff) |
Separate `Ty` and `TyKind` like in Chalk
Currently `Ty` just wraps `TyKind`, but this allows us to change most
places to already use `intern` / `interned`.
Diffstat (limited to 'crates/hir_ty/src/infer/coerce.rs')
-rw-r--r-- | crates/hir_ty/src/infer/coerce.rs | 38 |
1 files changed, 21 insertions, 17 deletions
diff --git a/crates/hir_ty/src/infer/coerce.rs b/crates/hir_ty/src/infer/coerce.rs index 7e8846f27..36670043a 100644 --- a/crates/hir_ty/src/infer/coerce.rs +++ b/crates/hir_ty/src/infer/coerce.rs | |||
@@ -7,7 +7,7 @@ | |||
7 | use chalk_ir::{Mutability, TyVariableKind}; | 7 | use chalk_ir::{Mutability, TyVariableKind}; |
8 | use hir_def::lang_item::LangItemTarget; | 8 | use hir_def::lang_item::LangItemTarget; |
9 | 9 | ||
10 | use crate::{autoderef, traits::Solution, Obligation, Substs, TraitRef, Ty}; | 10 | use crate::{autoderef, traits::Solution, Interner, Obligation, Substs, TraitRef, Ty, TyKind}; |
11 | 11 | ||
12 | use super::{InEnvironment, InferenceContext}; | 12 | use super::{InEnvironment, InferenceContext}; |
13 | 13 | ||
@@ -33,7 +33,9 @@ impl<'a> InferenceContext<'a> { | |||
33 | } else if self.coerce(ty2, ty1) { | 33 | } else if self.coerce(ty2, ty1) { |
34 | ty1.clone() | 34 | ty1.clone() |
35 | } else { | 35 | } else { |
36 | if let (Ty::FnDef(..), Ty::FnDef(..)) = (ty1, ty2) { | 36 | if let (TyKind::FnDef(..), TyKind::FnDef(..)) = |
37 | (ty1.interned(&Interner), ty2.interned(&Interner)) | ||
38 | { | ||
37 | cov_mark::hit!(coerce_fn_reification); | 39 | cov_mark::hit!(coerce_fn_reification); |
38 | // Special case: two function types. Try to coerce both to | 40 | // Special case: two function types. Try to coerce both to |
39 | // pointers to have a chance at getting a match. See | 41 | // pointers to have a chance at getting a match. See |
@@ -51,13 +53,13 @@ impl<'a> InferenceContext<'a> { | |||
51 | } | 53 | } |
52 | 54 | ||
53 | fn coerce_inner(&mut self, mut from_ty: Ty, to_ty: &Ty) -> bool { | 55 | fn coerce_inner(&mut self, mut from_ty: Ty, to_ty: &Ty) -> bool { |
54 | match (&from_ty, to_ty) { | 56 | match (from_ty.interned(&Interner), to_ty.interned(&Interner)) { |
55 | // Never type will make type variable to fallback to Never Type instead of Unknown. | 57 | // Never type will make type variable to fallback to Never Type instead of Unknown. |
56 | (Ty::Never, Ty::InferenceVar(tv, TyVariableKind::General)) => { | 58 | (TyKind::Never, TyKind::InferenceVar(tv, TyVariableKind::General)) => { |
57 | self.table.type_variable_table.set_diverging(*tv, true); | 59 | self.table.type_variable_table.set_diverging(*tv, true); |
58 | return true; | 60 | return true; |
59 | } | 61 | } |
60 | (Ty::Never, _) => return true, | 62 | (TyKind::Never, _) => return true, |
61 | 63 | ||
62 | // Trivial cases, this should go after `never` check to | 64 | // Trivial cases, this should go after `never` check to |
63 | // avoid infer result type to be never | 65 | // avoid infer result type to be never |
@@ -69,33 +71,33 @@ impl<'a> InferenceContext<'a> { | |||
69 | } | 71 | } |
70 | 72 | ||
71 | // Pointer weakening and function to pointer | 73 | // Pointer weakening and function to pointer |
72 | match (&mut from_ty, to_ty) { | 74 | match (&mut from_ty.0, to_ty.interned(&Interner)) { |
73 | // `*mut T` -> `*const T` | 75 | // `*mut T` -> `*const T` |
74 | // `&mut T` -> `&T` | 76 | // `&mut T` -> `&T` |
75 | (Ty::Raw(m1, ..), Ty::Raw(m2 @ Mutability::Not, ..)) | 77 | (TyKind::Raw(m1, ..), TyKind::Raw(m2 @ Mutability::Not, ..)) |
76 | | (Ty::Ref(m1, ..), Ty::Ref(m2 @ Mutability::Not, ..)) => { | 78 | | (TyKind::Ref(m1, ..), TyKind::Ref(m2 @ Mutability::Not, ..)) => { |
77 | *m1 = *m2; | 79 | *m1 = *m2; |
78 | } | 80 | } |
79 | // `&T` -> `*const T` | 81 | // `&T` -> `*const T` |
80 | // `&mut T` -> `*mut T`/`*const T` | 82 | // `&mut T` -> `*mut T`/`*const T` |
81 | (Ty::Ref(.., substs), &Ty::Raw(m2 @ Mutability::Not, ..)) | 83 | (TyKind::Ref(.., substs), &TyKind::Raw(m2 @ Mutability::Not, ..)) |
82 | | (Ty::Ref(Mutability::Mut, substs), &Ty::Raw(m2, ..)) => { | 84 | | (TyKind::Ref(Mutability::Mut, substs), &TyKind::Raw(m2, ..)) => { |
83 | from_ty = Ty::Raw(m2, substs.clone()); | 85 | from_ty = TyKind::Raw(m2, substs.clone()).intern(&Interner); |
84 | } | 86 | } |
85 | 87 | ||
86 | // Illegal mutability conversion | 88 | // Illegal mutability conversion |
87 | (Ty::Raw(Mutability::Not, ..), Ty::Raw(Mutability::Mut, ..)) | 89 | (TyKind::Raw(Mutability::Not, ..), TyKind::Raw(Mutability::Mut, ..)) |
88 | | (Ty::Ref(Mutability::Not, ..), Ty::Ref(Mutability::Mut, ..)) => return false, | 90 | | (TyKind::Ref(Mutability::Not, ..), TyKind::Ref(Mutability::Mut, ..)) => return false, |
89 | 91 | ||
90 | // `{function_type}` -> `fn()` | 92 | // `{function_type}` -> `fn()` |
91 | (Ty::FnDef(..), Ty::Function { .. }) => match from_ty.callable_sig(self.db) { | 93 | (TyKind::FnDef(..), TyKind::Function { .. }) => match from_ty.callable_sig(self.db) { |
92 | None => return false, | 94 | None => return false, |
93 | Some(sig) => { | 95 | Some(sig) => { |
94 | from_ty = Ty::fn_ptr(sig); | 96 | from_ty = Ty::fn_ptr(sig); |
95 | } | 97 | } |
96 | }, | 98 | }, |
97 | 99 | ||
98 | (Ty::Closure(.., substs), Ty::Function { .. }) => { | 100 | (TyKind::Closure(.., substs), TyKind::Function { .. }) => { |
99 | from_ty = substs[0].clone(); | 101 | from_ty = substs[0].clone(); |
100 | } | 102 | } |
101 | 103 | ||
@@ -107,9 +109,11 @@ impl<'a> InferenceContext<'a> { | |||
107 | } | 109 | } |
108 | 110 | ||
109 | // Auto Deref if cannot coerce | 111 | // Auto Deref if cannot coerce |
110 | match (&from_ty, to_ty) { | 112 | match (from_ty.interned(&Interner), to_ty.interned(&Interner)) { |
111 | // FIXME: DerefMut | 113 | // FIXME: DerefMut |
112 | (Ty::Ref(_, st1), Ty::Ref(_, st2)) => self.unify_autoderef_behind_ref(&st1[0], &st2[0]), | 114 | (TyKind::Ref(_, st1), TyKind::Ref(_, st2)) => { |
115 | self.unify_autoderef_behind_ref(&st1[0], &st2[0]) | ||
116 | } | ||
113 | 117 | ||
114 | // Otherwise, normal unify | 118 | // Otherwise, normal unify |
115 | _ => self.unify(&from_ty, to_ty), | 119 | _ => self.unify(&from_ty, to_ty), |