Skip to content

Commit 77c3c59

Browse files
committed
feat: Add size_ok for asserting size is not too big
This compares using `==` on 64-bit targets and `<=` on 32-bit targets. As noted in the documentation comment, when assertions about data stuructures' sizes are being done to safeguard against them growing too big, then it may be acceptable to use `<=` if the structure is smaller on 32-bit targets, but it is still valuable to be able to use `==` on 64-bit targets in the same assertions, since this guards against a data structure becoming smaller, other changes causing the smaller size to be important for memory usage or speed, but then the data structure growing again, up to its original size. An unconditional `<=` will not catch this, while `size_ok` usually will. A related reason to do a `==` on 64-bit systems is so that the expected value being compared to remains tied to the code. It can otherwise become unclear what the expected value's significance is and whether it ought to be updated.
1 parent 178cf25 commit 77c3c59

File tree

1 file changed

+24
-0
lines changed

1 file changed

+24
-0
lines changed

tests/tools/src/lib.rs

+24
Original file line numberDiff line numberDiff line change
@@ -882,6 +882,30 @@ impl Drop for Env<'_> {
882882
}
883883
}
884884

885+
/// Check data structure size, comparing strictly on 64-bit targets.
886+
///
887+
/// - On 32-bit targets, checks if `actual_size` is at most `expected_64_bit_size`.
888+
/// - On 64-bit targets, checks if `actual_size` is exactly `expected_64_bit_size`.
889+
///
890+
/// This is for assertions about the size of data structures, when the goal is to keep them from
891+
/// growing too large even across breaking changes. Such assertions must always fail when data
892+
/// structures grow larger than they have ever been, for which `<=` is enough. But it also helps to
893+
/// know when they have shrunk unexpectedly. They may shrink, other changes may rely on the smaller
894+
/// size for acceptable performance, and then they may grow again to their earlier size.
895+
///
896+
/// The problem with `==` is that data structures are often smaller on 32-bit targets. This could
897+
/// be addressed by asserting separate exact 64-bit and 32-bit sizes. But sizes may also differ
898+
/// across 32-bit targets, due to ABI and layout/packing details. That can happen across 64-bit
899+
/// targets too, but it seems less common.
900+
///
901+
/// For those reasons, this function does a `==` on 64-bit targets, but a `<=` on 32-bit targets.
902+
pub fn size_ok(actual_size: usize, expected_64_bit_size: usize) -> bool {
903+
#[cfg(target_pointer_width = "64")]
904+
return actual_size == expected_64_bit_size;
905+
#[cfg(target_pointer_width = "32")]
906+
return actual_size <= expected_64_bit_size;
907+
}
908+
885909
#[cfg(test)]
886910
mod tests {
887911
use super::*;

0 commit comments

Comments
 (0)