Skip to content

Commit 2b3a37f

Browse files
committed
introduce BoundVar newtype, which doesn't have much purpose yet
1 parent 21437de commit 2b3a37f

File tree

11 files changed

+189
-84
lines changed

11 files changed

+189
-84
lines changed

chalk-integration/src/lowering.rs

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
use chalk_ir::cast::{Cast, Caster};
22
use chalk_ir::interner::ChalkIr;
3-
use chalk_ir::{self, AssocTypeId, DebruijnIndex, ImplId, StructId, TraitId};
3+
use chalk_ir::{self, AssocTypeId, BoundVar, DebruijnIndex, ImplId, StructId, TraitId};
44
use chalk_parse::ast::*;
55
use chalk_rust_ir as rust_ir;
66
use chalk_rust_ir::{Anonymize, AssociatedTyValueId, IntoWhereClauses, ToParameter};
@@ -19,7 +19,7 @@ type TraitKinds = BTreeMap<chalk_ir::TraitId<ChalkIr>, TypeKind>;
1919
type AssociatedTyLookups = BTreeMap<(chalk_ir::TraitId<ChalkIr>, Ident), AssociatedTyLookup>;
2020
type AssociatedTyValueIds =
2121
BTreeMap<(chalk_ir::ImplId<ChalkIr>, Ident), AssociatedTyValueId<ChalkIr>>;
22-
type ParameterMap = BTreeMap<chalk_ir::ParameterKind<Ident>, DebruijnIndex>;
22+
type ParameterMap = BTreeMap<chalk_ir::ParameterKind<Ident>, BoundVar>;
2323

2424
pub type LowerResult<T> = Result<T, RustIrError>;
2525

