From 952714685a7c0e0a1c9970839ce307806adaa176 Mon Sep 17 00:00:00 2001 From: Florian Diebold Date: Sun, 5 Apr 2020 18:24:18 +0200 Subject: Upgrade Chalk again The big change here is counting binders, not variables (https://github.com/rust-lang/chalk/pull/360). We have to adapt to the same scheme for our `Ty::Bound`. It's mostly fine though, even makes some things more clear. --- crates/ra_hir_ty/src/infer/unify.rs | 28 +++++++++++++++++----------- 1 file changed, 17 insertions(+), 11 deletions(-) (limited to 'crates/ra_hir_ty/src/infer') diff --git a/crates/ra_hir_ty/src/infer/unify.rs b/crates/ra_hir_ty/src/infer/unify.rs index 0bf8fbd63..ac25f8a80 100644 --- a/crates/ra_hir_ty/src/infer/unify.rs +++ b/crates/ra_hir_ty/src/infer/unify.rs @@ -7,7 +7,9 @@ use ena::unify::{InPlaceUnificationTable, NoError, UnifyKey, UnifyValue}; use test_utils::tested_by; use super::{InferenceContext, Obligation}; -use crate::{Canonical, InEnvironment, InferTy, Substs, Ty, TypeCtor, TypeWalk}; +use crate::{ + BoundVar, Canonical, DebruijnIndex, InEnvironment, InferTy, Substs, Ty, TypeCtor, TypeWalk, +}; impl<'a> InferenceContext<'a> { pub(super) fn canonicalizer<'b>(&'b mut self) -> Canonicalizer<'a, 'b> @@ -47,7 +49,7 @@ where }) } - fn do_canonicalize(&mut self, t: T, binders: usize) -> T { + fn do_canonicalize(&mut self, t: T, binders: DebruijnIndex) -> T { t.fold_binders( &mut |ty, binders| match ty { Ty::Infer(tv) => { @@ -72,7 +74,7 @@ where InferTy::MaybeNeverTypeVar(_) => InferTy::MaybeNeverTypeVar(root), }; let position = self.add(free_var); - Ty::Bound((position + binders) as u32) + Ty::Bound(BoundVar::new(binders, position)) } } _ => ty, @@ -89,7 +91,7 @@ where } pub(crate) fn canonicalize_ty(mut self, ty: Ty) -> Canonicalized { - let result = self.do_canonicalize(ty, 0); + let result = self.do_canonicalize(ty, DebruijnIndex::INNERMOST); self.into_canonicalized(result) } @@ -98,8 +100,12 @@ where obligation: InEnvironment, ) -> Canonicalized> { let result = match obligation.value { - Obligation::Trait(tr) => Obligation::Trait(self.do_canonicalize(tr, 0)), - Obligation::Projection(pr) => Obligation::Projection(self.do_canonicalize(pr, 0)), + Obligation::Trait(tr) => { + Obligation::Trait(self.do_canonicalize(tr, DebruijnIndex::INNERMOST)) + } + Obligation::Projection(pr) => { + Obligation::Projection(self.do_canonicalize(pr, DebruijnIndex::INNERMOST)) + } }; self.into_canonicalized(InEnvironment { value: result, @@ -112,13 +118,13 @@ impl Canonicalized { pub fn decanonicalize_ty(&self, mut ty: Ty) -> Ty { ty.walk_mut_binders( &mut |ty, binders| { - if let &mut Ty::Bound(idx) = ty { - if idx as usize >= binders && (idx as usize - binders) < self.free_vars.len() { - *ty = Ty::Infer(self.free_vars[idx as usize - binders]); + if let &mut Ty::Bound(bound) = ty { + if bound.debruijn >= binders { + *ty = Ty::Infer(self.free_vars[bound.index]); } } }, - 0, + DebruijnIndex::INNERMOST, ); ty } @@ -150,7 +156,7 @@ pub fn unify(ty1: &Canonical, ty2: &Canonical) -> Option { // (kind of hacky) for (i, var) in vars.iter().enumerate() { if &*table.resolve_ty_shallow(var) == var { - table.unify(var, &Ty::Bound(i as u32)); + table.unify(var, &Ty::Bound(BoundVar::new(DebruijnIndex::INNERMOST, i))); } } Some( -- cgit v1.2.3