diff options
| author | Nicholas Nethercote <n.nethercote@gmail.com> | 2025-07-30 19:04:03 +1000 |
|---|---|---|
| committer | Nicholas Nethercote <n.nethercote@gmail.com> | 2025-07-31 19:54:58 +1000 |
| commit | 64be8bb599d3efa12235e266177c828ad97373e6 (patch) | |
| tree | 4c7a69f465e30ae6087f20b6ea4c85f69e5d391e | |
| parent | 507dec4dc321c868ad876c0b7302c66088b7cc7c (diff) | |
| download | rust-64be8bb599d3efa12235e266177c828ad97373e6.tar.gz rust-64be8bb599d3efa12235e266177c828ad97373e6.zip | |
Check consts in `ValidateBoundVars`.
Alongside the existing type and region checking.
| -rw-r--r-- | compiler/rustc_middle/src/ty/mod.rs | 4 | ||||
| -rw-r--r-- | compiler/rustc_type_ir/src/binder.rs | 23 |
2 files changed, 23 insertions, 4 deletions
diff --git a/compiler/rustc_middle/src/ty/mod.rs b/compiler/rustc_middle/src/ty/mod.rs index fab020547ad..342f5987466 100644 --- a/compiler/rustc_middle/src/ty/mod.rs +++ b/compiler/rustc_middle/src/ty/mod.rs @@ -977,8 +977,8 @@ impl<'tcx> rustc_type_ir::inherent::BoundVarLike<TyCtxt<'tcx>> for BoundConst { self.var } - fn assert_eq(self, _var: ty::BoundVariableKind) { - unreachable!() + fn assert_eq(self, var: ty::BoundVariableKind) { + var.expect_const() } } diff --git a/compiler/rustc_type_ir/src/binder.rs b/compiler/rustc_type_ir/src/binder.rs index a7b915c4845..fb0dfe95b73 100644 --- a/compiler/rustc_type_ir/src/binder.rs +++ b/compiler/rustc_type_ir/src/binder.rs @@ -274,8 +274,9 @@ impl<I: Interner, T: IntoIterator> Binder<I, T> { pub struct ValidateBoundVars<I: Interner> { bound_vars: I::BoundVarKinds, binder_index: ty::DebruijnIndex, - // We may encounter the same variable at different levels of binding, so - // this can't just be `Ty` + // We only cache types because any complex const will have to step through + // a type at some point anyways. We may encounter the same variable at + // different levels of binding, so this can't just be `Ty`. visited: SsoHashSet<(ty::DebruijnIndex, I::Ty)>, } @@ -319,6 +320,24 @@ impl<I: Interner> TypeVisitor<I> for ValidateBoundVars<I> { t.super_visit_with(self) } + fn visit_const(&mut self, c: I::Const) -> Self::Result { + if c.outer_exclusive_binder() < self.binder_index { + return ControlFlow::Break(()); + } + match c.kind() { + ty::ConstKind::Bound(debruijn, bound_const) if debruijn == self.binder_index => { + let idx = bound_const.var().as_usize(); + if self.bound_vars.len() <= idx { + panic!("Not enough bound vars: {:?} not found in {:?}", c, self.bound_vars); + } + bound_const.assert_eq(self.bound_vars.get(idx).unwrap()); + } + _ => {} + }; + + c.super_visit_with(self) + } + fn visit_region(&mut self, r: I::Region) -> Self::Result { match r.kind() { ty::ReBound(index, br) if index == self.binder_index => { |
