From d1bcf2ec849813edcd29587d45d476543f3c1dda Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jana=20D=C3=B6nszelmann?= Date: Tue, 18 Nov 2025 15:49:18 +0100 Subject: [PATCH] debug-assert FixedSizeEncoding invariant --- compiler/rustc_metadata/src/rmeta/table.rs | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/compiler/rustc_metadata/src/rmeta/table.rs b/compiler/rustc_metadata/src/rmeta/table.rs index a882ee4f2b92e..e61083e8bfba4 100644 --- a/compiler/rustc_metadata/src/rmeta/table.rs +++ b/compiler/rustc_metadata/src/rmeta/table.rs @@ -55,8 +55,10 @@ impl IsDefault for UnusedGenericParams { /// Helper trait, for encoding to, and decoding from, a fixed number of bytes. /// Used mainly for Lazy positions and lengths. -/// Unchecked invariant: `Self::default()` should encode as `[0; BYTE_LEN]`, +/// +/// Invariant: `Self::default()` should encode as `[0; BYTE_LEN]`, /// but this has no impact on safety. +/// In debug builds, this invariant is checked in `[TableBuilder::set]` pub(super) trait FixedSizeEncoding: IsDefault { /// This should be `[u8; BYTE_LEN]`; /// Cannot use an associated `const BYTE_LEN: usize` instead due to const eval limitations. @@ -432,6 +434,13 @@ impl> TableBui /// arises in the future then a new method (e.g. `clear` or `reset`) will need to be introduced /// for doing that explicitly. pub(crate) fn set(&mut self, i: I, value: T) { + #[cfg(debug_assertions)] + { + debug_assert!( + T::from_bytes(&[0; N]).is_default(), + "expected all-zeroes to decode to the default value, as per the invariant of FixedSizeEncoding" + ); + } if !value.is_default() { // FIXME(eddyb) investigate more compact encodings for sparse tables. // On the PR @michaelwoerister mentioned: