Skip to content

Commit b8bd997

Browse files
committed
chalk/db: use correct debrujin index when replacing opaque type.
1 parent c6f5c7b commit b8bd997

File tree

1 file changed

+40
-15
lines changed
  • compiler/rustc_traits/src/chalk

1 file changed

+40
-15
lines changed

compiler/rustc_traits/src/chalk/db.rs

Lines changed: 40 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
99
use rustc_middle::traits::ChalkRustInterner as RustInterner;
1010
use rustc_middle::ty::subst::{InternalSubsts, Subst, SubstsRef};
11-
use rustc_middle::ty::{self, AssocItemContainer, AssocKind, TyCtxt, TypeFoldable};
11+
use rustc_middle::ty::{self, AssocItemContainer, AssocKind, Ty, TyCtxt, TypeFoldable};
1212

1313
use rustc_ast::ast;
1414
use rustc_attr as attr;
@@ -482,21 +482,11 @@ impl<'tcx> chalk_solve::RustIrDatabase<RustInterner<'tcx>> for RustIrDatabase<'t
482482
.iter()
483483
.map(|(bound, _)| bound.subst(self.interner.tcx, &bound_vars))
484484
.map(|bound| {
485-
bound.fold_with(&mut ty::fold::BottomUpFolder {
485+
bound.fold_with(&mut ReplaceOpaqueTyFolder {
486486
tcx: self.interner.tcx,
487-
ty_op: |ty| {
488-
if let ty::Opaque(def_id, substs) = *ty.kind() {
489-
if def_id == opaque_ty_id.0 && substs == identity_substs {
490-
return self.interner.tcx.mk_ty(ty::Bound(
491-
ty::INNERMOST,
492-
ty::BoundTy::from(ty::BoundVar::from_u32(0)),
493-
));
494-
}
495-
}
496-
ty
497-
},
498-
lt_op: |lt| lt,
499-
ct_op: |ct| ct,
487+
opaque_ty_id,
488+
identity_substs,
489+
binder_index: ty::INNERMOST,
500490
})
501491
})
502492
.filter_map(|bound| {
@@ -739,3 +729,38 @@ fn binders_for<'tcx>(
739729
}),
740730
)
741731
}
732+
733+
struct ReplaceOpaqueTyFolder<'tcx> {
734+
tcx: TyCtxt<'tcx>,
735+
opaque_ty_id: chalk_ir::OpaqueTyId<RustInterner<'tcx>>,
736+
identity_substs: SubstsRef<'tcx>,
737+
binder_index: ty::DebruijnIndex,
738+
}
739+
740+
impl<'tcx> ty::TypeFolder<'tcx> for ReplaceOpaqueTyFolder<'tcx> {
741+
fn tcx<'b>(&'b self) -> TyCtxt<'tcx> {
742+
self.tcx
743+
}
744+
745+
fn fold_binder<T: TypeFoldable<'tcx>>(
746+
&mut self,
747+
t: ty::Binder<'tcx, T>,
748+
) -> ty::Binder<'tcx, T> {
749+
self.binder_index.shift_in(1);
750+
let t = t.super_fold_with(self);
751+
self.binder_index.shift_out(1);
752+
t
753+
}
754+
755+
fn fold_ty(&mut self, ty: Ty<'tcx>) -> Ty<'tcx> {
756+
if let ty::Opaque(def_id, substs) = *ty.kind() {
757+
if def_id == self.opaque_ty_id.0 && substs == self.identity_substs {
758+
return self.tcx.mk_ty(ty::Bound(
759+
self.binder_index,
760+
ty::BoundTy::from(ty::BoundVar::from_u32(0)),
761+
));
762+
}
763+
}
764+
ty
765+
}
766+
}

0 commit comments

Comments
 (0)