about summary refs log tree commit diff
diff options
context:
space:
mode:
authorNicholas Nethercote <n.nethercote@gmail.com>2025-07-30 19:04:03 +1000
committerNicholas Nethercote <n.nethercote@gmail.com>2025-07-31 19:54:58 +1000
commit64be8bb599d3efa12235e266177c828ad97373e6 (patch)
tree4c7a69f465e30ae6087f20b6ea4c85f69e5d391e
parent507dec4dc321c868ad876c0b7302c66088b7cc7c (diff)
downloadrust-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.rs4
-rw-r--r--compiler/rustc_type_ir/src/binder.rs23
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 => {