@@ -62,11 +62,11 @@ struct AssociatedTyLookup {
6262

6363
enum TypeLookup {
6464
Struct(chalk_ir::StructId<ChalkIr>),
65-
Parameter(DebruijnIndex),
65+
Parameter(BoundVar),
6666
}
6767

6868
enum LifetimeLookup {
69-
Parameter(DebruijnIndex),
69+
Parameter(BoundVar),
7070
}
7171

7272
const SELF: &str = "Self";
@@ -141,7 +141,7 @@ impl<'k> Env<'k> {
141141
let binders = binders
142142
.into_iter()
143143
.enumerate()
144-
.map(|(i, k)| (k, DebruijnIndex::from(i)));
144+
.map(|(i, k)| (k, BoundVar::new(DebruijnIndex::from(i))));
145145
let len = binders.len();
146146
let parameter_map: ParameterMap = self
147147
.parameter_map
@@ -421,7 +421,7 @@ trait LowerParameterMap {
421421
// probably just kind of messed up right now. That's ok.
422422
self.all_parameters()
423423
.into_iter()
424-
.zip((0..).map(DebruijnIndex::from_u32))
424+
.zip((0..).map(|i| BoundVar::new(DebruijnIndex::from_u32(i))))
425425
.collect()
426426
}
427427

@@ -1003,8 +1003,10 @@ impl LowerTy for Ty {
10031003
.flat_map(|qil| {
10041004
qil.into_where_clauses(
10051005
interner,
1006-
chalk_ir::TyData::BoundVar(DebruijnIndex::INNERMOST)
1007-
.intern(interner),
1006+
chalk_ir::TyData::BoundVar(BoundVar::new(
1007+
DebruijnIndex::INNERMOST,
1008+
))
1009+
.intern(interner),
10081010
)
10091011
})
10101012
.collect())

chalk-ir/src/debug.rs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -134,6 +134,13 @@ impl<I: Interner> Debug for TyData<I> {
134134
}
135135
}
136136

137+
impl Debug for BoundVar {
138+
fn fmt(&self, fmt: &mut Formatter) -> Result<(), Error> {
139+
let BoundVar { debruijn } = self;
140+
write!(fmt, "{:?}", debruijn)
141+
}
142+
}
143+
137144
impl Debug for DebruijnIndex {
138145
fn fmt(&self, fmt: &mut Formatter<'_>) -> Result<(), Error> {
139146
let DebruijnIndex { depth } = self;

chalk-ir/src/fold.rs

Lines changed: 25 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -122,22 +122,26 @@ where
122122
///
123123
/// This should return a type suitable for a context with
124124
/// `binders` in scope.
125-
fn fold_free_var_ty(&mut self, depth: usize, binders: usize) -> Fallible<Ty<TI>> {
125+
fn fold_free_var_ty(&mut self, bound_var: BoundVar, binders: usize) -> Fallible<Ty<TI>> {
126126
if self.forbid_free_vars() {
127-
panic!("unexpected free variable with depth `{:?}`", depth)
127+
panic!("unexpected free variable with depth `{:?}`", bound_var)
128128
} else {
129-
let debruijn = DebruijnIndex::from(depth).shifted_in(binders);
130-
Ok(TyData::<TI>::BoundVar(debruijn).intern(self.target_interner()))
129+
let bound_var = bound_var.shifted_in(binders);
130+
Ok(TyData::<TI>::BoundVar(bound_var).intern(self.target_interner()))
131131
}
132132
}
133133

134134
/// As `fold_free_var_ty`, but for lifetimes.
135-
fn fold_free_var_lifetime(&mut self, depth: usize, binders: usize) -> Fallible<Lifetime<TI>> {
135+
fn fold_free_var_lifetime(
136+
&mut self,
137+
bound_var: BoundVar,
138+
binders: usize,
139+
) -> Fallible<Lifetime<TI>> {
136140
if self.forbid_free_vars() {
137-
panic!("unexpected free variable with depth `{:?}`", depth)
141+
panic!("unexpected free variable with depth `{:?}`", bound_var)
138142
} else {
139-
let debruijn = DebruijnIndex::from(depth).shifted_in(binders);
140-
Ok(LifetimeData::<TI>::BoundVar(debruijn).intern(self.target_interner()))
143+
let bound_var = bound_var.shifted_in(binders);
144+
Ok(LifetimeData::<TI>::BoundVar(bound_var).intern(self.target_interner()))
141145
}
142146
}
143147

@@ -305,19 +309,20 @@ where
305309
I: 'i,
306310
TI: 'i,
307311
{
308-
match self.data(folder.interner()) {
309-
TyData::BoundVar(debruijn) => {
310-
let debruijn = *debruijn;
312+
let interner = folder.interner();
313+
match self.data(interner) {
314+
TyData::BoundVar(bound_var) => {
315+
let BoundVar { debruijn } = *bound_var;
311316
if debruijn.within(binders) {
312317
// If `debruijn` refers to one of the binders that
313318
// we folded over, then just return a bound
314319
// variable.
315-
Ok(TyData::<TI>::BoundVar(debruijn).intern(folder.target_interner()))
320+
Ok(TyData::<TI>::BoundVar(BoundVar::new(debruijn))
321+
.intern(folder.target_interner()))
316322
} else {
317323
// Otherwise, this variable was bound outside the
318324
// folded term, so invoke `fold_free_var_ty`.
319-
let index = debruijn.shifted_out(binders).as_usize();
320-
folder.fold_free_var_ty(index, binders)
325+
folder.fold_free_var_ty(bound_var.shifted_out(binders), binders)
321326
}
322327
}
323328
TyData::Dyn(clauses) => {
@@ -377,18 +382,19 @@ where
377382
let interner = folder.interner();
378383
let target_interner = folder.target_interner();
379384
match self.data(interner) {
380-
LifetimeData::BoundVar(debruijn) => {
381-
let debruijn = *debruijn;
385+
LifetimeData::BoundVar(bound_var) => {
386+
let BoundVar { debruijn } = *bound_var;
382387
if debruijn.within(binders) {
383388
// If `debruijn` refers to one of the binders that
384389
// we folded over, then just return a bound
385390
// variable.
386-
Ok(LifetimeData::<TI>::BoundVar(debruijn).intern(target_interner))
391+
Ok(LifetimeData::<TI>::BoundVar(BoundVar::new(debruijn))
392+
.intern(target_interner))
387393
} else {
388394
// Otherwise, this variable was bound outside the
389395
// folded term, so invoke `fold_free_var_lifetime`.
390-
let index = debruijn.shifted_out(binders).as_usize();
391-
folder.fold_free_var_lifetime(index, binders)
396+
let bound_var = BoundVar::new(debruijn.shifted_out(binders));
397+
folder.fold_free_var_lifetime(bound_var, binders)
392398
}
393399
}
394400
LifetimeData::InferenceVar(var) => folder.fold_inference_lifetime(*var, binders),

chalk-ir/src/fold/shift.rs

Lines changed: 21 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,6 @@ impl<T: Fold<I, I> + Eq, I: Interner> Shift<I> for T {
8383
}
8484

8585
/// A folder that adjusts debruijn indices by a certain amount.
86-
///
8786
struct Shifter<'i, I> {
8887
adjustment: usize,
8988
interner: &'i I,
@@ -93,8 +92,8 @@ impl<I> Shifter<'_, I> {
9392
/// Given a free variable at `depth`, shifts that depth to `depth
9493
/// + self.adjustment`, and then wraps *that* within the internal
9594
/// set `binders`.
96-
fn adjust(&self, depth: usize, binders: usize) -> DebruijnIndex {
97-
DebruijnIndex::from(depth + self.adjustment + binders)
95+
fn adjust(&self, bound_var: BoundVar, binders: usize) -> BoundVar {
96+
bound_var.shifted_in(self.adjustment + binders)
9897
}
9998
}
10099

@@ -103,12 +102,16 @@ impl<'i, I: Interner> Folder<'i, I> for Shifter<'i, I> {
103102
self
104103
}
105104

106-
fn fold_free_var_ty(&mut self, depth: usize, binders: usize) -> Fallible<Ty<I>> {
107-
Ok(TyData::<I>::BoundVar(self.adjust(depth, binders)).intern(self.interner()))
105+
fn fold_free_var_ty(&mut self, bound_var: BoundVar, binders: usize) -> Fallible<Ty<I>> {
106+
Ok(TyData::<I>::BoundVar(self.adjust(bound_var, binders)).intern(self.interner()))
108107
}
109108

110-
fn fold_free_var_lifetime(&mut self, depth: usize, binders: usize) -> Fallible<Lifetime<I>> {
111-
Ok(LifetimeData::<I>::BoundVar(self.adjust(depth, binders)).intern(self.interner()))
109+
fn fold_free_var_lifetime(
110+
&mut self,
111+
bound_var: BoundVar,
112+
binders: usize,
113+
) -> Fallible<Lifetime<I>> {
114+
Ok(LifetimeData::<I>::BoundVar(self.adjust(bound_var, binders)).intern(self.interner()))
112115
}
113116

114117
fn interner(&self) -> &'i I {
@@ -139,9 +142,9 @@ impl<I> DownShifter<'_, I> {
139142
/// those internal binders (i.e., `depth < self.adjustment`) the
140143
/// this will fail with `Err`. Otherwise, returns the variable at
141144
/// this new depth (but adjusted to appear within `binders`).
142-
fn adjust(&self, depth: usize, binders: usize) -> Fallible<DebruijnIndex> {
143-
match depth.checked_sub(self.adjustment) {
144-
Some(new_depth) => Ok(DebruijnIndex::from(new_depth + binders)),
145+
fn adjust(&self, bound_var: BoundVar, binders: usize) -> Fallible<BoundVar> {
146+
match bound_var.debruijn.checked_shifted_out(self.adjustment) {
147+
Some(new_depth) => Ok(BoundVar::new(new_depth.shifted_in(binders))),
145148
None => Err(NoSolution),
146149
}
147150
}
@@ -152,12 +155,16 @@ impl<'i, I: Interner> Folder<'i, I> for DownShifter<'i, I> {
152155
self
153156
}
154157

155-
fn fold_free_var_ty(&mut self, depth: usize, binders: usize) -> Fallible<Ty<I>> {
156-
Ok(TyData::<I>::BoundVar(self.adjust(depth, binders)?).intern(self.interner()))
158+
fn fold_free_var_ty(&mut self, bound_var: BoundVar, binders: usize) -> Fallible<Ty<I>> {
159+
Ok(TyData::<I>::BoundVar(self.adjust(bound_var, binders)?).intern(self.interner()))
157160
}
158161

159-
fn fold_free_var_lifetime(&mut self, depth: usize, binders: usize) -> Fallible<Lifetime<I>> {
160-
Ok(LifetimeData::<I>::BoundVar(self.adjust(depth, binders)?).intern(self.interner()))
162+
fn fold_free_var_lifetime(
163+
&mut self,
164+
bound_var: BoundVar,
165+
binders: usize,
166+
) -> Fallible<Lifetime<I>> {
167+
Ok(LifetimeData::<I>::BoundVar(self.adjust(bound_var, binders)?).intern(self.interner()))
161168
}
162169

163170
fn interner(&self) -> &'i I {

chalk-ir/src/fold/subst.rs

Lines changed: 16 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -28,26 +28,32 @@ impl<'i, I: Interner> Folder<'i, I> for Subst<'_, 'i, I> {
2828
self
2929
}
3030

31-
fn fold_free_var_ty(&mut self, depth: usize, binders: usize) -> Fallible<Ty<I>> {
31+
fn fold_free_var_ty(&mut self, bound_var: BoundVar, binders: usize) -> Fallible<Ty<I>> {
3232
let interner = self.interner();
33-
if depth >= self.parameters.len() {
34-
let debruijn = DebruijnIndex::from(depth - self.parameters.len() + binders);
35-
Ok(TyData::<I>::BoundVar(debruijn).intern(interner))
33+
let index = bound_var.index();
34+
if index >= self.parameters.len() {
35+
let debruijn = DebruijnIndex::from(index - self.parameters.len()).shifted_in(binders);
36+
Ok(TyData::<I>::BoundVar(BoundVar::new(debruijn)).intern(interner))
3637
} else {
37-
match self.parameters[depth].data(interner) {
38+
match self.parameters[index].data(interner) {
3839
ParameterKind::Ty(t) => Ok(t.shifted_in(interner, binders)),
3940
_ => panic!("mismatched kinds in substitution"),
4041
}
4142
}
4243
}
4344

44-
fn fold_free_var_lifetime(&mut self, depth: usize, binders: usize) -> Fallible<Lifetime<I>> {
45+
fn fold_free_var_lifetime(
46+
&mut self,
47+
bound_var: BoundVar,
48+
binders: usize,
49+
) -> Fallible<Lifetime<I>> {
4550
let interner = self.interner();
46-
if depth >= self.parameters.len() {
47-
let debruijn = DebruijnIndex::from(depth - self.parameters.len() + binders);
48-
Ok(LifetimeData::<I>::BoundVar(debruijn).intern(interner))
51+
let index = bound_var.index();
52+
if index >= self.parameters.len() {
53+
let debruijn = DebruijnIndex::from(index - self.parameters.len()).shifted_in(binders);
54+
Ok(LifetimeData::<I>::BoundVar(BoundVar::new(debruijn)).intern(interner))
4955
} else {
50-
match self.parameters[depth].data(interner) {
56+
match self.parameters[index].data(interner) {
5157
ParameterKind::Lifetime(l) => Ok(l.shifted_in(interner, binders)),
5258
_ => panic!("mismatched kinds in substitution"),
5359
}

0 commit comments

Comments
 (0)