diff options
Diffstat (limited to 'crates/hir_ty/src/infer/unify.rs')
-rw-r--r-- | crates/hir_ty/src/infer/unify.rs | 111 |
1 files changed, 64 insertions, 47 deletions
diff --git a/crates/hir_ty/src/infer/unify.rs b/crates/hir_ty/src/infer/unify.rs index 54fcfed10..ebc612ca9 100644 --- a/crates/hir_ty/src/infer/unify.rs +++ b/crates/hir_ty/src/infer/unify.rs | |||
@@ -7,8 +7,8 @@ use ena::unify::{InPlaceUnificationTable, NoError, UnifyKey, UnifyValue}; | |||
7 | 7 | ||
8 | use super::{InferenceContext, Obligation}; | 8 | use super::{InferenceContext, Obligation}; |
9 | use crate::{ | 9 | use crate::{ |
10 | BoundVar, Canonical, DebruijnIndex, GenericPredicate, InEnvironment, InferenceVar, Scalar, | 10 | BoundVar, Canonical, DebruijnIndex, GenericPredicate, InEnvironment, InferenceVar, Interner, |
11 | Substs, Ty, TypeWalk, | 11 | Scalar, Substs, Ty, TyKind, TypeWalk, |
12 | }; | 12 | }; |
13 | 13 | ||
14 | impl<'a> InferenceContext<'a> { | 14 | impl<'a> InferenceContext<'a> { |
@@ -49,8 +49,8 @@ impl<'a, 'b> Canonicalizer<'a, 'b> { | |||
49 | 49 | ||
50 | fn do_canonicalize<T: TypeWalk>(&mut self, t: T, binders: DebruijnIndex) -> T { | 50 | fn do_canonicalize<T: TypeWalk>(&mut self, t: T, binders: DebruijnIndex) -> T { |
51 | t.fold_binders( | 51 | t.fold_binders( |
52 | &mut |ty, binders| match ty { | 52 | &mut |ty, binders| match ty.interned(&Interner) { |
53 | Ty::InferenceVar(var, kind) => { | 53 | &TyKind::InferenceVar(var, kind) => { |
54 | let inner = var.to_inner(); | 54 | let inner = var.to_inner(); |
55 | if self.var_stack.contains(&inner) { | 55 | if self.var_stack.contains(&inner) { |
56 | // recursive type | 56 | // recursive type |
@@ -66,7 +66,7 @@ impl<'a, 'b> Canonicalizer<'a, 'b> { | |||
66 | } else { | 66 | } else { |
67 | let root = self.ctx.table.var_unification_table.find(inner); | 67 | let root = self.ctx.table.var_unification_table.find(inner); |
68 | let position = self.add(InferenceVar::from_inner(root), kind); | 68 | let position = self.add(InferenceVar::from_inner(root), kind); |
69 | Ty::BoundVar(BoundVar::new(binders, position)) | 69 | TyKind::BoundVar(BoundVar::new(binders, position)).intern(&Interner) |
70 | } | 70 | } |
71 | } | 71 | } |
72 | _ => ty, | 72 | _ => ty, |
@@ -108,10 +108,10 @@ impl<T> Canonicalized<T> { | |||
108 | pub(super) fn decanonicalize_ty(&self, mut ty: Ty) -> Ty { | 108 | pub(super) fn decanonicalize_ty(&self, mut ty: Ty) -> Ty { |
109 | ty.walk_mut_binders( | 109 | ty.walk_mut_binders( |
110 | &mut |ty, binders| { | 110 | &mut |ty, binders| { |
111 | if let &mut Ty::BoundVar(bound) = ty { | 111 | if let &mut TyKind::BoundVar(bound) = &mut ty.0 { |
112 | if bound.debruijn >= binders { | 112 | if bound.debruijn >= binders { |
113 | let (v, k) = self.free_vars[bound.index]; | 113 | let (v, k) = self.free_vars[bound.index]; |
114 | *ty = Ty::InferenceVar(v, k); | 114 | *ty = TyKind::InferenceVar(v, k).intern(&Interner); |
115 | } | 115 | } |
116 | } | 116 | } |
117 | }, | 117 | }, |
@@ -142,7 +142,7 @@ impl<T> Canonicalized<T> { | |||
142 | // eagerly replace projections in the type; we may be getting types | 142 | // eagerly replace projections in the type; we may be getting types |
143 | // e.g. from where clauses where this hasn't happened yet | 143 | // e.g. from where clauses where this hasn't happened yet |
144 | let ty = ctx.normalize_associated_types_in(ty.clone().subst_bound_vars(&new_vars)); | 144 | let ty = ctx.normalize_associated_types_in(ty.clone().subst_bound_vars(&new_vars)); |
145 | ctx.table.unify(&Ty::InferenceVar(v, k), &ty); | 145 | ctx.table.unify(&TyKind::InferenceVar(v, k).intern(&Interner), &ty); |
146 | } | 146 | } |
147 | } | 147 | } |
148 | } | 148 | } |
@@ -166,7 +166,10 @@ pub(crate) fn unify(tys: &Canonical<(Ty, Ty)>) -> Option<Substs> { | |||
166 | // (kind of hacky) | 166 | // (kind of hacky) |
167 | for (i, var) in vars.iter().enumerate() { | 167 | for (i, var) in vars.iter().enumerate() { |
168 | if &*table.resolve_ty_shallow(var) == var { | 168 | if &*table.resolve_ty_shallow(var) == var { |
169 | table.unify(var, &Ty::BoundVar(BoundVar::new(DebruijnIndex::INNERMOST, i))); | 169 | table.unify( |
170 | var, | ||
171 | &TyKind::BoundVar(BoundVar::new(DebruijnIndex::INNERMOST, i)).intern(&Interner), | ||
172 | ); | ||
170 | } | 173 | } |
171 | } | 174 | } |
172 | Some( | 175 | Some( |
@@ -196,11 +199,12 @@ impl TypeVariableTable { | |||
196 | 199 | ||
197 | fn fallback_value(&self, iv: InferenceVar, kind: TyVariableKind) -> Ty { | 200 | fn fallback_value(&self, iv: InferenceVar, kind: TyVariableKind) -> Ty { |
198 | match kind { | 201 | match kind { |
199 | _ if self.inner[iv.to_inner().0 as usize].diverging => Ty::Never, | 202 | _ if self.inner[iv.to_inner().0 as usize].diverging => TyKind::Never, |
200 | TyVariableKind::General => Ty::Unknown, | 203 | TyVariableKind::General => TyKind::Unknown, |
201 | TyVariableKind::Integer => Ty::Scalar(Scalar::Int(IntTy::I32)), | 204 | TyVariableKind::Integer => TyKind::Scalar(Scalar::Int(IntTy::I32)), |
202 | TyVariableKind::Float => Ty::Scalar(Scalar::Float(FloatTy::F64)), | 205 | TyVariableKind::Float => TyKind::Scalar(Scalar::Float(FloatTy::F64)), |
203 | } | 206 | } |
207 | .intern(&Interner) | ||
204 | } | 208 | } |
205 | } | 209 | } |
206 | 210 | ||
@@ -227,7 +231,7 @@ impl InferenceTable { | |||
227 | self.type_variable_table.push(TypeVariableData { diverging }); | 231 | self.type_variable_table.push(TypeVariableData { diverging }); |
228 | let key = self.var_unification_table.new_key(TypeVarValue::Unknown); | 232 | let key = self.var_unification_table.new_key(TypeVarValue::Unknown); |
229 | assert_eq!(key.0 as usize, self.type_variable_table.inner.len() - 1); | 233 | assert_eq!(key.0 as usize, self.type_variable_table.inner.len() - 1); |
230 | Ty::InferenceVar(InferenceVar::from_inner(key), kind) | 234 | TyKind::InferenceVar(InferenceVar::from_inner(key), kind).intern(&Interner) |
231 | } | 235 | } |
232 | 236 | ||
233 | pub(crate) fn new_type_var(&mut self) -> Ty { | 237 | pub(crate) fn new_type_var(&mut self) -> Ty { |
@@ -290,12 +294,12 @@ impl InferenceTable { | |||
290 | } | 294 | } |
291 | 295 | ||
292 | pub(super) fn unify_inner_trivial(&mut self, ty1: &Ty, ty2: &Ty, depth: usize) -> bool { | 296 | pub(super) fn unify_inner_trivial(&mut self, ty1: &Ty, ty2: &Ty, depth: usize) -> bool { |
293 | match (ty1, ty2) { | 297 | match (ty1.interned(&Interner), ty2.interned(&Interner)) { |
294 | (Ty::Unknown, _) | (_, Ty::Unknown) => true, | 298 | (TyKind::Unknown, _) | (_, TyKind::Unknown) => true, |
295 | 299 | ||
296 | (Ty::Placeholder(p1), Ty::Placeholder(p2)) if *p1 == *p2 => true, | 300 | (TyKind::Placeholder(p1), TyKind::Placeholder(p2)) if *p1 == *p2 => true, |
297 | 301 | ||
298 | (Ty::Dyn(dyn1), Ty::Dyn(dyn2)) if dyn1.len() == dyn2.len() => { | 302 | (TyKind::Dyn(dyn1), TyKind::Dyn(dyn2)) if dyn1.len() == dyn2.len() => { |
299 | for (pred1, pred2) in dyn1.iter().zip(dyn2.iter()) { | 303 | for (pred1, pred2) in dyn1.iter().zip(dyn2.iter()) { |
300 | if !self.unify_preds(pred1, pred2, depth + 1) { | 304 | if !self.unify_preds(pred1, pred2, depth + 1) { |
301 | return false; | 305 | return false; |
@@ -305,16 +309,16 @@ impl InferenceTable { | |||
305 | } | 309 | } |
306 | 310 | ||
307 | ( | 311 | ( |
308 | Ty::InferenceVar(tv1, TyVariableKind::General), | 312 | TyKind::InferenceVar(tv1, TyVariableKind::General), |
309 | Ty::InferenceVar(tv2, TyVariableKind::General), | 313 | TyKind::InferenceVar(tv2, TyVariableKind::General), |
310 | ) | 314 | ) |
311 | | ( | 315 | | ( |
312 | Ty::InferenceVar(tv1, TyVariableKind::Integer), | 316 | TyKind::InferenceVar(tv1, TyVariableKind::Integer), |
313 | Ty::InferenceVar(tv2, TyVariableKind::Integer), | 317 | TyKind::InferenceVar(tv2, TyVariableKind::Integer), |
314 | ) | 318 | ) |
315 | | ( | 319 | | ( |
316 | Ty::InferenceVar(tv1, TyVariableKind::Float), | 320 | TyKind::InferenceVar(tv1, TyVariableKind::Float), |
317 | Ty::InferenceVar(tv2, TyVariableKind::Float), | 321 | TyKind::InferenceVar(tv2, TyVariableKind::Float), |
318 | ) if self.type_variable_table.is_diverging(*tv1) | 322 | ) if self.type_variable_table.is_diverging(*tv1) |
319 | == self.type_variable_table.is_diverging(*tv2) => | 323 | == self.type_variable_table.is_diverging(*tv2) => |
320 | { | 324 | { |
@@ -326,24 +330,37 @@ impl InferenceTable { | |||
326 | // The order of MaybeNeverTypeVar matters here. | 330 | // The order of MaybeNeverTypeVar matters here. |
327 | // Unifying MaybeNeverTypeVar and TypeVar will let the latter become MaybeNeverTypeVar. | 331 | // Unifying MaybeNeverTypeVar and TypeVar will let the latter become MaybeNeverTypeVar. |
328 | // Unifying MaybeNeverTypeVar and other concrete type will let the former become it. | 332 | // Unifying MaybeNeverTypeVar and other concrete type will let the former become it. |
329 | (Ty::InferenceVar(tv, TyVariableKind::General), other) | 333 | (TyKind::InferenceVar(tv, TyVariableKind::General), other) |
330 | | (other, Ty::InferenceVar(tv, TyVariableKind::General)) | 334 | | (other, TyKind::InferenceVar(tv, TyVariableKind::General)) |
331 | | (Ty::InferenceVar(tv, TyVariableKind::Integer), other @ Ty::Scalar(Scalar::Int(_))) | ||
332 | | (other @ Ty::Scalar(Scalar::Int(_)), Ty::InferenceVar(tv, TyVariableKind::Integer)) | ||
333 | | ( | 335 | | ( |
334 | Ty::InferenceVar(tv, TyVariableKind::Integer), | 336 | TyKind::InferenceVar(tv, TyVariableKind::Integer), |
335 | other @ Ty::Scalar(Scalar::Uint(_)), | 337 | other @ TyKind::Scalar(Scalar::Int(_)), |
336 | ) | 338 | ) |
337 | | ( | 339 | | ( |
338 | other @ Ty::Scalar(Scalar::Uint(_)), | 340 | other @ TyKind::Scalar(Scalar::Int(_)), |
339 | Ty::InferenceVar(tv, TyVariableKind::Integer), | 341 | TyKind::InferenceVar(tv, TyVariableKind::Integer), |
340 | ) | 342 | ) |
341 | | (Ty::InferenceVar(tv, TyVariableKind::Float), other @ Ty::Scalar(Scalar::Float(_))) | 343 | | ( |
342 | | (other @ Ty::Scalar(Scalar::Float(_)), Ty::InferenceVar(tv, TyVariableKind::Float)) => | 344 | TyKind::InferenceVar(tv, TyVariableKind::Integer), |
343 | { | 345 | other @ TyKind::Scalar(Scalar::Uint(_)), |
346 | ) | ||
347 | | ( | ||
348 | other @ TyKind::Scalar(Scalar::Uint(_)), | ||
349 | TyKind::InferenceVar(tv, TyVariableKind::Integer), | ||
350 | ) | ||
351 | | ( | ||
352 | TyKind::InferenceVar(tv, TyVariableKind::Float), | ||
353 | other @ TyKind::Scalar(Scalar::Float(_)), | ||
354 | ) | ||
355 | | ( | ||
356 | other @ TyKind::Scalar(Scalar::Float(_)), | ||
357 | TyKind::InferenceVar(tv, TyVariableKind::Float), | ||
358 | ) => { | ||
344 | // the type var is unknown since we tried to resolve it | 359 | // the type var is unknown since we tried to resolve it |
345 | self.var_unification_table | 360 | self.var_unification_table.union_value( |
346 | .union_value(tv.to_inner(), TypeVarValue::Known(other.clone())); | 361 | tv.to_inner(), |
362 | TypeVarValue::Known(other.clone().intern(&Interner)), | ||
363 | ); | ||
347 | true | 364 | true |
348 | } | 365 | } |
349 | 366 | ||
@@ -364,11 +381,11 @@ impl InferenceTable { | |||
364 | self.unify_substs(&tr1.substs, &tr2.substs, depth + 1) | 381 | self.unify_substs(&tr1.substs, &tr2.substs, depth + 1) |
365 | } | 382 | } |
366 | (GenericPredicate::Projection(proj1), GenericPredicate::Projection(proj2)) | 383 | (GenericPredicate::Projection(proj1), GenericPredicate::Projection(proj2)) |
367 | if proj1.projection_ty.associated_ty == proj2.projection_ty.associated_ty => | 384 | if proj1.projection_ty.associated_ty_id == proj2.projection_ty.associated_ty_id => |
368 | { | 385 | { |
369 | self.unify_substs( | 386 | self.unify_substs( |
370 | &proj1.projection_ty.parameters, | 387 | &proj1.projection_ty.substitution, |
371 | &proj2.projection_ty.parameters, | 388 | &proj2.projection_ty.substitution, |
372 | depth + 1, | 389 | depth + 1, |
373 | ) && self.unify_inner(&proj1.ty, &proj2.ty, depth + 1) | 390 | ) && self.unify_inner(&proj1.ty, &proj2.ty, depth + 1) |
374 | } | 391 | } |
@@ -387,8 +404,8 @@ impl InferenceTable { | |||
387 | if i > 0 { | 404 | if i > 0 { |
388 | cov_mark::hit!(type_var_resolves_to_int_var); | 405 | cov_mark::hit!(type_var_resolves_to_int_var); |
389 | } | 406 | } |
390 | match &*ty { | 407 | match &ty.0 { |
391 | Ty::InferenceVar(tv, _) => { | 408 | TyKind::InferenceVar(tv, _) => { |
392 | let inner = tv.to_inner(); | 409 | let inner = tv.to_inner(); |
393 | match self.var_unification_table.inlined_probe_value(inner).known() { | 410 | match self.var_unification_table.inlined_probe_value(inner).known() { |
394 | Some(known_ty) => { | 411 | Some(known_ty) => { |
@@ -410,8 +427,8 @@ impl InferenceTable { | |||
410 | /// be resolved as far as possible, i.e. contain no type variables with | 427 | /// be resolved as far as possible, i.e. contain no type variables with |
411 | /// known type. | 428 | /// known type. |
412 | fn resolve_ty_as_possible_inner(&mut self, tv_stack: &mut Vec<TypeVarId>, ty: Ty) -> Ty { | 429 | fn resolve_ty_as_possible_inner(&mut self, tv_stack: &mut Vec<TypeVarId>, ty: Ty) -> Ty { |
413 | ty.fold(&mut |ty| match ty { | 430 | ty.fold(&mut |ty| match ty.interned(&Interner) { |
414 | Ty::InferenceVar(tv, kind) => { | 431 | &TyKind::InferenceVar(tv, kind) => { |
415 | let inner = tv.to_inner(); | 432 | let inner = tv.to_inner(); |
416 | if tv_stack.contains(&inner) { | 433 | if tv_stack.contains(&inner) { |
417 | cov_mark::hit!(type_var_cycles_resolve_as_possible); | 434 | cov_mark::hit!(type_var_cycles_resolve_as_possible); |
@@ -435,10 +452,10 @@ impl InferenceTable { | |||
435 | } | 452 | } |
436 | 453 | ||
437 | /// Resolves the type completely; type variables without known type are | 454 | /// Resolves the type completely; type variables without known type are |
438 | /// replaced by Ty::Unknown. | 455 | /// replaced by TyKind::Unknown. |
439 | fn resolve_ty_completely_inner(&mut self, tv_stack: &mut Vec<TypeVarId>, ty: Ty) -> Ty { | 456 | fn resolve_ty_completely_inner(&mut self, tv_stack: &mut Vec<TypeVarId>, ty: Ty) -> Ty { |
440 | ty.fold(&mut |ty| match ty { | 457 | ty.fold(&mut |ty| match ty.interned(&Interner) { |
441 | Ty::InferenceVar(tv, kind) => { | 458 | &TyKind::InferenceVar(tv, kind) => { |
442 | let inner = tv.to_inner(); | 459 | let inner = tv.to_inner(); |
443 | if tv_stack.contains(&inner) { | 460 | if tv_stack.contains(&inner) { |
444 | cov_mark::hit!(type_var_cycles_resolve_completely); | 461 | cov_mark::hit!(type_var_cycles_resolve_completely); |