Skip to content

Commit 4bc8a01

Browse files
Merge #8360
8360: Fix shifting of binders in FnPointer r=flodiebold a=flodiebold - don't shift in/out for Chalk mapping (we want to have the same binders now) - do shift in when creating the signature for a closure (though it shouldn't matter much) - do shift in when lowering a `fn()` type - correctly deal with the implied binder in TypeWalk Tested with the binders validator on various repos, so I'm pretty sure this doesn't mess things up 😬 Co-authored-by: Florian Diebold <flodiebold@gmail.com>
2 parents 7ce0e9c + 1ae967b commit 4bc8a01

File tree

4 files changed

+23
-10
lines changed

4 files changed

+23
-10
lines changed

crates/hir_ty/src/infer/expr.rs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ use crate::{
2323
traits::{chalk::from_chalk, FnTrait},
2424
utils::{generics, variant_data, Generics},
2525
AdtId, Binders, CallableDefId, FnPointer, FnSig, FnSubst, InEnvironment, Interner,
26-
ProjectionTyExt, Rawness, Scalar, Substitution, TraitRef, Ty, TyBuilder, TyKind,
26+
ProjectionTyExt, Rawness, Scalar, Substitution, TraitRef, Ty, TyBuilder, TyKind, TypeWalk,
2727
};
2828

2929
use super::{
@@ -262,7 +262,9 @@ impl<'a> InferenceContext<'a> {
262262
let sig_ty = TyKind::Function(FnPointer {
263263
num_binders: 0,
264264
sig: FnSig { abi: (), safety: chalk_ir::Safety::Safe, variadic: false },
265-
substitution: FnSubst(Substitution::from_iter(&Interner, sig_tys.clone())),
265+
substitution: FnSubst(
266+
Substitution::from_iter(&Interner, sig_tys.clone()).shifted_in(&Interner),
267+
),
266268
})
267269
.intern(&Interner);
268270
let closure_id = self.db.intern_closure((self.owner, tgt_expr)).into();

crates/hir_ty/src/lower.rs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -178,8 +178,9 @@ impl<'a> TyLoweringContext<'a> {
178178
}
179179
TypeRef::Placeholder => TyKind::Error.intern(&Interner),
180180
TypeRef::Fn(params, is_varargs) => {
181-
let substs =
182-
Substitution::from_iter(&Interner, params.iter().map(|tr| self.lower_ty(tr)));
181+
let substs = self.with_shifted_in(DebruijnIndex::ONE, |ctx| {
182+
Substitution::from_iter(&Interner, params.iter().map(|tr| ctx.lower_ty(tr)))
183+
});
183184
TyKind::Function(FnPointer {
184185
num_binders: 0, // FIXME lower `for<'a> fn()` correctly
185186
sig: FnSig { abi: (), safety: Safety::Safe, variadic: *is_varargs },

crates/hir_ty/src/traits/chalk/mapping.rs

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
//! Chalk (in both directions); plus some helper functions for more specialized
44
//! conversions.
55
6-
use chalk_ir::{cast::Cast, fold::shift::Shift, interner::HasInterner, LifetimeData};
6+
use chalk_ir::{cast::Cast, interner::HasInterner, LifetimeData};
77
use chalk_solve::rust_ir;
88

99
use base_db::salsa::InternKey;
@@ -25,7 +25,7 @@ impl ToChalk for Ty {
2525
TyKind::Ref(m, ty) => ref_to_chalk(db, m, ty),
2626
TyKind::Array(ty) => array_to_chalk(db, ty),
2727
TyKind::Function(FnPointer { sig, substitution: substs, .. }) => {
28-
let substitution = chalk_ir::FnSubst(substs.0.to_chalk(db).shifted_in(&Interner));
28+
let substitution = chalk_ir::FnSubst(substs.0.to_chalk(db));
2929
chalk_ir::TyKind::Function(chalk_ir::FnPointer {
3030
num_binders: 0,
3131
sig,
@@ -132,10 +132,7 @@ impl ToChalk for Ty {
132132
..
133133
}) => {
134134
assert_eq!(num_binders, 0);
135-
let substs = crate::FnSubst(from_chalk(
136-
db,
137-
substitution.0.shifted_out(&Interner).expect("fn ptr should have no binders"),
138-
));
135+
let substs = crate::FnSubst(from_chalk(db, substitution.0));
139136
TyKind::Function(FnPointer { num_binders, sig, substitution: substs })
140137
}
141138
chalk_ir::TyKind::BoundVar(idx) => TyKind::BoundVar(idx),

crates/hir_ty/src/walk.rs

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,13 @@ pub trait TypeWalk {
9292
self
9393
}
9494

95+
fn shifted_in(self, _interner: &Interner) -> Self
96+
where
97+
Self: Sized,
98+
{
99+
self.shifted_in_from(DebruijnIndex::ONE)
100+
}
101+
95102
/// Shifts up debruijn indices of `TyKind::Bound` vars by `n`.
96103
fn shifted_in_from(self, n: DebruijnIndex) -> Self
97104
where
@@ -149,6 +156,9 @@ impl TypeWalk for Ty {
149156
TyKind::Slice(ty) | TyKind::Array(ty) | TyKind::Ref(_, ty) | TyKind::Raw(_, ty) => {
150157
ty.walk(f);
151158
}
159+
TyKind::Function(fn_pointer) => {
160+
fn_pointer.substitution.0.walk(f);
161+
}
152162
_ => {
153163
if let Some(substs) = self.substs() {
154164
for t in substs.iter(&Interner) {
@@ -180,6 +190,9 @@ impl TypeWalk for Ty {
180190
TyKind::Slice(ty) | TyKind::Array(ty) | TyKind::Ref(_, ty) | TyKind::Raw(_, ty) => {
181191
ty.walk_mut_binders(f, binders);
182192
}
193+
TyKind::Function(fn_pointer) => {
194+
fn_pointer.substitution.0.walk_mut_binders(f, binders.shifted_in());
195+
}
183196
_ => {
184197
if let Some(substs) = self.substs_mut() {
185198
substs.walk_mut_binders(f, binders);

0 commit comments

Comments
 (0)