diff options
Diffstat (limited to 'crates/hir_ty/src/infer/coerce.rs')
-rw-r--r-- | crates/hir_ty/src/infer/coerce.rs | 29 |
1 files changed, 20 insertions, 9 deletions
diff --git a/crates/hir_ty/src/infer/coerce.rs b/crates/hir_ty/src/infer/coerce.rs index 32c273afc..1f463a425 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::{cast::Cast, Mutability, TyVariableKind}; | 7 | use chalk_ir::{cast::Cast, Mutability, TyVariableKind}; |
8 | use hir_def::lang_item::LangItemTarget; | 8 | use hir_def::lang_item::LangItemTarget; |
9 | 9 | ||
10 | use crate::{autoderef, Interner, Solution, Ty, TyBuilder, TyKind}; | 10 | use crate::{autoderef, Canonical, Interner, Solution, Ty, TyBuilder, TyExt, TyKind}; |
11 | 11 | ||
12 | use super::{InEnvironment, InferenceContext}; | 12 | use super::{InEnvironment, InferenceContext}; |
13 | 13 | ||
@@ -71,17 +71,19 @@ impl<'a> InferenceContext<'a> { | |||
71 | } | 71 | } |
72 | 72 | ||
73 | // Pointer weakening and function to pointer | 73 | // Pointer weakening and function to pointer |
74 | match (from_ty.interned_mut(), to_ty.kind(&Interner)) { | 74 | match (from_ty.kind(&Interner), to_ty.kind(&Interner)) { |
75 | // `*mut T` -> `*const T` | 75 | // `*mut T` -> `*const T` |
76 | (TyKind::Raw(_, inner), TyKind::Raw(m2 @ Mutability::Not, ..)) => { | ||
77 | from_ty = TyKind::Raw(*m2, inner.clone()).intern(&Interner); | ||
78 | } | ||
76 | // `&mut T` -> `&T` | 79 | // `&mut T` -> `&T` |
77 | (TyKind::Raw(m1, ..), TyKind::Raw(m2 @ Mutability::Not, ..)) | 80 | (TyKind::Ref(_, lt, inner), TyKind::Ref(m2 @ Mutability::Not, ..)) => { |
78 | | (TyKind::Ref(m1, ..), TyKind::Ref(m2 @ Mutability::Not, ..)) => { | 81 | from_ty = TyKind::Ref(*m2, lt.clone(), inner.clone()).intern(&Interner); |
79 | *m1 = *m2; | ||
80 | } | 82 | } |
81 | // `&T` -> `*const T` | 83 | // `&T` -> `*const T` |
82 | // `&mut T` -> `*mut T`/`*const T` | 84 | // `&mut T` -> `*mut T`/`*const T` |
83 | (TyKind::Ref(.., substs), &TyKind::Raw(m2 @ Mutability::Not, ..)) | 85 | (TyKind::Ref(.., substs), &TyKind::Raw(m2 @ Mutability::Not, ..)) |
84 | | (TyKind::Ref(Mutability::Mut, substs), &TyKind::Raw(m2, ..)) => { | 86 | | (TyKind::Ref(Mutability::Mut, _, substs), &TyKind::Raw(m2, ..)) => { |
85 | from_ty = TyKind::Raw(m2, substs.clone()).intern(&Interner); | 87 | from_ty = TyKind::Raw(m2, substs.clone()).intern(&Interner); |
86 | } | 88 | } |
87 | 89 | ||
@@ -111,7 +113,9 @@ impl<'a> InferenceContext<'a> { | |||
111 | // Auto Deref if cannot coerce | 113 | // Auto Deref if cannot coerce |
112 | match (from_ty.kind(&Interner), to_ty.kind(&Interner)) { | 114 | match (from_ty.kind(&Interner), to_ty.kind(&Interner)) { |
113 | // FIXME: DerefMut | 115 | // FIXME: DerefMut |
114 | (TyKind::Ref(_, st1), TyKind::Ref(_, st2)) => self.unify_autoderef_behind_ref(st1, st2), | 116 | (TyKind::Ref(.., st1), TyKind::Ref(.., st2)) => { |
117 | self.unify_autoderef_behind_ref(st1, st2) | ||
118 | } | ||
115 | 119 | ||
116 | // Otherwise, normal unify | 120 | // Otherwise, normal unify |
117 | _ => self.unify(&from_ty, to_ty), | 121 | _ => self.unify(&from_ty, to_ty), |
@@ -137,7 +141,7 @@ impl<'a> InferenceContext<'a> { | |||
137 | b.push(from_ty.clone()).push(to_ty.clone()).build() | 141 | b.push(from_ty.clone()).push(to_ty.clone()).build() |
138 | }; | 142 | }; |
139 | 143 | ||
140 | let goal = InEnvironment::new(self.trait_env.env.clone(), trait_ref.cast(&Interner)); | 144 | let goal = InEnvironment::new(&self.trait_env.env, trait_ref.cast(&Interner)); |
141 | 145 | ||
142 | let canonicalizer = self.canonicalizer(); | 146 | let canonicalizer = self.canonicalizer(); |
143 | let canonicalized = canonicalizer.canonicalize_obligation(goal); | 147 | let canonicalized = canonicalizer.canonicalize_obligation(goal); |
@@ -146,7 +150,14 @@ impl<'a> InferenceContext<'a> { | |||
146 | 150 | ||
147 | match solution { | 151 | match solution { |
148 | Solution::Unique(v) => { | 152 | Solution::Unique(v) => { |
149 | canonicalized.apply_solution(self, v.0); | 153 | canonicalized.apply_solution( |
154 | self, | ||
155 | Canonical { | ||
156 | binders: v.binders, | ||
157 | // FIXME handle constraints | ||
158 | value: v.value.subst, | ||
159 | }, | ||
160 | ); | ||
150 | } | 161 | } |
151 | _ => return None, | 162 | _ => return None, |
152 | }; | 163 | }; |