diff options
Diffstat (limited to 'crates/ra_hir_ty/src/infer')
-rw-r--r-- | crates/ra_hir_ty/src/infer/unify.rs | 28 |
1 files changed, 17 insertions, 11 deletions
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}; | |||
7 | use test_utils::tested_by; | 7 | use test_utils::tested_by; |
8 | 8 | ||
9 | use super::{InferenceContext, Obligation}; | 9 | use super::{InferenceContext, Obligation}; |
10 | use crate::{Canonical, InEnvironment, InferTy, Substs, Ty, TypeCtor, TypeWalk}; | 10 | use crate::{ |
11 | BoundVar, Canonical, DebruijnIndex, InEnvironment, InferTy, Substs, Ty, TypeCtor, TypeWalk, | ||
12 | }; | ||
11 | 13 | ||
12 | impl<'a> InferenceContext<'a> { | 14 | impl<'a> InferenceContext<'a> { |
13 | pub(super) fn canonicalizer<'b>(&'b mut self) -> Canonicalizer<'a, 'b> | 15 | pub(super) fn canonicalizer<'b>(&'b mut self) -> Canonicalizer<'a, 'b> |
@@ -47,7 +49,7 @@ where | |||
47 | }) | 49 | }) |
48 | } | 50 | } |
49 | 51 | ||
50 | fn do_canonicalize<T: TypeWalk>(&mut self, t: T, binders: usize) -> T { | 52 | fn do_canonicalize<T: TypeWalk>(&mut self, t: T, binders: DebruijnIndex) -> T { |
51 | t.fold_binders( | 53 | t.fold_binders( |
52 | &mut |ty, binders| match ty { | 54 | &mut |ty, binders| match ty { |
53 | Ty::Infer(tv) => { | 55 | Ty::Infer(tv) => { |
@@ -72,7 +74,7 @@ where | |||
72 | InferTy::MaybeNeverTypeVar(_) => InferTy::MaybeNeverTypeVar(root), | 74 | InferTy::MaybeNeverTypeVar(_) => InferTy::MaybeNeverTypeVar(root), |
73 | }; | 75 | }; |
74 | let position = self.add(free_var); | 76 | let position = self.add(free_var); |
75 | Ty::Bound((position + binders) as u32) | 77 | Ty::Bound(BoundVar::new(binders, position)) |
76 | } | 78 | } |
77 | } | 79 | } |
78 | _ => ty, | 80 | _ => ty, |
@@ -89,7 +91,7 @@ where | |||
89 | } | 91 | } |
90 | 92 | ||
91 | pub(crate) fn canonicalize_ty(mut self, ty: Ty) -> Canonicalized<Ty> { | 93 | pub(crate) fn canonicalize_ty(mut self, ty: Ty) -> Canonicalized<Ty> { |
92 | let result = self.do_canonicalize(ty, 0); | 94 | let result = self.do_canonicalize(ty, DebruijnIndex::INNERMOST); |
93 | self.into_canonicalized(result) | 95 | self.into_canonicalized(result) |
94 | } | 96 | } |
95 | 97 | ||
@@ -98,8 +100,12 @@ where | |||
98 | obligation: InEnvironment<Obligation>, | 100 | obligation: InEnvironment<Obligation>, |
99 | ) -> Canonicalized<InEnvironment<Obligation>> { | 101 | ) -> Canonicalized<InEnvironment<Obligation>> { |
100 | let result = match obligation.value { | 102 | let result = match obligation.value { |
101 | Obligation::Trait(tr) => Obligation::Trait(self.do_canonicalize(tr, 0)), | 103 | Obligation::Trait(tr) => { |
102 | Obligation::Projection(pr) => Obligation::Projection(self.do_canonicalize(pr, 0)), | 104 | Obligation::Trait(self.do_canonicalize(tr, DebruijnIndex::INNERMOST)) |
105 | } | ||
106 | Obligation::Projection(pr) => { | ||
107 | Obligation::Projection(self.do_canonicalize(pr, DebruijnIndex::INNERMOST)) | ||
108 | } | ||
103 | }; | 109 | }; |
104 | self.into_canonicalized(InEnvironment { | 110 | self.into_canonicalized(InEnvironment { |
105 | value: result, | 111 | value: result, |
@@ -112,13 +118,13 @@ impl<T> Canonicalized<T> { | |||
112 | pub fn decanonicalize_ty(&self, mut ty: Ty) -> Ty { | 118 | pub fn decanonicalize_ty(&self, mut ty: Ty) -> Ty { |
113 | ty.walk_mut_binders( | 119 | ty.walk_mut_binders( |
114 | &mut |ty, binders| { | 120 | &mut |ty, binders| { |
115 | if let &mut Ty::Bound(idx) = ty { | 121 | if let &mut Ty::Bound(bound) = ty { |
116 | if idx as usize >= binders && (idx as usize - binders) < self.free_vars.len() { | 122 | if bound.debruijn >= binders { |
117 | *ty = Ty::Infer(self.free_vars[idx as usize - binders]); | 123 | *ty = Ty::Infer(self.free_vars[bound.index]); |
118 | } | 124 | } |
119 | } | 125 | } |
120 | }, | 126 | }, |
121 | 0, | 127 | DebruijnIndex::INNERMOST, |
122 | ); | 128 | ); |
123 | ty | 129 | ty |
124 | } | 130 | } |
@@ -150,7 +156,7 @@ pub fn unify(ty1: &Canonical<Ty>, ty2: &Canonical<Ty>) -> Option<Substs> { | |||
150 | // (kind of hacky) | 156 | // (kind of hacky) |
151 | for (i, var) in vars.iter().enumerate() { | 157 | for (i, var) in vars.iter().enumerate() { |
152 | if &*table.resolve_ty_shallow(var) == var { | 158 | if &*table.resolve_ty_shallow(var) == var { |
153 | table.unify(var, &Ty::Bound(i as u32)); | 159 | table.unify(var, &Ty::Bound(BoundVar::new(DebruijnIndex::INNERMOST, i))); |
154 | } | 160 | } |
155 | } | 161 | } |
156 | Some( | 162 | Some( |