Skip to content

Commit 98329f3

Browse files
committed
distinguish shifting one level from N levels
The new convention is: * `shift_in` and `shifted_in` assume one level * `shifted_in_by(N)` to shift by N levels `shift_out` is analogous but it also always returns `Option` instead of having an assert.
1 parent a234501 commit 98329f3

File tree

9 files changed

+69
-50
lines changed

9 files changed

+69
-50
lines changed

chalk-integration/src/lowering.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -146,7 +146,7 @@ impl<'k> Env<'k> {
146146
let parameter_map: ParameterMap = self
147147
.parameter_map
148148
.iter()
149-
.map(|(&k, &v)| (k, v.shifted_in(1)))
149+
.map(|(&k, &v)| (k, v.shifted_in()))
150150
.chain(binders)
151151
.collect();
152152
if parameter_map.len() != self.parameter_map.len() + len {

chalk-ir/src/fold.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -129,7 +129,7 @@ where
129129
bound_var, binders
130130
)
131131
} else {
132-
let bound_var = bound_var.shifted_in(binders);
132+
let bound_var = bound_var.shifted_in_by(binders);
133133
Ok(TyData::<TI>::BoundVar(bound_var).intern(self.target_interner()))
134134
}
135135
}
@@ -146,7 +146,7 @@ where
146146
bound_var, binders
147147
)
148148
} else {
149-
let bound_var = bound_var.shifted_in(binders);
149+
let bound_var = bound_var.shifted_in_by(binders);
150150
Ok(LifetimeData::<TI>::BoundVar(bound_var).intern(self.target_interner()))
151151
}
152152
}
@@ -318,7 +318,7 @@ where
318318
let interner = folder.interner();
319319
match self.data(interner) {
320320
TyData::BoundVar(bound_var) => {
321-
if let Some(bound_var1) = bound_var.checked_shifted_out(binders) {
321+
if let Some(bound_var1) = bound_var.shifted_out_by(binders) {
322322
// This variable was bound outside of the binders
323323
// that we have traversed during folding;
324324
// therefore, it is free. Let the folder have a
@@ -388,7 +388,7 @@ where
388388
let interner = folder.interner();
389389
match self.data(interner) {
390390
LifetimeData::BoundVar(bound_var) => {
391-
if let Some(bound_var1) = bound_var.checked_shifted_out(binders) {
391+
if let Some(bound_var1) = bound_var.shifted_out_by(binders) {
392392
// This variable was bound outside of the binders
393393
// that we have traversed during folding;
394394
// therefore, it is free. Let the folder have a

chalk-ir/src/fold/shift.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -93,7 +93,7 @@ impl<I> Shifter<'_, I> {
9393
/// + self.adjustment`, and then wraps *that* within the internal
9494
/// set `binders`.
9595
fn adjust(&self, bound_var: BoundVar, binders: usize) -> BoundVar {
96-
bound_var.shifted_in(self.adjustment + binders)
96+
bound_var.shifted_in_by(self.adjustment + binders)
9797
}
9898
}
9999

@@ -143,8 +143,8 @@ impl<I> DownShifter<'_, I> {
143143
/// this will fail with `Err`. Otherwise, returns the variable at
144144
/// this new depth (but adjusted to appear within `binders`).
145145
fn adjust(&self, bound_var: BoundVar, binders: usize) -> Fallible<BoundVar> {
146-
match bound_var.checked_shifted_out(self.adjustment) {
147-
Some(bound_var1) => Ok(bound_var1.shifted_in(binders)),
146+
match bound_var.shifted_out_by(self.adjustment) {
147+
Some(bound_var1) => Ok(bound_var1.shifted_in_by(binders)),
148148
None => Err(NoSolution),
149149
}
150150
}

chalk-ir/src/fold/subst.rs

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -55,8 +55,9 @@ impl<'i, I: Interner> Folder<'i, I> for Subst<'_, 'i, I> {
5555
}
5656
} else {
5757
Ok(bound_var
58-
.shifted_out(1)
59-
.shifted_in(binders)
58+
.shifted_out()
59+
.expect("cannot fail because this is not the innermost")
60+
.shifted_in_by(binders)
6061
.to_ty(self.interner()))
6162
}
6263
}
@@ -75,8 +76,9 @@ impl<'i, I: Interner> Folder<'i, I> for Subst<'_, 'i, I> {
7576
}
7677
} else {
7778
Ok(bound_var
78-
.shifted_out(1)
79-
.shifted_in(binders)
79+
.shifted_out()
80+
.unwrap()
81+
.shifted_in_by(binders)
8082
.to_lifetime(self.interner()))
8183
}
8284
}

chalk-ir/src/lib.rs

Lines changed: 46 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -315,21 +315,30 @@ impl BoundVar {
315315

316316
/// Adjusts the debruijn index (see [`DebruijnIndex::shifted_in`]).
317317
#[must_use]
318-
pub fn shifted_in(self, amount: usize) -> Self {
319-
BoundVar::new(self.debruijn.shifted_in(amount), self.index)
318+
pub fn shifted_in(self) -> Self {
319+
BoundVar::new(self.debruijn.shifted_in(), self.index)
320320
}
321321

322-
/// Adjusts the debruijn index (see [`DebruijnIndex::shifted_out`]).
322+
/// Adjusts the debruijn index (see [`DebruijnIndex::shifted_in`]).
323323
#[must_use]
324-
pub fn shifted_out(self, amount: usize) -> Self {
325-
BoundVar::new(self.debruijn.shifted_out(amount), self.index)
324+
pub fn shifted_in_by(self, amount: usize) -> Self {
325+
BoundVar::new(self.debruijn.shifted_in_by(amount), self.index)
326326
}
327327

328-
/// Shift out this variable by `amount` binders, returning `None`
329-
/// if not enclosed in that many levels of binders.
330-
pub fn checked_shifted_out(self, amount: usize) -> Option<Self> {
331-
let debruijn = self.debruijn.checked_shifted_out(amount)?;
332-
Some(BoundVar::new(debruijn, self.index))
328+
/// Adjusts the debruijn index (see [`DebruijnIndex::shifted_in`]).
329+
#[must_use]
330+
pub fn shifted_out(self) -> Option<Self> {
331+
self.debruijn
332+
.shifted_out()
333+
.map(|db| BoundVar::new(db, self.index))
334+
}
335+
336+
/// Adjusts the debruijn index (see [`DebruijnIndex::shifted_in`]).
337+
#[must_use]
338+
pub fn shifted_out_by(self, amount: usize) -> Option<Self> {
339+
self.debruijn
340+
.shifted_out_by(amount)
341+
.map(|db| BoundVar::new(db, self.index))
333342
}
334343

335344
/// Return the index of the bound variable, but only if it is bound
@@ -435,6 +444,19 @@ impl DebruijnIndex {
435444
self < binder
436445
}
437446

447+
/// Returns the resulting index when this value is moved into
448+
/// through one binder.
449+
#[must_use]
450+
pub fn shifted_in(self) -> DebruijnIndex {
451+
self.shifted_in_by(1)
452+
}
453+
454+
/// Update this index in place by shifting it "in" through
455+
/// `amount` number of binders.
456+
pub fn shift_in(&mut self) {
457+
*self = self.shifted_in();
458+
}
459+
438460
/// Returns the resulting index when this value is moved into
439461
/// `amount` number of new binders. So, e.g., if you had
440462
///
@@ -446,38 +468,33 @@ impl DebruijnIndex {
446468
///
447469
/// you would need to shift the index for `'a` into a new binder.
448470
#[must_use]
449-
pub fn shifted_in(self, amount: usize) -> DebruijnIndex {
471+
pub fn shifted_in_by(self, amount: usize) -> DebruijnIndex {
450472
DebruijnIndex::from(self.as_usize() + amount)
451473
}
452474

453-
/// Update this index in place by shifting it "in" through
454-
/// `amount` number of binders.
455-
pub fn shift_in(&mut self, amount: usize) {
456-
*self = self.shifted_in(amount);
457-
}
458-
459475
/// Returns the resulting index when this value is moved out from
460476
/// `amount` number of new binders.
461477
#[must_use]
462-
pub fn shifted_out(self, amount: usize) -> DebruijnIndex {
463-
assert!(self.as_usize() >= amount);
464-
DebruijnIndex::from(self.as_usize() - amount)
478+
pub fn shifted_out(self) -> Option<DebruijnIndex> {
479+
self.shifted_out_by(1)
465480
}
466481

482+
/// Update in place by shifting out from `amount` binders.
483+
pub fn shift_out(&mut self) {
484+
*self = self.shifted_out().unwrap();
485+
}
486+
487+
/// Returns the resulting index when this value is moved out from
488+
/// `amount` number of new binders.
467489
#[must_use]
468-
pub fn checked_shifted_out(self, amount: usize) -> Option<DebruijnIndex> {
490+
pub fn shifted_out_by(self, amount: usize) -> Option<DebruijnIndex> {
469491
if self.within(amount) {
470492
None
471493
} else {
472-
Some(self.shifted_out(amount))
494+
Some(DebruijnIndex::from(self.as_usize() - amount))
473495
}
474496
}
475497

476-
/// Update in place by shifting out from `amount` binders.
477-
pub fn shift_out(&mut self, amount: usize) {
478-
*self = self.shifted_out(amount);
479-
}
480-
481498
/// Adjusts any De Bruijn indices so as to make `to_binder` the
482499
/// innermost binder. That is, if we have something bound at `to_binder`,
483500
/// it will now be bound at INNERMOST. This is an appropriate thing to do
@@ -498,8 +515,8 @@ impl DebruijnIndex {
498515
/// If we invoke `shift_out_to_binder` and the region is in fact
499516
/// bound by one of the binders we are shifting out of, that is an
500517
/// error (and should fail an assertion failure).
501-
pub fn shifted_out_to_binder(self, to_binder: DebruijnIndex) -> Self {
502-
self.shifted_out(to_binder.as_usize() - Self::INNERMOST.as_usize())
518+
pub fn shifted_out_to_binder(self, to_binder: DebruijnIndex) -> Option<Self> {
519+
self.shifted_out_by(to_binder.as_usize() - Self::INNERMOST.as_usize())
503520
}
504521
}
505522

chalk-ir/src/macros.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ macro_rules! ty {
3535
};
3636

3737
(bound $d:tt $b:tt) => {
38-
$crate::TyData::BoundVar($crate::BoundVar::new($crate::DebruijnIndex::INNERMOST.shifted_in($d), $b)).intern(&chalk_ir::interner::ChalkIr)
38+
$crate::TyData::BoundVar($crate::BoundVar::new($crate::DebruijnIndex::INNERMOST.shifted_in_by($d), $b)).intern(&chalk_ir::interner::ChalkIr)
3939
};
4040

4141
(bound $b:expr) => {
@@ -75,7 +75,7 @@ macro_rules! lifetime {
7575
};
7676

7777
(bound $d:tt $b:tt) => {
78-
$crate::LifetimeData::BoundVar($crate::BoundVar::new($crate::DebruijnIndex::INNERMOST.shifted_in($d), $b)).intern(&chalk_ir::interner::ChalkIr)
78+
$crate::LifetimeData::BoundVar($crate::BoundVar::new($crate::DebruijnIndex::INNERMOST.shifted_in_by($d), $b)).intern(&chalk_ir::interner::ChalkIr)
7979
};
8080

8181
(bound $b:expr) => {

chalk-solve/src/infer/canonicalize.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -145,7 +145,7 @@ where
145145
let free_var = ParameterKind::Ty(self.table.unify.find(var));
146146
let bound_var = BoundVar::new(DebruijnIndex::INNERMOST, self.add(free_var));
147147
debug!("not yet unified: position={:?}", bound_var);
148-
Ok(TyData::BoundVar(bound_var.shifted_in(binders)).intern(interner))
148+
Ok(TyData::BoundVar(bound_var.shifted_in_by(binders)).intern(interner))
149149
}
150150
}
151151
}
@@ -171,7 +171,7 @@ where
171171
let free_var = ParameterKind::Lifetime(self.table.unify.find(var));
172172
let bound_var = BoundVar::new(DebruijnIndex::INNERMOST, self.add(free_var));
173173
debug!("not yet unified: position={:?}", bound_var);
174-
Ok(LifetimeData::BoundVar(bound_var.shifted_in(binders)).intern(interner))
174+
Ok(LifetimeData::BoundVar(bound_var.shifted_in_by(binders)).intern(interner))
175175
}
176176
}
177177
}

chalk-solve/src/solve/slg/resolvent.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -417,9 +417,9 @@ impl<'i, I: Interner> Zipper<'i, I> for AnswerSubstitutor<'i, I> {
417417
}
418418

419419
(TyData::Function(answer), TyData::Function(pending)) => {
420-
self.outer_binder.shift_in(1);
420+
self.outer_binder.shift_in();
421421
Zip::zip_with(self, &answer.parameters, &pending.parameters)?;
422-
self.outer_binder.shift_out(1);
422+
self.outer_binder.shift_out();
423423
Ok(())
424424
}
425425

@@ -484,9 +484,9 @@ impl<'i, I: Interner> Zipper<'i, I> for AnswerSubstitutor<'i, I> {
484484
where
485485
T: Zip<I> + Fold<I, Result = T>,
486486
{
487-
self.outer_binder.shift_in(1);
487+
self.outer_binder.shift_in();
488488
Zip::zip_with(self, &answer.value, &pending.value)?;
489-
self.outer_binder.shift_out(1);
489+
self.outer_binder.shift_out();
490490
Ok(())
491491
}
492492

chalk-solve/src/wf.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -378,7 +378,7 @@ where
378378
.iter()
379379
.zip(0..)
380380
.map(|p| p.to_parameter(interner));
381-
let impl_debruin = DebruijnIndex::INNERMOST.shifted_in(1);
381+
let impl_debruin = DebruijnIndex::INNERMOST.shifted_in();
382382
let impl_parameters = impl_binders
383383
.iter()
384384
.zip(0..)

0 commit comments

Comments
 (0)