aboutsummaryrefslogtreecommitdiff
path: root/crates/hir_ty/src/infer
diff options
context:
space:
mode:
Diffstat (limited to 'crates/hir_ty/src/infer')
-rw-r--r--crates/hir_ty/src/infer/coerce.rs480
-rw-r--r--crates/hir_ty/src/infer/expr.rs142
-rw-r--r--crates/hir_ty/src/infer/pat.rs19
-rw-r--r--crates/hir_ty/src/infer/path.rs6
-rw-r--r--crates/hir_ty/src/infer/unify.rs861
5 files changed, 848 insertions, 660 deletions
diff --git a/crates/hir_ty/src/infer/coerce.rs b/crates/hir_ty/src/infer/coerce.rs
index 1f463a425..765a02b1c 100644
--- a/crates/hir_ty/src/infer/coerce.rs
+++ b/crates/hir_ty/src/infer/coerce.rs
@@ -2,156 +2,414 @@
2//! happen in certain places, e.g. weakening `&mut` to `&` or deref coercions 2//! happen in certain places, e.g. weakening `&mut` to `&` or deref coercions
3//! like going from `&Vec<T>` to `&[T]`. 3//! like going from `&Vec<T>` to `&[T]`.
4//! 4//!
5//! See: https://doc.rust-lang.org/nomicon/coercions.html 5//! See https://doc.rust-lang.org/nomicon/coercions.html and
6//! librustc_typeck/check/coercion.rs.
6 7
7use chalk_ir::{cast::Cast, Mutability, TyVariableKind}; 8use chalk_ir::{cast::Cast, Mutability, TyVariableKind};
8use hir_def::lang_item::LangItemTarget; 9use hir_def::{expr::ExprId, lang_item::LangItemTarget};
9 10
10use crate::{autoderef, Canonical, Interner, Solution, Ty, TyBuilder, TyExt, TyKind}; 11use crate::{
12 autoderef, infer::TypeMismatch, static_lifetime, Canonical, DomainGoal, FnPointer, FnSig,
13 Interner, Solution, Substitution, Ty, TyBuilder, TyExt, TyKind,
14};
11 15
12use super::{InEnvironment, InferenceContext}; 16use super::{InEnvironment, InferOk, InferResult, InferenceContext, TypeError};
13 17
14impl<'a> InferenceContext<'a> { 18impl<'a> InferenceContext<'a> {
15 /// Unify two types, but may coerce the first one to the second one 19 /// Unify two types, but may coerce the first one to the second one
16 /// using "implicit coercion rules" if needed. 20 /// using "implicit coercion rules" if needed.
17 pub(super) fn coerce(&mut self, from_ty: &Ty, to_ty: &Ty) -> bool { 21 pub(super) fn coerce(&mut self, from_ty: &Ty, to_ty: &Ty) -> bool {
18 let from_ty = self.resolve_ty_shallow(from_ty).into_owned(); 22 let from_ty = self.resolve_ty_shallow(from_ty);
19 let to_ty = self.resolve_ty_shallow(to_ty); 23 let to_ty = self.resolve_ty_shallow(to_ty);
20 self.coerce_inner(from_ty, &to_ty) 24 match self.coerce_inner(from_ty, &to_ty) {
25 Ok(result) => {
26 self.table.register_infer_ok(result);
27 true
28 }
29 Err(_) => {
30 // FIXME deal with error
31 false
32 }
33 }
21 } 34 }
22 35
23 /// Merge two types from different branches, with possible coercion. 36 /// Merge two types from different branches, with possible coercion.
24 /// 37 ///
25 /// Mostly this means trying to coerce one to the other, but 38 /// Mostly this means trying to coerce one to the other, but
26 /// - if we have two function types for different functions, we need to 39 /// - if we have two function types for different functions or closures, we need to
27 /// coerce both to function pointers; 40 /// coerce both to function pointers;
28 /// - if we were concerned with lifetime subtyping, we'd need to look for a 41 /// - if we were concerned with lifetime subtyping, we'd need to look for a
29 /// least upper bound. 42 /// least upper bound.
30 pub(super) fn coerce_merge_branch(&mut self, ty1: &Ty, ty2: &Ty) -> Ty { 43 pub(super) fn coerce_merge_branch(&mut self, id: Option<ExprId>, ty1: &Ty, ty2: &Ty) -> Ty {
31 if self.coerce(ty1, ty2) { 44 let ty1 = self.resolve_ty_shallow(ty1);
32 ty2.clone() 45 let ty2 = self.resolve_ty_shallow(ty2);
33 } else if self.coerce(ty2, ty1) { 46 // Special case: two function types. Try to coerce both to
47 // pointers to have a chance at getting a match. See
48 // https://github.com/rust-lang/rust/blob/7b805396bf46dce972692a6846ce2ad8481c5f85/src/librustc_typeck/check/coercion.rs#L877-L916
49 let sig = match (ty1.kind(&Interner), ty2.kind(&Interner)) {
50 (TyKind::FnDef(..), TyKind::FnDef(..))
51 | (TyKind::Closure(..), TyKind::FnDef(..))
52 | (TyKind::FnDef(..), TyKind::Closure(..))
53 | (TyKind::Closure(..), TyKind::Closure(..)) => {
54 // FIXME: we're ignoring safety here. To be more correct, if we have one FnDef and one Closure,
55 // we should be coercing the closure to a fn pointer of the safety of the FnDef
56 cov_mark::hit!(coerce_fn_reification);
57 let sig = ty1.callable_sig(self.db).expect("FnDef without callable sig");
58 Some(sig)
59 }
60 _ => None,
61 };
62 if let Some(sig) = sig {
63 let target_ty = TyKind::Function(sig.to_fn_ptr()).intern(&Interner);
64 let result1 = self.coerce_inner(ty1.clone(), &target_ty);
65 let result2 = self.coerce_inner(ty2.clone(), &target_ty);
66 if let (Ok(result1), Ok(result2)) = (result1, result2) {
67 self.table.register_infer_ok(result1);
68 self.table.register_infer_ok(result2);
69 return target_ty;
70 }
71 }
72
73 // It might not seem like it, but order is important here: ty1 is our
74 // "previous" type, ty2 is the "new" one being added. If the previous
75 // type is a type variable and the new one is `!`, trying it the other
76 // way around first would mean we make the type variable `!`, instead of
77 // just marking it as possibly diverging.
78 if self.coerce(&ty2, &ty1) {
34 ty1.clone() 79 ty1.clone()
80 } else if self.coerce(&ty1, &ty2) {
81 ty2.clone()
35 } else { 82 } else {
36 if let (TyKind::FnDef(..), TyKind::FnDef(..)) = 83 if let Some(id) = id {
37 (ty1.kind(&Interner), ty2.kind(&Interner)) 84 self.result
38 { 85 .type_mismatches
39 cov_mark::hit!(coerce_fn_reification); 86 .insert(id.into(), TypeMismatch { expected: ty1.clone(), actual: ty2.clone() });
40 // Special case: two function types. Try to coerce both to
41 // pointers to have a chance at getting a match. See
42 // https://github.com/rust-lang/rust/blob/7b805396bf46dce972692a6846ce2ad8481c5f85/src/librustc_typeck/check/coercion.rs#L877-L916
43 let sig1 = ty1.callable_sig(self.db).expect("FnDef without callable sig");
44 let sig2 = ty2.callable_sig(self.db).expect("FnDef without callable sig");
45 let ptr_ty1 = TyBuilder::fn_ptr(sig1);
46 let ptr_ty2 = TyBuilder::fn_ptr(sig2);
47 self.coerce_merge_branch(&ptr_ty1, &ptr_ty2)
48 } else {
49 cov_mark::hit!(coerce_merge_fail_fallback);
50 ty1.clone()
51 } 87 }
88 cov_mark::hit!(coerce_merge_fail_fallback);
89 ty1.clone()
52 } 90 }
53 } 91 }
54 92
55 fn coerce_inner(&mut self, mut from_ty: Ty, to_ty: &Ty) -> bool { 93 fn coerce_inner(&mut self, from_ty: Ty, to_ty: &Ty) -> InferResult {
56 match (from_ty.kind(&Interner), to_ty.kind(&Interner)) { 94 if from_ty.is_never() {
57 // Never type will make type variable to fallback to Never Type instead of Unknown. 95 // Subtle: If we are coercing from `!` to `?T`, where `?T` is an unbound
58 (TyKind::Never, TyKind::InferenceVar(tv, TyVariableKind::General)) => { 96 // type variable, we want `?T` to fallback to `!` if not
59 self.table.type_variable_table.set_diverging(*tv, true); 97 // otherwise constrained. An example where this arises:
60 return true; 98 //
99 // let _: Option<?T> = Some({ return; });
100 //
101 // here, we would coerce from `!` to `?T`.
102 match to_ty.kind(&Interner) {
103 TyKind::InferenceVar(tv, TyVariableKind::General) => {
104 self.table.set_diverging(*tv, true);
105 }
106 _ => {}
61 } 107 }
62 (TyKind::Never, _) => return true, 108 return Ok(InferOk { goals: Vec::new() });
109 }
63 110
64 // Trivial cases, this should go after `never` check to 111 // Consider coercing the subtype to a DST
65 // avoid infer result type to be never 112 if let Ok(ret) = self.try_coerce_unsized(&from_ty, &to_ty) {
66 _ => { 113 return Ok(ret);
67 if self.table.unify_inner_trivial(&from_ty, &to_ty, 0) { 114 }
68 return true; 115
69 } 116 // Examine the supertype and consider auto-borrowing.
117 match to_ty.kind(&Interner) {
118 TyKind::Raw(mt, _) => {
119 return self.coerce_ptr(from_ty, to_ty, *mt);
70 } 120 }
121 TyKind::Ref(mt, _, _) => {
122 return self.coerce_ref(from_ty, to_ty, *mt);
123 }
124 _ => {}
71 } 125 }
72 126
73 // Pointer weakening and function to pointer 127 match from_ty.kind(&Interner) {
74 match (from_ty.kind(&Interner), to_ty.kind(&Interner)) { 128 TyKind::FnDef(..) => {
75 // `*mut T` -> `*const T` 129 // Function items are coercible to any closure
76 (TyKind::Raw(_, inner), TyKind::Raw(m2 @ Mutability::Not, ..)) => { 130 // type; function pointers are not (that would
77 from_ty = TyKind::Raw(*m2, inner.clone()).intern(&Interner); 131 // require double indirection).
132 // Additionally, we permit coercion of function
133 // items to drop the unsafe qualifier.
134 self.coerce_from_fn_item(from_ty, to_ty)
78 } 135 }
79 // `&mut T` -> `&T` 136 TyKind::Function(from_fn_ptr) => {
80 (TyKind::Ref(_, lt, inner), TyKind::Ref(m2 @ Mutability::Not, ..)) => { 137 // We permit coercion of fn pointers to drop the
81 from_ty = TyKind::Ref(*m2, lt.clone(), inner.clone()).intern(&Interner); 138 // unsafe qualifier.
139 self.coerce_from_fn_pointer(from_ty.clone(), from_fn_ptr, to_ty)
82 } 140 }
83 // `&T` -> `*const T` 141 TyKind::Closure(_, from_substs) => {
84 // `&mut T` -> `*mut T`/`*const T` 142 // Non-capturing closures are coercible to
85 (TyKind::Ref(.., substs), &TyKind::Raw(m2 @ Mutability::Not, ..)) 143 // function pointers or unsafe function pointers.
86 | (TyKind::Ref(Mutability::Mut, _, substs), &TyKind::Raw(m2, ..)) => { 144 // It cannot convert closures that require unsafe.
87 from_ty = TyKind::Raw(m2, substs.clone()).intern(&Interner); 145 self.coerce_closure_to_fn(from_ty.clone(), from_substs, to_ty)
88 } 146 }
147 _ => {
148 // Otherwise, just use unification rules.
149 self.table.try_unify(&from_ty, to_ty)
150 }
151 }
152 }
89 153
90 // Illegal mutability conversion 154 fn coerce_ptr(&mut self, from_ty: Ty, to_ty: &Ty, to_mt: Mutability) -> InferResult {
91 (TyKind::Raw(Mutability::Not, ..), TyKind::Raw(Mutability::Mut, ..)) 155 let (_is_ref, from_mt, from_inner) = match from_ty.kind(&Interner) {
92 | (TyKind::Ref(Mutability::Not, ..), TyKind::Ref(Mutability::Mut, ..)) => return false, 156 TyKind::Ref(mt, _, ty) => (true, mt, ty),
157 TyKind::Raw(mt, ty) => (false, mt, ty),
158 _ => return self.table.try_unify(&from_ty, to_ty),
159 };
93 160
94 // `{function_type}` -> `fn()` 161 coerce_mutabilities(*from_mt, to_mt)?;
95 (TyKind::FnDef(..), TyKind::Function { .. }) => match from_ty.callable_sig(self.db) { 162
96 None => return false, 163 // Check that the types which they point at are compatible.
97 Some(sig) => { 164 let from_raw = TyKind::Raw(to_mt, from_inner.clone()).intern(&Interner);
98 from_ty = TyBuilder::fn_ptr(sig); 165 // FIXME: behavior differs based on is_ref once we're computing adjustments
99 } 166 self.table.try_unify(&from_raw, to_ty)
167 }
168
169 /// Reborrows `&mut A` to `&mut B` and `&(mut) A` to `&B`.
170 /// To match `A` with `B`, autoderef will be performed,
171 /// calling `deref`/`deref_mut` where necessary.
172 fn coerce_ref(&mut self, from_ty: Ty, to_ty: &Ty, to_mt: Mutability) -> InferResult {
173 match from_ty.kind(&Interner) {
174 TyKind::Ref(mt, _, _) => {
175 coerce_mutabilities(*mt, to_mt)?;
176 }
177 _ => return self.table.try_unify(&from_ty, to_ty),
178 };
179
180 // NOTE: this code is mostly copied and adapted from rustc, and
181 // currently more complicated than necessary, carrying errors around
182 // etc.. This complication will become necessary when we actually track
183 // details of coercion errors though, so I think it's useful to leave
184 // the structure like it is.
185
186 let canonicalized = self.canonicalize(from_ty.clone());
187 let autoderef = autoderef::autoderef(
188 self.db,
189 self.resolver.krate(),
190 InEnvironment {
191 goal: canonicalized.value.clone(),
192 environment: self.trait_env.env.clone(),
100 }, 193 },
194 );
195 let mut first_error = None;
196 let mut found = None;
101 197
102 (TyKind::Closure(.., substs), TyKind::Function { .. }) => { 198 for (autoderefs, referent_ty) in autoderef.enumerate() {
103 from_ty = substs.at(&Interner, 0).assert_ty_ref(&Interner).clone(); 199 if autoderefs == 0 {
200 // Don't let this pass, otherwise it would cause
201 // &T to autoref to &&T.
202 continue;
104 } 203 }
105 204
106 _ => {} 205 let referent_ty = canonicalized.decanonicalize_ty(referent_ty.value);
206
207 // At this point, we have deref'd `a` to `referent_ty`. So
208 // imagine we are coercing from `&'a mut Vec<T>` to `&'b mut [T]`.
209 // In the autoderef loop for `&'a mut Vec<T>`, we would get
210 // three callbacks:
211 //
212 // - `&'a mut Vec<T>` -- 0 derefs, just ignore it
213 // - `Vec<T>` -- 1 deref
214 // - `[T]` -- 2 deref
215 //
216 // At each point after the first callback, we want to
217 // check to see whether this would match out target type
218 // (`&'b mut [T]`) if we autoref'd it. We can't just
219 // compare the referent types, though, because we still
220 // have to consider the mutability. E.g., in the case
221 // we've been considering, we have an `&mut` reference, so
222 // the `T` in `[T]` needs to be unified with equality.
223 //
224 // Therefore, we construct reference types reflecting what
225 // the types will be after we do the final auto-ref and
226 // compare those. Note that this means we use the target
227 // mutability [1], since it may be that we are coercing
228 // from `&mut T` to `&U`.
229 let lt = static_lifetime(); // FIXME: handle lifetimes correctly, see rustc
230 let derefd_from_ty = TyKind::Ref(to_mt, lt, referent_ty).intern(&Interner);
231 match self.table.try_unify(&derefd_from_ty, to_ty) {
232 Ok(result) => {
233 found = Some(result);
234 break;
235 }
236 Err(err) => {
237 if first_error.is_none() {
238 first_error = Some(err);
239 }
240 }
241 }
107 } 242 }
108 243
109 if let Some(ret) = self.try_coerce_unsized(&from_ty, &to_ty) { 244 // Extract type or return an error. We return the first error
110 return ret; 245 // we got, which should be from relating the "base" type
246 // (e.g., in example above, the failure from relating `Vec<T>`
247 // to the target type), since that should be the least
248 // confusing.
249 let result = match found {
250 Some(d) => d,
251 None => {
252 let err = first_error.expect("coerce_borrowed_pointer had no error");
253 return Err(err);
254 }
255 };
256
257 Ok(result)
258 }
259
260 /// Attempts to coerce from the type of a Rust function item into a function pointer.
261 fn coerce_from_fn_item(&mut self, from_ty: Ty, to_ty: &Ty) -> InferResult {
262 match to_ty.kind(&Interner) {
263 TyKind::Function(_) => {
264 let from_sig = from_ty.callable_sig(self.db).expect("FnDef had no sig");
265
266 // FIXME check ABI: Intrinsics are not coercible to function pointers
267 // FIXME Safe `#[target_feature]` functions are not assignable to safe fn pointers (RFC 2396)
268
269 // FIXME rustc normalizes assoc types in the sig here, not sure if necessary
270
271 let from_sig = from_sig.to_fn_ptr();
272 let from_fn_pointer = TyKind::Function(from_sig.clone()).intern(&Interner);
273 let ok = self.coerce_from_safe_fn(from_fn_pointer, &from_sig, to_ty)?;
274
275 Ok(ok)
276 }
277 _ => self.table.try_unify(&from_ty, to_ty),
111 } 278 }
279 }
280
281 fn coerce_from_fn_pointer(
282 &mut self,
283 from_ty: Ty,
284 from_f: &FnPointer,
285 to_ty: &Ty,
286 ) -> InferResult {
287 self.coerce_from_safe_fn(from_ty, from_f, to_ty)
288 }
112 289
113 // Auto Deref if cannot coerce 290 fn coerce_from_safe_fn(
114 match (from_ty.kind(&Interner), to_ty.kind(&Interner)) { 291 &mut self,
115 // FIXME: DerefMut 292 from_ty: Ty,
116 (TyKind::Ref(.., st1), TyKind::Ref(.., st2)) => { 293 from_fn_ptr: &FnPointer,
117 self.unify_autoderef_behind_ref(st1, st2) 294 to_ty: &Ty,
295 ) -> InferResult {
296 if let TyKind::Function(to_fn_ptr) = to_ty.kind(&Interner) {
297 if let (chalk_ir::Safety::Safe, chalk_ir::Safety::Unsafe) =
298 (from_fn_ptr.sig.safety, to_fn_ptr.sig.safety)
299 {
300 let from_unsafe =
301 TyKind::Function(safe_to_unsafe_fn_ty(from_fn_ptr.clone())).intern(&Interner);
302 return self.table.try_unify(&from_unsafe, to_ty);
118 } 303 }
304 }
305 self.table.try_unify(&from_ty, to_ty)
306 }
119 307
120 // Otherwise, normal unify 308 /// Attempts to coerce from the type of a non-capturing closure into a
121 _ => self.unify(&from_ty, to_ty), 309 /// function pointer.
310 fn coerce_closure_to_fn(
311 &mut self,
312 from_ty: Ty,
313 from_substs: &Substitution,
314 to_ty: &Ty,
315 ) -> InferResult {
316 match to_ty.kind(&Interner) {
317 TyKind::Function(fn_ty) /* if from_substs is non-capturing (FIXME) */ => {
318 // We coerce the closure, which has fn type
319 // `extern "rust-call" fn((arg0,arg1,...)) -> _`
320 // to
321 // `fn(arg0,arg1,...) -> _`
322 // or
323 // `unsafe fn(arg0,arg1,...) -> _`
324 let safety = fn_ty.sig.safety;
325 let pointer_ty = coerce_closure_fn_ty(from_substs, safety);
326 self.table.try_unify(&pointer_ty, to_ty)
327 }
328 _ => self.table.try_unify(&from_ty, to_ty),
122 } 329 }
123 } 330 }
124 331
125 /// Coerce a type using `from_ty: CoerceUnsized<ty_ty>` 332 /// Coerce a type using `from_ty: CoerceUnsized<ty_ty>`
126 /// 333 ///
127 /// See: https://doc.rust-lang.org/nightly/std/marker/trait.CoerceUnsized.html 334 /// See: https://doc.rust-lang.org/nightly/std/marker/trait.CoerceUnsized.html
128 fn try_coerce_unsized(&mut self, from_ty: &Ty, to_ty: &Ty) -> Option<bool> { 335 fn try_coerce_unsized(&mut self, from_ty: &Ty, to_ty: &Ty) -> InferResult {
336 // These 'if' statements require some explanation.
337 // The `CoerceUnsized` trait is special - it is only
338 // possible to write `impl CoerceUnsized<B> for A` where
339 // A and B have 'matching' fields. This rules out the following
340 // two types of blanket impls:
341 //
342 // `impl<T> CoerceUnsized<T> for SomeType`
343 // `impl<T> CoerceUnsized<SomeType> for T`
344 //
345 // Both of these trigger a special `CoerceUnsized`-related error (E0376)
346 //
347 // We can take advantage of this fact to avoid performing unecessary work.
348 // If either `source` or `target` is a type variable, then any applicable impl
349 // would need to be generic over the self-type (`impl<T> CoerceUnsized<SomeType> for T`)
350 // or generic over the `CoerceUnsized` type parameter (`impl<T> CoerceUnsized<T> for
351 // SomeType`).
352 //
353 // However, these are exactly the kinds of impls which are forbidden by
354 // the compiler! Therefore, we can be sure that coercion will always fail
355 // when either the source or target type is a type variable. This allows us
356 // to skip performing any trait selection, and immediately bail out.
357 if from_ty.is_ty_var() {
358 return Err(TypeError);
359 }
360 if to_ty.is_ty_var() {
361 return Err(TypeError);
362 }
363
364 // Handle reborrows before trying to solve `Source: CoerceUnsized<Target>`.
365 let coerce_from = match (from_ty.kind(&Interner), to_ty.kind(&Interner)) {
366 (TyKind::Ref(from_mt, _, from_inner), TyKind::Ref(to_mt, _, _)) => {
367 coerce_mutabilities(*from_mt, *to_mt)?;
368
369 let lt = static_lifetime();
370 TyKind::Ref(*to_mt, lt, from_inner.clone()).intern(&Interner)
371 }
372 (TyKind::Ref(from_mt, _, from_inner), TyKind::Raw(to_mt, _)) => {
373 coerce_mutabilities(*from_mt, *to_mt)?;
374
375 TyKind::Raw(*to_mt, from_inner.clone()).intern(&Interner)
376 }
377 _ => from_ty.clone(),
378 };
379
129 let krate = self.resolver.krate().unwrap(); 380 let krate = self.resolver.krate().unwrap();
130 let coerce_unsized_trait = match self.db.lang_item(krate, "coerce_unsized".into()) { 381 let coerce_unsized_trait = match self.db.lang_item(krate, "coerce_unsized".into()) {
131 Some(LangItemTarget::TraitId(trait_)) => trait_, 382 Some(LangItemTarget::TraitId(trait_)) => trait_,
132 _ => return None, 383 _ => return Err(TypeError),
133 }; 384 };
134 385
135 let trait_ref = { 386 let trait_ref = {
136 let b = TyBuilder::trait_ref(self.db, coerce_unsized_trait); 387 let b = TyBuilder::trait_ref(self.db, coerce_unsized_trait);
137 if b.remaining() != 2 { 388 if b.remaining() != 2 {
138 // The CoerceUnsized trait should have two generic params: Self and T. 389 // The CoerceUnsized trait should have two generic params: Self and T.
139 return None; 390 return Err(TypeError);
140 } 391 }
141 b.push(from_ty.clone()).push(to_ty.clone()).build() 392 b.push(coerce_from.clone()).push(to_ty.clone()).build()
142 }; 393 };
143 394
144 let goal = InEnvironment::new(&self.trait_env.env, trait_ref.cast(&Interner)); 395 let goal: InEnvironment<DomainGoal> =
396 InEnvironment::new(&self.trait_env.env, trait_ref.cast(&Interner));
145 397
146 let canonicalizer = self.canonicalizer(); 398 let canonicalized = self.canonicalize(goal);
147 let canonicalized = canonicalizer.canonicalize_obligation(goal);
148 399
149 let solution = self.db.trait_solve(krate, canonicalized.value.clone())?; 400 // FIXME: rustc's coerce_unsized is more specialized -- it only tries to
401 // solve `CoerceUnsized` and `Unsize` goals at this point and leaves the
402 // rest for later. Also, there's some logic about sized type variables.
403 // Need to find out in what cases this is necessary
404 let solution = self
405 .db
406 .trait_solve(krate, canonicalized.value.clone().cast(&Interner))
407 .ok_or(TypeError)?;
150 408
151 match solution { 409 match solution {
152 Solution::Unique(v) => { 410 Solution::Unique(v) => {
153 canonicalized.apply_solution( 411 canonicalized.apply_solution(
154 self, 412 &mut self.table,
155 Canonical { 413 Canonical {
156 binders: v.binders, 414 binders: v.binders,
157 // FIXME handle constraints 415 // FIXME handle constraints
@@ -159,38 +417,40 @@ impl<'a> InferenceContext<'a> {
159 }, 417 },
160 ); 418 );
161 } 419 }
162 _ => return None, 420 // FIXME: should we accept ambiguous results here?
421 _ => return Err(TypeError),
163 }; 422 };
164 423
165 Some(true) 424 Ok(InferOk { goals: Vec::new() })
166 } 425 }
426}
167 427
168 /// Unify `from_ty` to `to_ty` with optional auto Deref 428fn coerce_closure_fn_ty(closure_substs: &Substitution, safety: chalk_ir::Safety) -> Ty {
169 /// 429 let closure_sig = closure_substs.at(&Interner, 0).assert_ty_ref(&Interner).clone();
170 /// Note that the parameters are already stripped the outer reference. 430 match closure_sig.kind(&Interner) {
171 fn unify_autoderef_behind_ref(&mut self, from_ty: &Ty, to_ty: &Ty) -> bool { 431 TyKind::Function(fn_ty) => TyKind::Function(FnPointer {
172 let canonicalized = self.canonicalizer().canonicalize_ty(from_ty.clone()); 432 num_binders: fn_ty.num_binders,
173 let to_ty = self.resolve_ty_shallow(&to_ty); 433 sig: FnSig { safety, ..fn_ty.sig },
174 // FIXME: Auto DerefMut 434 substitution: fn_ty.substitution.clone(),
175 for derefed_ty in autoderef::autoderef( 435 })
176 self.db, 436 .intern(&Interner),
177 self.resolver.krate(), 437 _ => TyKind::Error.intern(&Interner),
178 InEnvironment { 438 }
179 goal: canonicalized.value.clone(), 439}
180 environment: self.trait_env.env.clone(), 440
181 }, 441fn safe_to_unsafe_fn_ty(fn_ty: FnPointer) -> FnPointer {
182 ) { 442 FnPointer {
183 let derefed_ty = canonicalized.decanonicalize_ty(derefed_ty.value); 443 num_binders: fn_ty.num_binders,
184 let from_ty = self.resolve_ty_shallow(&derefed_ty); 444 sig: FnSig { safety: chalk_ir::Safety::Unsafe, ..fn_ty.sig },
185 // Stop when constructor matches. 445 substitution: fn_ty.substitution,
186 if from_ty.equals_ctor(&to_ty) { 446 }
187 // It will not recurse to `coerce`. 447}
188 return self.table.unify(&from_ty, &to_ty);
189 } else if self.table.unify_inner_trivial(&derefed_ty, &to_ty, 0) {
190 return true;
191 }
192 }
193 448
194 false 449fn coerce_mutabilities(from: Mutability, to: Mutability) -> Result<(), TypeError> {
450 match (from, to) {
451 (Mutability::Mut, Mutability::Mut)
452 | (Mutability::Mut, Mutability::Not)
453 | (Mutability::Not, Mutability::Not) => Ok(()),
454 (Mutability::Not, Mutability::Mut) => Err(TypeError),
195 } 455 }
196} 456}
diff --git a/crates/hir_ty/src/infer/expr.rs b/crates/hir_ty/src/infer/expr.rs
index 7278faeec..08c05c67c 100644
--- a/crates/hir_ty/src/infer/expr.rs
+++ b/crates/hir_ty/src/infer/expr.rs
@@ -35,39 +35,43 @@ use super::{
35impl<'a> InferenceContext<'a> { 35impl<'a> InferenceContext<'a> {
36 pub(super) fn infer_expr(&mut self, tgt_expr: ExprId, expected: &Expectation) -> Ty { 36 pub(super) fn infer_expr(&mut self, tgt_expr: ExprId, expected: &Expectation) -> Ty {
37 let ty = self.infer_expr_inner(tgt_expr, expected); 37 let ty = self.infer_expr_inner(tgt_expr, expected);
38 if ty.is_never() { 38 if self.resolve_ty_shallow(&ty).is_never() {
39 // Any expression that produces a value of type `!` must have diverged 39 // Any expression that produces a value of type `!` must have diverged
40 self.diverges = Diverges::Always; 40 self.diverges = Diverges::Always;
41 } 41 }
42 let could_unify = self.unify(&ty, &expected.ty); 42 if let Some(expected_ty) = expected.only_has_type(&mut self.table) {
43 if !could_unify { 43 let could_unify = self.unify(&ty, &expected_ty);
44 self.result.type_mismatches.insert( 44 if !could_unify {
45 tgt_expr.into(), 45 self.result.type_mismatches.insert(
46 TypeMismatch { expected: expected.ty.clone(), actual: ty.clone() }, 46 tgt_expr.into(),
47 ); 47 TypeMismatch { expected: expected_ty.clone(), actual: ty.clone() },
48 );
49 }
48 } 50 }
49 self.resolve_ty_as_possible(ty) 51 ty
50 } 52 }
51 53
52 /// Infer type of expression with possibly implicit coerce to the expected type. 54 /// Infer type of expression with possibly implicit coerce to the expected type.
53 /// Return the type after possible coercion. 55 /// Return the type after possible coercion.
54 pub(super) fn infer_expr_coerce(&mut self, expr: ExprId, expected: &Expectation) -> Ty { 56 pub(super) fn infer_expr_coerce(&mut self, expr: ExprId, expected: &Expectation) -> Ty {
55 let ty = self.infer_expr_inner(expr, &expected); 57 let ty = self.infer_expr_inner(expr, &expected);
56 let ty = if !self.coerce(&ty, &expected.coercion_target()) { 58 let ty = if let Some(target) = expected.only_has_type(&mut self.table) {
57 self.result.type_mismatches.insert( 59 if !self.coerce(&ty, &target) {
58 expr.into(), 60 self.result.type_mismatches.insert(
59 TypeMismatch { expected: expected.ty.clone(), actual: ty.clone() }, 61 expr.into(),
60 ); 62 TypeMismatch { expected: target.clone(), actual: ty.clone() },
61 // Return actual type when type mismatch. 63 );
62 // This is needed for diagnostic when return type mismatch. 64 // Return actual type when type mismatch.
63 ty 65 // This is needed for diagnostic when return type mismatch.
64 } else if expected.coercion_target().is_unknown() { 66 ty
65 ty 67 } else {
68 target.clone()
69 }
66 } else { 70 } else {
67 expected.ty.clone() 71 ty
68 }; 72 };
69 73
70 self.resolve_ty_as_possible(ty) 74 ty
71 } 75 }
72 76
73 fn callable_sig_from_fn_trait(&mut self, ty: &Ty, num_args: usize) -> Option<(Vec<Ty>, Ty)> { 77 fn callable_sig_from_fn_trait(&mut self, ty: &Ty, num_args: usize) -> Option<(Vec<Ty>, Ty)> {
@@ -98,10 +102,10 @@ impl<'a> InferenceContext<'a> {
98 goal: projection.trait_ref(self.db).cast(&Interner), 102 goal: projection.trait_ref(self.db).cast(&Interner),
99 environment: trait_env, 103 environment: trait_env,
100 }; 104 };
101 let canonical = self.canonicalizer().canonicalize_obligation(obligation.clone()); 105 let canonical = self.canonicalize(obligation.clone());
102 if self.db.trait_solve(krate, canonical.value).is_some() { 106 if self.db.trait_solve(krate, canonical.value.cast(&Interner)).is_some() {
103 self.push_obligation(obligation.goal); 107 self.push_obligation(obligation.goal);
104 let return_ty = self.normalize_projection_ty(projection); 108 let return_ty = self.table.normalize_projection_ty(projection);
105 Some((arg_tys, return_ty)) 109 Some((arg_tys, return_ty))
106 } else { 110 } else {
107 None 111 None
@@ -131,17 +135,21 @@ impl<'a> InferenceContext<'a> {
131 let condition_diverges = mem::replace(&mut self.diverges, Diverges::Maybe); 135 let condition_diverges = mem::replace(&mut self.diverges, Diverges::Maybe);
132 let mut both_arms_diverge = Diverges::Always; 136 let mut both_arms_diverge = Diverges::Always;
133 137
138 let mut result_ty = self.table.new_type_var();
134 let then_ty = self.infer_expr_inner(*then_branch, &expected); 139 let then_ty = self.infer_expr_inner(*then_branch, &expected);
135 both_arms_diverge &= mem::replace(&mut self.diverges, Diverges::Maybe); 140 both_arms_diverge &= mem::replace(&mut self.diverges, Diverges::Maybe);
141 result_ty = self.coerce_merge_branch(Some(*then_branch), &result_ty, &then_ty);
136 let else_ty = match else_branch { 142 let else_ty = match else_branch {
137 Some(else_branch) => self.infer_expr_inner(*else_branch, &expected), 143 Some(else_branch) => self.infer_expr_inner(*else_branch, &expected),
138 None => TyBuilder::unit(), 144 None => TyBuilder::unit(),
139 }; 145 };
140 both_arms_diverge &= self.diverges; 146 both_arms_diverge &= self.diverges;
147 // FIXME: create a synthetic `else {}` so we have something to refer to here instead of None?
148 result_ty = self.coerce_merge_branch(*else_branch, &result_ty, &else_ty);
141 149
142 self.diverges = condition_diverges | both_arms_diverge; 150 self.diverges = condition_diverges | both_arms_diverge;
143 151
144 self.coerce_merge_branch(&then_ty, &else_ty) 152 result_ty
145 } 153 }
146 Expr::Block { statements, tail, label, id: _ } => { 154 Expr::Block { statements, tail, label, id: _ } => {
147 let old_resolver = mem::replace( 155 let old_resolver = mem::replace(
@@ -277,12 +285,13 @@ impl<'a> InferenceContext<'a> {
277 // Eagerly try to relate the closure type with the expected 285 // Eagerly try to relate the closure type with the expected
278 // type, otherwise we often won't have enough information to 286 // type, otherwise we often won't have enough information to
279 // infer the body. 287 // infer the body.
280 self.coerce(&closure_ty, &expected.ty); 288 if let Some(t) = expected.only_has_type(&mut self.table) {
289 self.coerce(&closure_ty, &t);
290 }
281 291
282 // Now go through the argument patterns 292 // Now go through the argument patterns
283 for (arg_pat, arg_ty) in args.iter().zip(sig_tys) { 293 for (arg_pat, arg_ty) in args.iter().zip(sig_tys) {
284 let resolved = self.resolve_ty_as_possible(arg_ty); 294 self.infer_pat(*arg_pat, &arg_ty, BindingMode::default());
285 self.infer_pat(*arg_pat, &resolved, BindingMode::default());
286 } 295 }
287 296
288 let prev_diverges = mem::replace(&mut self.diverges, Diverges::Maybe); 297 let prev_diverges = mem::replace(&mut self.diverges, Diverges::Maybe);
@@ -297,13 +306,13 @@ impl<'a> InferenceContext<'a> {
297 } 306 }
298 Expr::Call { callee, args } => { 307 Expr::Call { callee, args } => {
299 let callee_ty = self.infer_expr(*callee, &Expectation::none()); 308 let callee_ty = self.infer_expr(*callee, &Expectation::none());
300 let canonicalized = self.canonicalizer().canonicalize_ty(callee_ty.clone()); 309 let canonicalized = self.canonicalize(callee_ty.clone());
301 let mut derefs = autoderef( 310 let mut derefs = autoderef(
302 self.db, 311 self.db,
303 self.resolver.krate(), 312 self.resolver.krate(),
304 InEnvironment { 313 InEnvironment {
305 goal: canonicalized.value.clone(), 314 goal: canonicalized.value.clone(),
306 environment: self.trait_env.env.clone(), 315 environment: self.table.trait_env.env.clone(),
307 }, 316 },
308 ); 317 );
309 let (param_tys, ret_ty): (Vec<Ty>, Ty) = derefs 318 let (param_tys, ret_ty): (Vec<Ty>, Ty) = derefs
@@ -350,7 +359,7 @@ impl<'a> InferenceContext<'a> {
350 359
351 let arm_ty = self.infer_expr_inner(arm.expr, &expected); 360 let arm_ty = self.infer_expr_inner(arm.expr, &expected);
352 all_arms_diverge &= self.diverges; 361 all_arms_diverge &= self.diverges;
353 result_ty = self.coerce_merge_branch(&result_ty, &arm_ty); 362 result_ty = self.coerce_merge_branch(Some(arm.expr), &result_ty, &arm_ty);
354 } 363 }
355 364
356 self.diverges = matchee_diverges | all_arms_diverge; 365 self.diverges = matchee_diverges | all_arms_diverge;
@@ -364,12 +373,6 @@ impl<'a> InferenceContext<'a> {
364 } 373 }
365 Expr::Continue { .. } => TyKind::Never.intern(&Interner), 374 Expr::Continue { .. } => TyKind::Never.intern(&Interner),
366 Expr::Break { expr, label } => { 375 Expr::Break { expr, label } => {
367 let val_ty = if let Some(expr) = expr {
368 self.infer_expr(*expr, &Expectation::none())
369 } else {
370 TyBuilder::unit()
371 };
372
373 let last_ty = 376 let last_ty =
374 if let Some(ctxt) = find_breakable(&mut self.breakables, label.as_ref()) { 377 if let Some(ctxt) = find_breakable(&mut self.breakables, label.as_ref()) {
375 ctxt.break_ty.clone() 378 ctxt.break_ty.clone()
@@ -377,7 +380,14 @@ impl<'a> InferenceContext<'a> {
377 self.err_ty() 380 self.err_ty()
378 }; 381 };
379 382
380 let merged_type = self.coerce_merge_branch(&last_ty, &val_ty); 383 let val_ty = if let Some(expr) = expr {
384 self.infer_expr(*expr, &Expectation::none())
385 } else {
386 TyBuilder::unit()
387 };
388
389 // FIXME: create a synthetic `()` during lowering so we have something to refer to here?
390 let merged_type = self.coerce_merge_branch(*expr, &last_ty, &val_ty);
381 391
382 if let Some(ctxt) = find_breakable(&mut self.breakables, label.as_ref()) { 392 if let Some(ctxt) = find_breakable(&mut self.breakables, label.as_ref()) {
383 ctxt.break_ty = merged_type; 393 ctxt.break_ty = merged_type;
@@ -411,7 +421,9 @@ impl<'a> InferenceContext<'a> {
411 self.write_variant_resolution(tgt_expr.into(), variant); 421 self.write_variant_resolution(tgt_expr.into(), variant);
412 } 422 }
413 423
414 self.unify(&ty, &expected.ty); 424 if let Some(t) = expected.only_has_type(&mut self.table) {
425 self.unify(&ty, &t);
426 }
415 427
416 let substs = ty 428 let substs = ty
417 .as_adt() 429 .as_adt()
@@ -442,7 +454,7 @@ impl<'a> InferenceContext<'a> {
442 } 454 }
443 Expr::Field { expr, name } => { 455 Expr::Field { expr, name } => {
444 let receiver_ty = self.infer_expr_inner(*expr, &Expectation::none()); 456 let receiver_ty = self.infer_expr_inner(*expr, &Expectation::none());
445 let canonicalized = self.canonicalizer().canonicalize_ty(receiver_ty); 457 let canonicalized = self.canonicalize(receiver_ty);
446 let ty = autoderef::autoderef( 458 let ty = autoderef::autoderef(
447 self.db, 459 self.db,
448 self.resolver.krate(), 460 self.resolver.krate(),
@@ -514,6 +526,7 @@ impl<'a> InferenceContext<'a> {
514 self.resolve_associated_type(inner_ty, self.resolve_ops_try_ok()) 526 self.resolve_associated_type(inner_ty, self.resolve_ops_try_ok())
515 } 527 }
516 Expr::Cast { expr, type_ref } => { 528 Expr::Cast { expr, type_ref } => {
529 // FIXME: propagate the "castable to" expectation (and find a test case that shows this is necessary)
517 let _inner_ty = self.infer_expr_inner(*expr, &Expectation::none()); 530 let _inner_ty = self.infer_expr_inner(*expr, &Expectation::none());
518 let cast_ty = self.make_ty(type_ref); 531 let cast_ty = self.make_ty(type_ref);
519 // FIXME check the cast... 532 // FIXME check the cast...
@@ -521,15 +534,17 @@ impl<'a> InferenceContext<'a> {
521 } 534 }
522 Expr::Ref { expr, rawness, mutability } => { 535 Expr::Ref { expr, rawness, mutability } => {
523 let mutability = lower_to_chalk_mutability(*mutability); 536 let mutability = lower_to_chalk_mutability(*mutability);
524 let expectation = if let Some((exp_inner, exp_rawness, exp_mutability)) = 537 let expectation = if let Some((exp_inner, exp_rawness, exp_mutability)) = expected
525 &expected.ty.as_reference_or_ptr() 538 .only_has_type(&mut self.table)
539 .as_ref()
540 .and_then(|t| t.as_reference_or_ptr())
526 { 541 {
527 if *exp_mutability == Mutability::Mut && mutability == Mutability::Not { 542 if exp_mutability == Mutability::Mut && mutability == Mutability::Not {
528 // FIXME: throw type error - expected mut reference but found shared ref, 543 // FIXME: record type error - expected mut reference but found shared ref,
529 // which cannot be coerced 544 // which cannot be coerced
530 } 545 }
531 if *exp_rawness == Rawness::Ref && *rawness == Rawness::RawPtr { 546 if exp_rawness == Rawness::Ref && *rawness == Rawness::RawPtr {
532 // FIXME: throw type error - expected reference but found ptr, 547 // FIXME: record type error - expected reference but found ptr,
533 // which cannot be coerced 548 // which cannot be coerced
534 } 549 }
535 Expectation::rvalue_hint(Ty::clone(exp_inner)) 550 Expectation::rvalue_hint(Ty::clone(exp_inner))
@@ -556,10 +571,11 @@ impl<'a> InferenceContext<'a> {
556 } 571 }
557 Expr::UnaryOp { expr, op } => { 572 Expr::UnaryOp { expr, op } => {
558 let inner_ty = self.infer_expr_inner(*expr, &Expectation::none()); 573 let inner_ty = self.infer_expr_inner(*expr, &Expectation::none());
574 let inner_ty = self.resolve_ty_shallow(&inner_ty);
559 match op { 575 match op {
560 UnaryOp::Deref => match self.resolver.krate() { 576 UnaryOp::Deref => match self.resolver.krate() {
561 Some(krate) => { 577 Some(krate) => {
562 let canonicalized = self.canonicalizer().canonicalize_ty(inner_ty); 578 let canonicalized = self.canonicalize(inner_ty);
563 match autoderef::deref( 579 match autoderef::deref(
564 self.db, 580 self.db,
565 krate, 581 krate,
@@ -612,8 +628,10 @@ impl<'a> InferenceContext<'a> {
612 _ => Expectation::none(), 628 _ => Expectation::none(),
613 }; 629 };
614 let lhs_ty = self.infer_expr(*lhs, &lhs_expectation); 630 let lhs_ty = self.infer_expr(*lhs, &lhs_expectation);
631 let lhs_ty = self.resolve_ty_shallow(&lhs_ty);
615 let rhs_expectation = op::binary_op_rhs_expectation(*op, lhs_ty.clone()); 632 let rhs_expectation = op::binary_op_rhs_expectation(*op, lhs_ty.clone());
616 let rhs_ty = self.infer_expr(*rhs, &Expectation::has_type(rhs_expectation)); 633 let rhs_ty = self.infer_expr(*rhs, &Expectation::has_type(rhs_expectation));
634 let rhs_ty = self.resolve_ty_shallow(&rhs_ty);
617 635
618 let ret = op::binary_op_return_ty(*op, lhs_ty.clone(), rhs_ty.clone()); 636 let ret = op::binary_op_return_ty(*op, lhs_ty.clone(), rhs_ty.clone());
619 637
@@ -676,7 +694,7 @@ impl<'a> InferenceContext<'a> {
676 if let (Some(index_trait), Some(krate)) = 694 if let (Some(index_trait), Some(krate)) =
677 (self.resolve_ops_index(), self.resolver.krate()) 695 (self.resolve_ops_index(), self.resolver.krate())
678 { 696 {
679 let canonicalized = self.canonicalizer().canonicalize_ty(base_ty); 697 let canonicalized = self.canonicalize(base_ty);
680 let self_ty = method_resolution::resolve_indexing_op( 698 let self_ty = method_resolution::resolve_indexing_op(
681 self.db, 699 self.db,
682 &canonicalized.value, 700 &canonicalized.value,
@@ -696,8 +714,12 @@ impl<'a> InferenceContext<'a> {
696 } 714 }
697 } 715 }
698 Expr::Tuple { exprs } => { 716 Expr::Tuple { exprs } => {
699 let mut tys = match expected.ty.kind(&Interner) { 717 let mut tys = match expected
700 TyKind::Tuple(_, substs) => substs 718 .only_has_type(&mut self.table)
719 .as_ref()
720 .map(|t| t.kind(&Interner))
721 {
722 Some(TyKind::Tuple(_, substs)) => substs
701 .iter(&Interner) 723 .iter(&Interner)
702 .map(|a| a.assert_ty_ref(&Interner).clone()) 724 .map(|a| a.assert_ty_ref(&Interner).clone())
703 .chain(repeat_with(|| self.table.new_type_var())) 725 .chain(repeat_with(|| self.table.new_type_var()))
@@ -713,14 +735,16 @@ impl<'a> InferenceContext<'a> {
713 TyKind::Tuple(tys.len(), Substitution::from_iter(&Interner, tys)).intern(&Interner) 735 TyKind::Tuple(tys.len(), Substitution::from_iter(&Interner, tys)).intern(&Interner)
714 } 736 }
715 Expr::Array(array) => { 737 Expr::Array(array) => {
716 let elem_ty = match expected.ty.kind(&Interner) { 738 let elem_ty =
717 TyKind::Array(st, _) | TyKind::Slice(st) => st.clone(), 739 match expected.to_option(&mut self.table).as_ref().map(|t| t.kind(&Interner)) {
718 _ => self.table.new_type_var(), 740 Some(TyKind::Array(st, _)) | Some(TyKind::Slice(st)) => st.clone(),
719 }; 741 _ => self.table.new_type_var(),
742 };
720 743
721 let len = match array { 744 let len = match array {
722 Array::ElementList(items) => { 745 Array::ElementList(items) => {
723 for expr in items.iter() { 746 for expr in items.iter() {
747 // FIXME: use CoerceMany (coerce_merge_branch)
724 self.infer_expr_coerce(*expr, &Expectation::has_type(elem_ty.clone())); 748 self.infer_expr_coerce(*expr, &Expectation::has_type(elem_ty.clone()));
725 } 749 }
726 Some(items.len() as u64) 750 Some(items.len() as u64)
@@ -785,7 +809,6 @@ impl<'a> InferenceContext<'a> {
785 }; 809 };
786 // use a new type variable if we got unknown here 810 // use a new type variable if we got unknown here
787 let ty = self.insert_type_vars_shallow(ty); 811 let ty = self.insert_type_vars_shallow(ty);
788 let ty = self.resolve_ty_as_possible(ty);
789 self.write_expr_ty(tgt_expr, ty.clone()); 812 self.write_expr_ty(tgt_expr, ty.clone());
790 ty 813 ty
791 } 814 }
@@ -813,7 +836,6 @@ impl<'a> InferenceContext<'a> {
813 } 836 }
814 } 837 }
815 838
816 let ty = self.resolve_ty_as_possible(ty);
817 self.infer_pat(*pat, &ty, BindingMode::default()); 839 self.infer_pat(*pat, &ty, BindingMode::default());
818 } 840 }
819 Statement::Expr { expr, .. } => { 841 Statement::Expr { expr, .. } => {
@@ -836,7 +858,9 @@ impl<'a> InferenceContext<'a> {
836 // we don't even make an attempt at coercion 858 // we don't even make an attempt at coercion
837 self.table.new_maybe_never_var() 859 self.table.new_maybe_never_var()
838 } else { 860 } else {
839 self.coerce(&TyBuilder::unit(), &expected.coercion_target()); 861 if let Some(t) = expected.only_has_type(&mut self.table) {
862 self.coerce(&TyBuilder::unit(), &t);
863 }
840 TyBuilder::unit() 864 TyBuilder::unit()
841 } 865 }
842 }; 866 };
@@ -852,7 +876,7 @@ impl<'a> InferenceContext<'a> {
852 generic_args: Option<&GenericArgs>, 876 generic_args: Option<&GenericArgs>,
853 ) -> Ty { 877 ) -> Ty {
854 let receiver_ty = self.infer_expr(receiver, &Expectation::none()); 878 let receiver_ty = self.infer_expr(receiver, &Expectation::none());
855 let canonicalized_receiver = self.canonicalizer().canonicalize_ty(receiver_ty.clone()); 879 let canonicalized_receiver = self.canonicalize(receiver_ty.clone());
856 880
857 let traits_in_scope = self.resolver.traits_in_scope(self.db.upcast()); 881 let traits_in_scope = self.resolver.traits_in_scope(self.db.upcast());
858 882
@@ -891,7 +915,8 @@ impl<'a> InferenceContext<'a> {
891 }; 915 };
892 // Apply autoref so the below unification works correctly 916 // Apply autoref so the below unification works correctly
893 // FIXME: return correct autorefs from lookup_method 917 // FIXME: return correct autorefs from lookup_method
894 let actual_receiver_ty = match expected_receiver_ty.as_reference() { 918 let actual_receiver_ty = match self.resolve_ty_shallow(&expected_receiver_ty).as_reference()
919 {
895 Some((_, lifetime, mutability)) => { 920 Some((_, lifetime, mutability)) => {
896 TyKind::Ref(mutability, lifetime, derefed_receiver_ty).intern(&Interner) 921 TyKind::Ref(mutability, lifetime, derefed_receiver_ty).intern(&Interner)
897 } 922 }
@@ -971,6 +996,7 @@ impl<'a> InferenceContext<'a> {
971 } 996 }
972 997
973 fn register_obligations_for_call(&mut self, callable_ty: &Ty) { 998 fn register_obligations_for_call(&mut self, callable_ty: &Ty) {
999 let callable_ty = self.resolve_ty_shallow(&callable_ty);
974 if let TyKind::FnDef(fn_def, parameters) = callable_ty.kind(&Interner) { 1000 if let TyKind::FnDef(fn_def, parameters) = callable_ty.kind(&Interner) {
975 let def: CallableDefId = from_chalk(self.db, *fn_def); 1001 let def: CallableDefId = from_chalk(self.db, *fn_def);
976 let generic_predicates = self.db.generic_predicates(def.into()); 1002 let generic_predicates = self.db.generic_predicates(def.into());
diff --git a/crates/hir_ty/src/infer/pat.rs b/crates/hir_ty/src/infer/pat.rs
index b15f4977d..9c8e3b6ae 100644
--- a/crates/hir_ty/src/infer/pat.rs
+++ b/crates/hir_ty/src/infer/pat.rs
@@ -94,14 +94,15 @@ impl<'a> InferenceContext<'a> {
94 pub(super) fn infer_pat( 94 pub(super) fn infer_pat(
95 &mut self, 95 &mut self,
96 pat: PatId, 96 pat: PatId,
97 mut expected: &Ty, 97 expected: &Ty,
98 mut default_bm: BindingMode, 98 mut default_bm: BindingMode,
99 ) -> Ty { 99 ) -> Ty {
100 let body = Arc::clone(&self.body); // avoid borrow checker problem 100 let body = Arc::clone(&self.body); // avoid borrow checker problem
101 let mut expected = self.resolve_ty_shallow(expected);
101 102
102 if is_non_ref_pat(&body, pat) { 103 if is_non_ref_pat(&body, pat) {
103 while let Some((inner, _lifetime, mutability)) = expected.as_reference() { 104 while let Some((inner, _lifetime, mutability)) = expected.as_reference() {
104 expected = inner; 105 expected = self.resolve_ty_shallow(inner);
105 default_bm = match default_bm { 106 default_bm = match default_bm {
106 BindingMode::Move => BindingMode::Ref(mutability), 107 BindingMode::Move => BindingMode::Ref(mutability),
107 BindingMode::Ref(Mutability::Not) => BindingMode::Ref(Mutability::Not), 108 BindingMode::Ref(Mutability::Not) => BindingMode::Ref(Mutability::Not),
@@ -147,9 +148,9 @@ impl<'a> InferenceContext<'a> {
147 } 148 }
148 Pat::Or(ref pats) => { 149 Pat::Or(ref pats) => {
149 if let Some((first_pat, rest)) = pats.split_first() { 150 if let Some((first_pat, rest)) = pats.split_first() {
150 let ty = self.infer_pat(*first_pat, expected, default_bm); 151 let ty = self.infer_pat(*first_pat, &expected, default_bm);
151 for pat in rest { 152 for pat in rest {
152 self.infer_pat(*pat, expected, default_bm); 153 self.infer_pat(*pat, &expected, default_bm);
153 } 154 }
154 ty 155 ty
155 } else { 156 } else {
@@ -173,13 +174,13 @@ impl<'a> InferenceContext<'a> {
173 Pat::TupleStruct { path: p, args: subpats, ellipsis } => self.infer_tuple_struct_pat( 174 Pat::TupleStruct { path: p, args: subpats, ellipsis } => self.infer_tuple_struct_pat(
174 p.as_deref(), 175 p.as_deref(),
175 subpats, 176 subpats,
176 expected, 177 &expected,
177 default_bm, 178 default_bm,
178 pat, 179 pat,
179 *ellipsis, 180 *ellipsis,
180 ), 181 ),
181 Pat::Record { path: p, args: fields, ellipsis: _ } => { 182 Pat::Record { path: p, args: fields, ellipsis: _ } => {
182 self.infer_record_pat(p.as_deref(), fields, expected, default_bm, pat) 183 self.infer_record_pat(p.as_deref(), fields, &expected, default_bm, pat)
183 } 184 }
184 Pat::Path(path) => { 185 Pat::Path(path) => {
185 // FIXME use correct resolver for the surrounding expression 186 // FIXME use correct resolver for the surrounding expression
@@ -193,7 +194,7 @@ impl<'a> InferenceContext<'a> {
193 BindingMode::convert(*mode) 194 BindingMode::convert(*mode)
194 }; 195 };
195 let inner_ty = if let Some(subpat) = subpat { 196 let inner_ty = if let Some(subpat) = subpat {
196 self.infer_pat(*subpat, expected, default_bm) 197 self.infer_pat(*subpat, &expected, default_bm)
197 } else { 198 } else {
198 expected.clone() 199 expected.clone()
199 }; 200 };
@@ -206,7 +207,6 @@ impl<'a> InferenceContext<'a> {
206 } 207 }
207 BindingMode::Move => inner_ty.clone(), 208 BindingMode::Move => inner_ty.clone(),
208 }; 209 };
209 let bound_ty = self.resolve_ty_as_possible(bound_ty);
210 self.write_pat_ty(pat, bound_ty); 210 self.write_pat_ty(pat, bound_ty);
211 return inner_ty; 211 return inner_ty;
212 } 212 }
@@ -265,13 +265,12 @@ impl<'a> InferenceContext<'a> {
265 }; 265 };
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.type_mismatches.insert(
270 pat.into(), 270 pat.into(),
271 TypeMismatch { expected: expected.clone(), actual: ty.clone() }, 271 TypeMismatch { expected: expected.clone(), actual: ty.clone() },
272 ); 272 );
273 } 273 }
274 let ty = self.resolve_ty_as_possible(ty);
275 self.write_pat_ty(pat, ty.clone()); 274 self.write_pat_ty(pat, ty.clone());
276 ty 275 ty
277 } 276 }
diff --git a/crates/hir_ty/src/infer/path.rs b/crates/hir_ty/src/infer/path.rs
index 495282eba..14c99eafd 100644
--- a/crates/hir_ty/src/infer/path.rs
+++ b/crates/hir_ty/src/infer/path.rs
@@ -65,7 +65,6 @@ impl<'a> InferenceContext<'a> {
65 let typable: ValueTyDefId = match value { 65 let typable: ValueTyDefId = match value {
66 ValueNs::LocalBinding(pat) => { 66 ValueNs::LocalBinding(pat) => {
67 let ty = self.result.type_of_pat.get(pat)?.clone(); 67 let ty = self.result.type_of_pat.get(pat)?.clone();
68 let ty = self.resolve_ty_as_possible(ty);
69 return Some(ty); 68 return Some(ty);
70 } 69 }
71 ValueNs::FunctionId(it) => it.into(), 70 ValueNs::FunctionId(it) => it.into(),
@@ -218,14 +217,14 @@ impl<'a> InferenceContext<'a> {
218 return Some(result); 217 return Some(result);
219 } 218 }
220 219
221 let canonical_ty = self.canonicalizer().canonicalize_ty(ty.clone()); 220 let canonical_ty = self.canonicalize(ty.clone());
222 let krate = self.resolver.krate()?; 221 let krate = self.resolver.krate()?;
223 let traits_in_scope = self.resolver.traits_in_scope(self.db.upcast()); 222 let traits_in_scope = self.resolver.traits_in_scope(self.db.upcast());
224 223
225 method_resolution::iterate_method_candidates( 224 method_resolution::iterate_method_candidates(
226 &canonical_ty.value, 225 &canonical_ty.value,
227 self.db, 226 self.db,
228 self.trait_env.clone(), 227 self.table.trait_env.clone(),
229 krate, 228 krate,
230 &traits_in_scope, 229 &traits_in_scope,
231 None, 230 None,
@@ -275,6 +274,7 @@ impl<'a> InferenceContext<'a> {
275 name: &Name, 274 name: &Name,
276 id: ExprOrPatId, 275 id: ExprOrPatId,
277 ) -> Option<(ValueNs, Option<Substitution>)> { 276 ) -> Option<(ValueNs, Option<Substitution>)> {
277 let ty = self.resolve_ty_shallow(ty);
278 let (enum_id, subst) = match ty.as_adt() { 278 let (enum_id, subst) = match ty.as_adt() {
279 Some((AdtId::EnumId(e), subst)) => (e, subst), 279 Some((AdtId::EnumId(e), subst)) => (e, subst),
280 _ => return None, 280 _ => return None,
diff --git a/crates/hir_ty/src/infer/unify.rs b/crates/hir_ty/src/infer/unify.rs
index d8e0b4320..21d3fb54e 100644
--- a/crates/hir_ty/src/infer/unify.rs
+++ b/crates/hir_ty/src/infer/unify.rs
@@ -1,177 +1,95 @@
1//! Unification and canonicalization logic. 1//! Unification and canonicalization logic.
2 2
3use std::borrow::Cow; 3use std::{fmt, mem, sync::Arc};
4 4
5use chalk_ir::{ 5use chalk_ir::{
6 cast::Cast, fold::Fold, interner::HasInterner, FloatTy, IntTy, TyVariableKind, UniverseIndex, 6 cast::Cast, fold::Fold, interner::HasInterner, zip::Zip, FloatTy, IntTy, TyVariableKind,
7 VariableKind, 7 UniverseIndex,
8}; 8};
9use ena::unify::{InPlaceUnificationTable, NoError, UnifyKey, UnifyValue}; 9use chalk_solve::infer::ParameterEnaVariableExt;
10use ena::unify::UnifyKey;
10 11
11use super::{DomainGoal, InferenceContext}; 12use super::{InferOk, InferResult, InferenceContext, TypeError};
12use crate::{ 13use crate::{
13 fold_tys, static_lifetime, AliasEq, AliasTy, BoundVar, Canonical, CanonicalVarKinds, 14 db::HirDatabase, fold_tys, static_lifetime, AliasEq, AliasTy, BoundVar, Canonical,
14 DebruijnIndex, FnPointer, FnSubst, InEnvironment, InferenceVar, Interner, Scalar, Substitution, 15 DebruijnIndex, GenericArg, Goal, Guidance, InEnvironment, InferenceVar, Interner, ProjectionTy,
15 Ty, TyExt, TyKind, WhereClause, 16 Scalar, Solution, Substitution, TraitEnvironment, Ty, TyKind, VariableKind,
16}; 17};
17 18
18impl<'a> InferenceContext<'a> { 19impl<'a> InferenceContext<'a> {
19 pub(super) fn canonicalizer<'b>(&'b mut self) -> Canonicalizer<'a, 'b> 20 pub(super) fn canonicalize<T: Fold<Interner> + HasInterner<Interner = Interner>>(
21 &mut self,
22 t: T,
23 ) -> Canonicalized<T::Result>
20 where 24 where
21 'a: 'b, 25 T::Result: HasInterner<Interner = Interner>,
22 { 26 {
23 Canonicalizer { ctx: self, free_vars: Vec::new(), var_stack: Vec::new() } 27 // try to resolve obligations before canonicalizing, since this might
28 // result in new knowledge about variables
29 self.resolve_obligations_as_possible();
30 self.table.canonicalize(t)
24 } 31 }
25} 32}
26 33
27pub(super) struct Canonicalizer<'a, 'b> 34#[derive(Debug, Clone)]
28where
29 'a: 'b,
30{
31 ctx: &'b mut InferenceContext<'a>,
32 free_vars: Vec<(InferenceVar, TyVariableKind)>,
33 /// A stack of type variables that is used to detect recursive types (which
34 /// are an error, but we need to protect against them to avoid stack
35 /// overflows).
36 var_stack: Vec<TypeVarId>,
37}
38
39#[derive(Debug)]
40pub(super) struct Canonicalized<T> 35pub(super) struct Canonicalized<T>
41where 36where
42 T: HasInterner<Interner = Interner>, 37 T: HasInterner<Interner = Interner>,
43{ 38{
44 pub(super) value: Canonical<T>, 39 pub(super) value: Canonical<T>,
45 free_vars: Vec<(InferenceVar, TyVariableKind)>, 40 free_vars: Vec<GenericArg>,
46}
47
48impl<'a, 'b> Canonicalizer<'a, 'b> {
49 fn add(&mut self, free_var: InferenceVar, kind: TyVariableKind) -> usize {
50 self.free_vars.iter().position(|&(v, _)| v == free_var).unwrap_or_else(|| {
51 let next_index = self.free_vars.len();
52 self.free_vars.push((free_var, kind));
53 next_index
54 })
55 }
56
57 fn do_canonicalize<T: Fold<Interner, Result = T> + HasInterner<Interner = Interner>>(
58 &mut self,
59 t: T,
60 binders: DebruijnIndex,
61 ) -> T {
62 fold_tys(
63 t,
64 |ty, binders| match ty.kind(&Interner) {
65 &TyKind::InferenceVar(var, kind) => {
66 let inner = from_inference_var(var);
67 if self.var_stack.contains(&inner) {
68 // recursive type
69 return self.ctx.table.type_variable_table.fallback_value(var, kind);
70 }
71 if let Some(known_ty) =
72 self.ctx.table.var_unification_table.inlined_probe_value(inner).known()
73 {
74 self.var_stack.push(inner);
75 let result = self.do_canonicalize(known_ty.clone(), binders);
76 self.var_stack.pop();
77 result
78 } else {
79 let root = self.ctx.table.var_unification_table.find(inner);
80 let position = self.add(to_inference_var(root), kind);
81 TyKind::BoundVar(BoundVar::new(binders, position)).intern(&Interner)
82 }
83 }
84 _ => ty,
85 },
86 binders,
87 )
88 }
89
90 fn into_canonicalized<T: HasInterner<Interner = Interner>>(
91 self,
92 result: T,
93 ) -> Canonicalized<T> {
94 let kinds = self
95 .free_vars
96 .iter()
97 .map(|&(_, k)| chalk_ir::WithKind::new(VariableKind::Ty(k), UniverseIndex::ROOT));
98 Canonicalized {
99 value: Canonical {
100 value: result,
101 binders: CanonicalVarKinds::from_iter(&Interner, kinds),
102 },
103 free_vars: self.free_vars,
104 }
105 }
106
107 pub(crate) fn canonicalize_ty(mut self, ty: Ty) -> Canonicalized<Ty> {
108 let result = self.do_canonicalize(ty, DebruijnIndex::INNERMOST);
109 self.into_canonicalized(result)
110 }
111
112 pub(crate) fn canonicalize_obligation(
113 mut self,
114 obligation: InEnvironment<DomainGoal>,
115 ) -> Canonicalized<InEnvironment<DomainGoal>> {
116 let result = match obligation.goal {
117 DomainGoal::Holds(wc) => {
118 DomainGoal::Holds(self.do_canonicalize(wc, DebruijnIndex::INNERMOST))
119 }
120 _ => unimplemented!(),
121 };
122 self.into_canonicalized(InEnvironment { goal: result, environment: obligation.environment })
123 }
124} 41}
125 42
126impl<T: HasInterner<Interner = Interner>> Canonicalized<T> { 43impl<T: HasInterner<Interner = Interner>> Canonicalized<T> {
127 pub(super) fn decanonicalize_ty(&self, ty: Ty) -> Ty { 44 pub(super) fn decanonicalize_ty(&self, ty: Ty) -> Ty {
128 crate::fold_free_vars(ty, |bound, _binders| { 45 chalk_ir::Substitute::apply(&self.free_vars, ty, &Interner)
129 let (v, k) = self.free_vars[bound.index];
130 TyKind::InferenceVar(v, k).intern(&Interner)
131 })
132 } 46 }
133 47
134 pub(super) fn apply_solution( 48 pub(super) fn apply_solution(
135 &self, 49 &self,
136 ctx: &mut InferenceContext<'_>, 50 ctx: &mut InferenceTable,
137 solution: Canonical<Substitution>, 51 solution: Canonical<Substitution>,
138 ) { 52 ) {
139 // the solution may contain new variables, which we need to convert to new inference vars 53 // the solution may contain new variables, which we need to convert to new inference vars
140 let new_vars = Substitution::from_iter( 54 let new_vars = Substitution::from_iter(
141 &Interner, 55 &Interner,
142 solution.binders.iter(&Interner).map(|k| match k.kind { 56 solution.binders.iter(&Interner).map(|k| match k.kind {
143 VariableKind::Ty(TyVariableKind::General) => { 57 VariableKind::Ty(TyVariableKind::General) => ctx.new_type_var().cast(&Interner),
144 ctx.table.new_type_var().cast(&Interner) 58 VariableKind::Ty(TyVariableKind::Integer) => ctx.new_integer_var().cast(&Interner),
145 } 59 VariableKind::Ty(TyVariableKind::Float) => ctx.new_float_var().cast(&Interner),
146 VariableKind::Ty(TyVariableKind::Integer) => {
147 ctx.table.new_integer_var().cast(&Interner)
148 }
149 VariableKind::Ty(TyVariableKind::Float) => {
150 ctx.table.new_float_var().cast(&Interner)
151 }
152 // Chalk can sometimes return new lifetime variables. We just use the static lifetime everywhere 60 // Chalk can sometimes return new lifetime variables. We just use the static lifetime everywhere
153 VariableKind::Lifetime => static_lifetime().cast(&Interner), 61 VariableKind::Lifetime => static_lifetime().cast(&Interner),
154 _ => panic!("const variable in solution"), 62 _ => panic!("const variable in solution"),
155 }), 63 }),
156 ); 64 );
157 for (i, ty) in solution.value.iter(&Interner).enumerate() { 65 for (i, v) in solution.value.iter(&Interner).enumerate() {
158 let (v, k) = self.free_vars[i]; 66 let var = self.free_vars[i].clone();
159 // eagerly replace projections in the type; we may be getting types 67 if let Some(ty) = v.ty(&Interner) {
160 // e.g. from where clauses where this hasn't happened yet 68 // eagerly replace projections in the type; we may be getting types
161 let ty = ctx.normalize_associated_types_in( 69 // e.g. from where clauses where this hasn't happened yet
162 new_vars.apply(ty.assert_ty_ref(&Interner).clone(), &Interner), 70 let ty = ctx.normalize_associated_types_in(new_vars.apply(ty.clone(), &Interner));
163 ); 71 ctx.unify(var.assert_ty_ref(&Interner), &ty);
164 ctx.table.unify(&TyKind::InferenceVar(v, k).intern(&Interner), &ty); 72 } else {
73 let _ = ctx.try_unify(&var, &new_vars.apply(v.clone(), &Interner));
74 }
165 } 75 }
166 } 76 }
167} 77}
168 78
169pub fn could_unify(t1: &Ty, t2: &Ty) -> bool { 79pub fn could_unify(
170 InferenceTable::new().unify(t1, t2) 80 db: &dyn HirDatabase,
81 env: Arc<TraitEnvironment>,
82 tys: &Canonical<(Ty, Ty)>,
83) -> bool {
84 unify(db, env, tys).is_some()
171} 85}
172 86
173pub(crate) fn unify(tys: &Canonical<(Ty, Ty)>) -> Option<Substitution> { 87pub(crate) fn unify(
174 let mut table = InferenceTable::new(); 88 db: &dyn HirDatabase,
89 env: Arc<TraitEnvironment>,
90 tys: &Canonical<(Ty, Ty)>,
91) -> Option<Substitution> {
92 let mut table = InferenceTable::new(db, env);
175 let vars = Substitution::from_iter( 93 let vars = Substitution::from_iter(
176 &Interner, 94 &Interner,
177 tys.binders 95 tys.binders
@@ -187,77 +105,151 @@ pub(crate) fn unify(tys: &Canonical<(Ty, Ty)>) -> Option<Substitution> {
187 } 105 }
188 // default any type vars that weren't unified back to their original bound vars 106 // default any type vars that weren't unified back to their original bound vars
189 // (kind of hacky) 107 // (kind of hacky)
190 for (i, var) in vars.iter(&Interner).enumerate() { 108 let find_var = |iv| {
191 let var = var.assert_ty_ref(&Interner); 109 vars.iter(&Interner).position(|v| match v.interned() {
192 if &*table.resolve_ty_shallow(var) == var { 110 chalk_ir::GenericArgData::Ty(ty) => ty.inference_var(&Interner),
193 table.unify( 111 chalk_ir::GenericArgData::Lifetime(lt) => lt.inference_var(&Interner),
194 var, 112 chalk_ir::GenericArgData::Const(c) => c.inference_var(&Interner),
195 &TyKind::BoundVar(BoundVar::new(DebruijnIndex::INNERMOST, i)).intern(&Interner), 113 } == Some(iv))
196 ); 114 };
197 } 115 let fallback = |iv, kind, default, binder| match kind {
198 } 116 chalk_ir::VariableKind::Ty(_ty_kind) => find_var(iv)
117 .map_or(default, |i| BoundVar::new(binder, i).to_ty(&Interner).cast(&Interner)),
118 chalk_ir::VariableKind::Lifetime => find_var(iv)
119 .map_or(default, |i| BoundVar::new(binder, i).to_lifetime(&Interner).cast(&Interner)),
120 chalk_ir::VariableKind::Const(ty) => find_var(iv)
121 .map_or(default, |i| BoundVar::new(binder, i).to_const(&Interner, ty).cast(&Interner)),
122 };
199 Some(Substitution::from_iter( 123 Some(Substitution::from_iter(
200 &Interner, 124 &Interner,
201 vars.iter(&Interner) 125 vars.iter(&Interner)
202 .map(|v| table.resolve_ty_completely(v.assert_ty_ref(&Interner).clone())), 126 .map(|v| table.resolve_with_fallback(v.assert_ty_ref(&Interner).clone(), fallback)),
203 )) 127 ))
204} 128}
205 129
206#[derive(Clone, Debug)] 130#[derive(Copy, Clone, Debug)]
207pub(super) struct TypeVariableTable { 131pub(crate) struct TypeVariableData {
208 inner: Vec<TypeVariableData>, 132 diverging: bool,
209} 133}
210 134
211impl TypeVariableTable { 135type ChalkInferenceTable = chalk_solve::infer::InferenceTable<Interner>;
212 fn push(&mut self, data: TypeVariableData) { 136
213 self.inner.push(data); 137#[derive(Clone)]
138pub(crate) struct InferenceTable<'a> {
139 pub(crate) db: &'a dyn HirDatabase,
140 pub(crate) trait_env: Arc<TraitEnvironment>,
141 var_unification_table: ChalkInferenceTable,
142 type_variable_table: Vec<TypeVariableData>,
143 pending_obligations: Vec<Canonicalized<InEnvironment<Goal>>>,
144}
145
146impl<'a> InferenceTable<'a> {
147 pub(crate) fn new(db: &'a dyn HirDatabase, trait_env: Arc<TraitEnvironment>) -> Self {
148 InferenceTable {
149 db,
150 trait_env,
151 var_unification_table: ChalkInferenceTable::new(),
152 type_variable_table: Vec::new(),
153 pending_obligations: Vec::new(),
154 }
214 } 155 }
215 156
216 pub(super) fn set_diverging(&mut self, iv: InferenceVar, diverging: bool) { 157 /// Chalk doesn't know about the `diverging` flag, so when it unifies two
217 self.inner[from_inference_var(iv).0 as usize].diverging = diverging; 158 /// type variables of which one is diverging, the chosen root might not be
159 /// diverging and we have no way of marking it as such at that time. This
160 /// function goes through all type variables and make sure their root is
161 /// marked as diverging if necessary, so that resolving them gives the right
162 /// result.
163 pub(super) fn propagate_diverging_flag(&mut self) {
164 for i in 0..self.type_variable_table.len() {
165 if !self.type_variable_table[i].diverging {
166 continue;
167 }
168 let v = InferenceVar::from(i as u32);
169 let root = self.var_unification_table.inference_var_root(v);
170 if let Some(data) = self.type_variable_table.get_mut(root.index() as usize) {
171 data.diverging = true;
172 }
173 }
218 } 174 }
219 175
220 fn is_diverging(&mut self, iv: InferenceVar) -> bool { 176 pub(super) fn set_diverging(&mut self, iv: InferenceVar, diverging: bool) {
221 self.inner[from_inference_var(iv).0 as usize].diverging 177 self.type_variable_table[iv.index() as usize].diverging = diverging;
222 } 178 }
223 179
224 fn fallback_value(&self, iv: InferenceVar, kind: TyVariableKind) -> Ty { 180 fn fallback_value(&self, iv: InferenceVar, kind: TyVariableKind) -> Ty {
225 match kind { 181 match kind {
226 _ if self.inner[from_inference_var(iv).0 as usize].diverging => TyKind::Never, 182 _ if self
183 .type_variable_table
184 .get(iv.index() as usize)
185 .map_or(false, |data| data.diverging) =>
186 {
187 TyKind::Never
188 }
227 TyVariableKind::General => TyKind::Error, 189 TyVariableKind::General => TyKind::Error,
228 TyVariableKind::Integer => TyKind::Scalar(Scalar::Int(IntTy::I32)), 190 TyVariableKind::Integer => TyKind::Scalar(Scalar::Int(IntTy::I32)),
229 TyVariableKind::Float => TyKind::Scalar(Scalar::Float(FloatTy::F64)), 191 TyVariableKind::Float => TyKind::Scalar(Scalar::Float(FloatTy::F64)),
230 } 192 }
231 .intern(&Interner) 193 .intern(&Interner)
232 } 194 }
233}
234 195
235#[derive(Copy, Clone, Debug)] 196 pub(super) fn canonicalize<T: Fold<Interner> + HasInterner<Interner = Interner>>(
236pub(crate) struct TypeVariableData { 197 &mut self,
237 diverging: bool, 198 t: T,
238} 199 ) -> Canonicalized<T::Result>
200 where
201 T::Result: HasInterner<Interner = Interner>,
202 {
203 let result = self.var_unification_table.canonicalize(&Interner, t);
204 let free_vars = result
205 .free_vars
206 .into_iter()
207 .map(|free_var| free_var.to_generic_arg(&Interner))
208 .collect();
209 Canonicalized { value: result.quantified, free_vars }
210 }
211
212 /// Recurses through the given type, normalizing associated types mentioned
213 /// in it by replacing them by type variables and registering obligations to
214 /// resolve later. This should be done once for every type we get from some
215 /// type annotation (e.g. from a let type annotation, field type or function
216 /// call). `make_ty` handles this already, but e.g. for field types we need
217 /// to do it as well.
218 pub(super) fn normalize_associated_types_in(&mut self, ty: Ty) -> Ty {
219 fold_tys(
220 ty,
221 |ty, _| match ty.kind(&Interner) {
222 TyKind::Alias(AliasTy::Projection(proj_ty)) => {
223 self.normalize_projection_ty(proj_ty.clone())
224 }
225 _ => ty,
226 },
227 DebruijnIndex::INNERMOST,
228 )
229 }
239 230
240#[derive(Clone, Debug)] 231 pub(super) fn normalize_projection_ty(&mut self, proj_ty: ProjectionTy) -> Ty {
241pub(crate) struct InferenceTable { 232 let var = self.new_type_var();
242 pub(super) var_unification_table: InPlaceUnificationTable<TypeVarId>, 233 let alias_eq = AliasEq { alias: AliasTy::Projection(proj_ty), ty: var.clone() };
243 pub(super) type_variable_table: TypeVariableTable, 234 let obligation = alias_eq.cast(&Interner);
244 pub(super) revision: u32, 235 self.register_obligation(obligation);
245} 236 var
237 }
246 238
247impl InferenceTable { 239 fn extend_type_variable_table(&mut self, to_index: usize) {
248 pub(crate) fn new() -> Self { 240 self.type_variable_table.extend(
249 InferenceTable { 241 (0..1 + to_index - self.type_variable_table.len())
250 var_unification_table: InPlaceUnificationTable::new(), 242 .map(|_| TypeVariableData { diverging: false }),
251 type_variable_table: TypeVariableTable { inner: Vec::new() }, 243 );
252 revision: 0,
253 }
254 } 244 }
255 245
256 fn new_var(&mut self, kind: TyVariableKind, diverging: bool) -> Ty { 246 fn new_var(&mut self, kind: TyVariableKind, diverging: bool) -> Ty {
257 self.type_variable_table.push(TypeVariableData { diverging }); 247 let var = self.var_unification_table.new_variable(UniverseIndex::ROOT);
258 let key = self.var_unification_table.new_key(TypeVarValue::Unknown); 248 // Chalk might have created some type variables for its own purposes that we don't know about...
259 assert_eq!(key.0 as usize, self.type_variable_table.inner.len() - 1); 249 self.extend_type_variable_table(var.index() as usize);
260 TyKind::InferenceVar(to_inference_var(key), kind).intern(&Interner) 250 assert_eq!(var.index() as usize, self.type_variable_table.len() - 1);
251 self.type_variable_table[var.index() as usize].diverging = diverging;
252 var.to_ty_with_kind(&Interner, kind)
261 } 253 }
262 254
263 pub(crate) fn new_type_var(&mut self) -> Ty { 255 pub(crate) fn new_type_var(&mut self) -> Ty {
@@ -276,350 +268,261 @@ impl InferenceTable {
276 self.new_var(TyVariableKind::General, true) 268 self.new_var(TyVariableKind::General, true)
277 } 269 }
278 270
279 pub(crate) fn resolve_ty_completely(&mut self, ty: Ty) -> Ty { 271 pub(crate) fn resolve_with_fallback<T>(
280 self.resolve_ty_completely_inner(&mut Vec::new(), ty) 272 &mut self,
273 t: T,
274 fallback: impl Fn(InferenceVar, VariableKind, GenericArg, DebruijnIndex) -> GenericArg,
275 ) -> T::Result
276 where
277 T: HasInterner<Interner = Interner> + Fold<Interner>,
278 {
279 self.resolve_with_fallback_inner(&mut Vec::new(), t, &fallback)
281 } 280 }
282 281
283 pub(crate) fn resolve_ty_as_possible(&mut self, ty: Ty) -> Ty { 282 fn resolve_with_fallback_inner<T>(
284 self.resolve_ty_as_possible_inner(&mut Vec::new(), ty) 283 &mut self,
284 var_stack: &mut Vec<InferenceVar>,
285 t: T,
286 fallback: &impl Fn(InferenceVar, VariableKind, GenericArg, DebruijnIndex) -> GenericArg,
287 ) -> T::Result
288 where
289 T: HasInterner<Interner = Interner> + Fold<Interner>,
290 {
291 t.fold_with(
292 &mut resolve::Resolver { table: self, var_stack, fallback },
293 DebruijnIndex::INNERMOST,
294 )
295 .expect("fold failed unexpectedly")
285 } 296 }
286 297
287 pub(crate) fn unify(&mut self, ty1: &Ty, ty2: &Ty) -> bool { 298 pub(crate) fn resolve_ty_completely(&mut self, ty: Ty) -> Ty {
288 self.unify_inner(ty1, ty2, 0) 299 self.resolve_with_fallback(ty, |_, _, d, _| d)
289 } 300 }
290 301
291 pub(crate) fn unify_substs( 302 /// Unify two types and register new trait goals that arise from that.
292 &mut self, 303 pub(crate) fn unify(&mut self, ty1: &Ty, ty2: &Ty) -> bool {
293 substs1: &Substitution, 304 let result = if let Ok(r) = self.try_unify(ty1, ty2) {
294 substs2: &Substitution, 305 r
295 depth: usize, 306 } else {
296 ) -> bool { 307 return false;
297 substs1.iter(&Interner).zip(substs2.iter(&Interner)).all(|(t1, t2)| { 308 };
298 self.unify_inner(t1.assert_ty_ref(&Interner), t2.assert_ty_ref(&Interner), depth) 309 self.register_infer_ok(result);
299 }) 310 true
300 } 311 }
301 312
302 fn unify_inner(&mut self, ty1: &Ty, ty2: &Ty, depth: usize) -> bool { 313 /// Unify two types and return new trait goals arising from it, so the
303 if depth > 1000 { 314 /// caller needs to deal with them.
304 // prevent stackoverflows 315 pub(crate) fn try_unify<T: Zip<Interner>>(&mut self, t1: &T, t2: &T) -> InferResult {
305 panic!("infinite recursion in unification"); 316 match self.var_unification_table.relate(
306 } 317 &Interner,
307 if ty1 == ty2 { 318 &self.db,
308 return true; 319 &self.trait_env.env,
309 } 320 chalk_ir::Variance::Invariant,
310 // try to resolve type vars first 321 t1,
311 let ty1 = self.resolve_ty_shallow(ty1); 322 t2,
312 let ty2 = self.resolve_ty_shallow(ty2); 323 ) {
313 if ty1.equals_ctor(&ty2) { 324 Ok(result) => Ok(InferOk { goals: result.goals }),
314 match (ty1.kind(&Interner), ty2.kind(&Interner)) { 325 Err(chalk_ir::NoSolution) => Err(TypeError),
315 (TyKind::Adt(_, substs1), TyKind::Adt(_, substs2))
316 | (TyKind::FnDef(_, substs1), TyKind::FnDef(_, substs2))
317 | (
318 TyKind::Function(FnPointer { substitution: FnSubst(substs1), .. }),
319 TyKind::Function(FnPointer { substitution: FnSubst(substs2), .. }),
320 )
321 | (TyKind::Tuple(_, substs1), TyKind::Tuple(_, substs2))
322 | (TyKind::OpaqueType(_, substs1), TyKind::OpaqueType(_, substs2))
323 | (TyKind::AssociatedType(_, substs1), TyKind::AssociatedType(_, substs2))
324 | (TyKind::Closure(.., substs1), TyKind::Closure(.., substs2)) => {
325 self.unify_substs(substs1, substs2, depth + 1)
326 }
327 (TyKind::Array(ty1, c1), TyKind::Array(ty2, c2)) if c1 == c2 => {
328 self.unify_inner(ty1, ty2, depth + 1)
329 }
330 (TyKind::Ref(_, _, ty1), TyKind::Ref(_, _, ty2))
331 | (TyKind::Raw(_, ty1), TyKind::Raw(_, ty2))
332 | (TyKind::Slice(ty1), TyKind::Slice(ty2)) => self.unify_inner(ty1, ty2, depth + 1),
333 _ => true, /* we checked equals_ctor already */
334 }
335 } else if let (TyKind::Closure(.., substs1), TyKind::Closure(.., substs2)) =
336 (ty1.kind(&Interner), ty2.kind(&Interner))
337 {
338 self.unify_substs(substs1, substs2, depth + 1)
339 } else {
340 self.unify_inner_trivial(&ty1, &ty2, depth)
341 } 326 }
342 } 327 }
343 328
344 pub(super) fn unify_inner_trivial(&mut self, ty1: &Ty, ty2: &Ty, depth: usize) -> bool { 329 /// If `ty` is a type variable with known type, returns that type;
345 match (ty1.kind(&Interner), ty2.kind(&Interner)) { 330 /// otherwise, return ty.
346 (TyKind::Error, _) | (_, TyKind::Error) => true, 331 pub(crate) fn resolve_ty_shallow(&mut self, ty: &Ty) -> Ty {
332 self.var_unification_table.normalize_ty_shallow(&Interner, ty).unwrap_or_else(|| ty.clone())
333 }
347 334
348 (TyKind::Placeholder(p1), TyKind::Placeholder(p2)) if *p1 == *p2 => true, 335 pub(crate) fn register_obligation(&mut self, goal: Goal) {
336 let in_env = InEnvironment::new(&self.trait_env.env, goal);
337 self.register_obligation_in_env(in_env)
338 }
349 339
350 (TyKind::Dyn(dyn1), TyKind::Dyn(dyn2)) 340 fn register_obligation_in_env(&mut self, goal: InEnvironment<Goal>) {
351 if dyn1.bounds.skip_binders().interned().len() 341 let canonicalized = self.canonicalize(goal);
352 == dyn2.bounds.skip_binders().interned().len() => 342 if !self.try_resolve_obligation(&canonicalized) {
353 { 343 self.pending_obligations.push(canonicalized);
354 for (pred1, pred2) in dyn1 344 }
355 .bounds 345 }
356 .skip_binders()
357 .interned()
358 .iter()
359 .zip(dyn2.bounds.skip_binders().interned().iter())
360 {
361 if !self.unify_preds(pred1.skip_binders(), pred2.skip_binders(), depth + 1) {
362 return false;
363 }
364 }
365 true
366 }
367 346
368 ( 347 pub(crate) fn register_infer_ok(&mut self, infer_ok: InferOk) {
369 TyKind::InferenceVar(tv1, TyVariableKind::General), 348 infer_ok.goals.into_iter().for_each(|goal| self.register_obligation_in_env(goal));
370 TyKind::InferenceVar(tv2, TyVariableKind::General), 349 }
371 )
372 | (
373 TyKind::InferenceVar(tv1, TyVariableKind::Integer),
374 TyKind::InferenceVar(tv2, TyVariableKind::Integer),
375 )
376 | (
377 TyKind::InferenceVar(tv1, TyVariableKind::Float),
378 TyKind::InferenceVar(tv2, TyVariableKind::Float),
379 ) if self.type_variable_table.is_diverging(*tv1)
380 == self.type_variable_table.is_diverging(*tv2) =>
381 {
382 // both type vars are unknown since we tried to resolve them
383 if !self
384 .var_unification_table
385 .unioned(from_inference_var(*tv1), from_inference_var(*tv2))
386 {
387 self.var_unification_table
388 .union(from_inference_var(*tv1), from_inference_var(*tv2));
389 self.revision += 1;
390 }
391 true
392 }
393 350
394 // The order of MaybeNeverTypeVar matters here. 351 pub(crate) fn resolve_obligations_as_possible(&mut self) {
395 // Unifying MaybeNeverTypeVar and TypeVar will let the latter become MaybeNeverTypeVar. 352 let _span = profile::span("resolve_obligations_as_possible");
396 // Unifying MaybeNeverTypeVar and other concrete type will let the former become it. 353 let mut changed = true;
397 (TyKind::InferenceVar(tv, TyVariableKind::General), other) 354 let mut obligations = Vec::new();
398 | (other, TyKind::InferenceVar(tv, TyVariableKind::General)) 355 while changed {
399 | ( 356 changed = false;
400 TyKind::InferenceVar(tv, TyVariableKind::Integer), 357 mem::swap(&mut self.pending_obligations, &mut obligations);
401 other @ TyKind::Scalar(Scalar::Int(_)), 358 for canonicalized in obligations.drain(..) {
402 ) 359 if !self.check_changed(&canonicalized) {
403 | ( 360 self.pending_obligations.push(canonicalized);
404 other @ TyKind::Scalar(Scalar::Int(_)), 361 continue;
405 TyKind::InferenceVar(tv, TyVariableKind::Integer), 362 }
406 ) 363 changed = true;
407 | ( 364 let uncanonical = chalk_ir::Substitute::apply(
408 TyKind::InferenceVar(tv, TyVariableKind::Integer), 365 &canonicalized.free_vars,
409 other @ TyKind::Scalar(Scalar::Uint(_)), 366 canonicalized.value.value,
410 ) 367 &Interner,
411 | (
412 other @ TyKind::Scalar(Scalar::Uint(_)),
413 TyKind::InferenceVar(tv, TyVariableKind::Integer),
414 )
415 | (
416 TyKind::InferenceVar(tv, TyVariableKind::Float),
417 other @ TyKind::Scalar(Scalar::Float(_)),
418 )
419 | (
420 other @ TyKind::Scalar(Scalar::Float(_)),
421 TyKind::InferenceVar(tv, TyVariableKind::Float),
422 ) => {
423 // the type var is unknown since we tried to resolve it
424 self.var_unification_table.union_value(
425 from_inference_var(*tv),
426 TypeVarValue::Known(other.clone().intern(&Interner)),
427 ); 368 );
428 self.revision += 1; 369 self.register_obligation_in_env(uncanonical);
429 true
430 } 370 }
431
432 _ => false,
433 } 371 }
434 } 372 }
435 373
436 fn unify_preds(&mut self, pred1: &WhereClause, pred2: &WhereClause, depth: usize) -> bool { 374 /// This checks whether any of the free variables in the `canonicalized`
437 match (pred1, pred2) { 375 /// have changed (either been unified with another variable, or with a
438 (WhereClause::Implemented(tr1), WhereClause::Implemented(tr2)) 376 /// value). If this is not the case, we don't need to try to solve the goal
439 if tr1.trait_id == tr2.trait_id => 377 /// again -- it'll give the same result as last time.
440 { 378 fn check_changed(&mut self, canonicalized: &Canonicalized<InEnvironment<Goal>>) -> bool {
441 self.unify_substs(&tr1.substitution, &tr2.substitution, depth + 1) 379 canonicalized.free_vars.iter().any(|var| {
380 let iv = match var.data(&Interner) {
381 chalk_ir::GenericArgData::Ty(ty) => ty.inference_var(&Interner),
382 chalk_ir::GenericArgData::Lifetime(lt) => lt.inference_var(&Interner),
383 chalk_ir::GenericArgData::Const(c) => c.inference_var(&Interner),
442 } 384 }
443 ( 385 .expect("free var is not inference var");
444 WhereClause::AliasEq(AliasEq { alias: alias1, ty: ty1 }), 386 if self.var_unification_table.probe_var(iv).is_some() {
445 WhereClause::AliasEq(AliasEq { alias: alias2, ty: ty2 }), 387 return true;
446 ) => {
447 let (substitution1, substitution2) = match (alias1, alias2) {
448 (AliasTy::Projection(projection_ty1), AliasTy::Projection(projection_ty2))
449 if projection_ty1.associated_ty_id == projection_ty2.associated_ty_id =>
450 {
451 (&projection_ty1.substitution, &projection_ty2.substitution)
452 }
453 (AliasTy::Opaque(opaque1), AliasTy::Opaque(opaque2))
454 if opaque1.opaque_ty_id == opaque2.opaque_ty_id =>
455 {
456 (&opaque1.substitution, &opaque2.substitution)
457 }
458 _ => return false,
459 };
460 self.unify_substs(&substitution1, &substitution2, depth + 1)
461 && self.unify_inner(&ty1, &ty2, depth + 1)
462 } 388 }
463 _ => false, 389 let root = self.var_unification_table.inference_var_root(iv);
464 } 390 iv != root
391 })
465 } 392 }
466 393
467 /// If `ty` is a type variable with known type, returns that type; 394 fn try_resolve_obligation(
468 /// otherwise, return ty. 395 &mut self,
469 pub(crate) fn resolve_ty_shallow<'b>(&mut self, ty: &'b Ty) -> Cow<'b, Ty> { 396 canonicalized: &Canonicalized<InEnvironment<Goal>>,
470 let mut ty = Cow::Borrowed(ty); 397 ) -> bool {
471 // The type variable could resolve to a int/float variable. Hence try 398 let solution = self.db.trait_solve(self.trait_env.krate, canonicalized.value.clone());
472 // resolving up to three times; each type of variable shouldn't occur 399
473 // more than once 400 match solution {
474 for i in 0..3 { 401 Some(Solution::Unique(canonical_subst)) => {
475 if i > 0 { 402 canonicalized.apply_solution(
476 cov_mark::hit!(type_var_resolves_to_int_var); 403 self,
404 Canonical {
405 binders: canonical_subst.binders,
406 // FIXME: handle constraints
407 value: canonical_subst.value.subst,
408 },
409 );
410 true
477 } 411 }
478 match ty.kind(&Interner) { 412 Some(Solution::Ambig(Guidance::Definite(substs))) => {
479 TyKind::InferenceVar(tv, _) => { 413 canonicalized.apply_solution(self, substs);
480 let inner = from_inference_var(*tv); 414 false
481 match self.var_unification_table.inlined_probe_value(inner).known() { 415 }
482 Some(known_ty) => { 416 Some(_) => {
483 // The known_ty can't be a type var itself 417 // FIXME use this when trying to resolve everything at the end
484 ty = Cow::Owned(known_ty.clone()); 418 false
485 } 419 }
486 _ => return ty, 420 None => {
487 } 421 // FIXME obligation cannot be fulfilled => diagnostic
488 } 422 true
489 _ => return ty,
490 } 423 }
491 } 424 }
492 log::error!("Inference variable still not resolved: {:?}", ty);
493 ty
494 }
495
496 /// Resolves the type as far as currently possible, replacing type variables
497 /// by their known types. All types returned by the infer_* functions should
498 /// be resolved as far as possible, i.e. contain no type variables with
499 /// known type.
500 fn resolve_ty_as_possible_inner(&mut self, tv_stack: &mut Vec<TypeVarId>, ty: Ty) -> Ty {
501 fold_tys(
502 ty,
503 |ty, _| match ty.kind(&Interner) {
504 &TyKind::InferenceVar(tv, kind) => {
505 let inner = from_inference_var(tv);
506 if tv_stack.contains(&inner) {
507 cov_mark::hit!(type_var_cycles_resolve_as_possible);
508 // recursive type
509 return self.type_variable_table.fallback_value(tv, kind);
510 }
511 if let Some(known_ty) =
512 self.var_unification_table.inlined_probe_value(inner).known()
513 {
514 // known_ty may contain other variables that are known by now
515 tv_stack.push(inner);
516 let result = self.resolve_ty_as_possible_inner(tv_stack, known_ty.clone());
517 tv_stack.pop();
518 result
519 } else {
520 ty
521 }
522 }
523 _ => ty,
524 },
525 DebruijnIndex::INNERMOST,
526 )
527 }
528
529 /// Resolves the type completely; type variables without known type are
530 /// replaced by TyKind::Unknown.
531 fn resolve_ty_completely_inner(&mut self, tv_stack: &mut Vec<TypeVarId>, ty: Ty) -> Ty {
532 fold_tys(
533 ty,
534 |ty, _| match ty.kind(&Interner) {
535 &TyKind::InferenceVar(tv, kind) => {
536 let inner = from_inference_var(tv);
537 if tv_stack.contains(&inner) {
538 cov_mark::hit!(type_var_cycles_resolve_completely);
539 // recursive type
540 return self.type_variable_table.fallback_value(tv, kind);
541 }
542 if let Some(known_ty) =
543 self.var_unification_table.inlined_probe_value(inner).known()
544 {
545 // known_ty may contain other variables that are known by now
546 tv_stack.push(inner);
547 let result = self.resolve_ty_completely_inner(tv_stack, known_ty.clone());
548 tv_stack.pop();
549 result
550 } else {
551 self.type_variable_table.fallback_value(tv, kind)
552 }
553 }
554 _ => ty,
555 },
556 DebruijnIndex::INNERMOST,
557 )
558 } 425 }
559} 426}
560 427
561/// The ID of a type variable. 428impl<'a> fmt::Debug for InferenceTable<'a> {
562#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug)] 429 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
563pub(super) struct TypeVarId(pub(super) u32); 430 f.debug_struct("InferenceTable").field("num_vars", &self.type_variable_table.len()).finish()
564
565impl UnifyKey for TypeVarId {
566 type Value = TypeVarValue;
567
568 fn index(&self) -> u32 {
569 self.0
570 }
571
572 fn from_index(i: u32) -> Self {
573 TypeVarId(i)
574 } 431 }
575
576 fn tag() -> &'static str {
577 "TypeVarId"
578 }
579}
580
581fn from_inference_var(var: InferenceVar) -> TypeVarId {
582 TypeVarId(var.index())
583}
584
585fn to_inference_var(TypeVarId(index): TypeVarId) -> InferenceVar {
586 index.into()
587}
588
589/// The value of a type variable: either we already know the type, or we don't
590/// know it yet.
591#[derive(Clone, PartialEq, Eq, Debug)]
592pub(super) enum TypeVarValue {
593 Known(Ty),
594 Unknown,
595} 432}
596 433
597impl TypeVarValue { 434mod resolve {
598 fn known(&self) -> Option<&Ty> { 435 use super::InferenceTable;
599 match self { 436 use crate::{
600 TypeVarValue::Known(ty) => Some(ty), 437 ConcreteConst, Const, ConstData, ConstValue, DebruijnIndex, GenericArg, InferenceVar,
601 TypeVarValue::Unknown => None, 438 Interner, Ty, TyVariableKind, VariableKind,
439 };
440 use chalk_ir::{
441 cast::Cast,
442 fold::{Fold, Folder},
443 Fallible,
444 };
445 use hir_def::type_ref::ConstScalar;
446
447 pub(super) struct Resolver<'a, 'b, F> {
448 pub(super) table: &'a mut InferenceTable<'b>,
449 pub(super) var_stack: &'a mut Vec<InferenceVar>,
450 pub(super) fallback: F,
451 }
452 impl<'a, 'b, 'i, F> Folder<'i, Interner> for Resolver<'a, 'b, F>
453 where
454 F: Fn(InferenceVar, VariableKind, GenericArg, DebruijnIndex) -> GenericArg + 'i,
455 {
456 fn as_dyn(&mut self) -> &mut dyn Folder<'i, Interner> {
457 self
602 } 458 }
603 }
604}
605
606impl UnifyValue for TypeVarValue {
607 type Error = NoError;
608 459
609 fn unify_values(value1: &Self, value2: &Self) -> Result<Self, NoError> { 460 fn interner(&self) -> &'i Interner {
610 match (value1, value2) { 461 &Interner
611 // We should never equate two type variables, both of which have 462 }
612 // known types. Instead, we recursively equate those types.
613 (TypeVarValue::Known(t1), TypeVarValue::Known(t2)) => panic!(
614 "equating two type variables, both of which have known types: {:?} and {:?}",
615 t1, t2
616 ),
617 463
618 // If one side is known, prefer that one. 464 fn fold_inference_ty(
619 (TypeVarValue::Known(..), TypeVarValue::Unknown) => Ok(value1.clone()), 465 &mut self,
620 (TypeVarValue::Unknown, TypeVarValue::Known(..)) => Ok(value2.clone()), 466 var: InferenceVar,
467 kind: TyVariableKind,
468 outer_binder: DebruijnIndex,
469 ) -> Fallible<Ty> {
470 let var = self.table.var_unification_table.inference_var_root(var);
471 if self.var_stack.contains(&var) {
472 // recursive type
473 let default = self.table.fallback_value(var, kind).cast(&Interner);
474 return Ok((self.fallback)(var, VariableKind::Ty(kind), default, outer_binder)
475 .assert_ty_ref(&Interner)
476 .clone());
477 }
478 let result = if let Some(known_ty) = self.table.var_unification_table.probe_var(var) {
479 // known_ty may contain other variables that are known by now
480 self.var_stack.push(var);
481 let result =
482 known_ty.fold_with(self, outer_binder).expect("fold failed unexpectedly");
483 self.var_stack.pop();
484 result.assert_ty_ref(&Interner).clone()
485 } else {
486 let default = self.table.fallback_value(var, kind).cast(&Interner);
487 (self.fallback)(var, VariableKind::Ty(kind), default, outer_binder)
488 .assert_ty_ref(&Interner)
489 .clone()
490 };
491 Ok(result)
492 }
621 493
622 (TypeVarValue::Unknown, TypeVarValue::Unknown) => Ok(TypeVarValue::Unknown), 494 fn fold_inference_const(
495 &mut self,
496 ty: Ty,
497 var: InferenceVar,
498 outer_binder: DebruijnIndex,
499 ) -> Fallible<Const> {
500 let var = self.table.var_unification_table.inference_var_root(var);
501 let default = ConstData {
502 ty: ty.clone(),
503 value: ConstValue::Concrete(ConcreteConst { interned: ConstScalar::Unknown }),
504 }
505 .intern(&Interner)
506 .cast(&Interner);
507 if self.var_stack.contains(&var) {
508 // recursive
509 return Ok((self.fallback)(var, VariableKind::Const(ty), default, outer_binder)
510 .assert_const_ref(&Interner)
511 .clone());
512 }
513 let result = if let Some(known_ty) = self.table.var_unification_table.probe_var(var) {
514 // known_ty may contain other variables that are known by now
515 self.var_stack.push(var);
516 let result =
517 known_ty.fold_with(self, outer_binder).expect("fold failed unexpectedly");
518 self.var_stack.pop();
519 result.assert_const_ref(&Interner).clone()
520 } else {
521 (self.fallback)(var, VariableKind::Const(ty), default, outer_binder)
522 .assert_const_ref(&Interner)
523 .clone()
524 };
525 Ok(result)
623 } 526 }
624 } 527 }
625} 528}