fusebox
fusebox copied to clipboard
Still triggers UB
So, I wrote some random testing, and it consistently fails cargo miri run for me, so… have fun with it :-)
#![allow(clippy::all)]
use std::any::Any;
use fusebox::FuseBox;
use rand::random;
fn main() {
for _ in 0..100 {
let mut x: FuseBox<dyn Any> = FuseBox::new();
for _ in 0..(random::<u8>() / 10) {
if random() {
x.push(0_u8);
} else if random() {
x.push(0_u16);
} else if random() {
x.push(0_u32);
} else {
x.push(0_u64);
}
}
}
}
This one is, uh, fun. Adding and removing dbg!(std::any::type_name::<T>()); from push_unsafe somehow affects whether MIRI detects UB or not :)
As far as I could tell, miri uses a deterministic random number generation. Maybe increasing the 0..100 loop helps getting back an error?
Deterministic as in, does the same thing every run, reproducibly.
I reduced the case to a single sequence of inserts, but it has aforementioned non-deterministic behaviour.
let mut x: FuseBox<dyn Debug> = FuseBox::new();
x.push(0_u8);
x.push(0_u8);
x.push(0_u16);
x.push(0_u8);
x.push(0_u8);
x.push(0_u8);
x.push(0_u8);
x.push(0_u16);
x.push(0_u32);
For these test cases, it might also be relevant how well-aligned the allocations just happen to be by mere chance. I don’t know how miri decides on that point.
I don't know if println or dbg could involve any allocations or otherwise influences this behavior.
@steffahn I believe this issue is now fixed! A bit of an ugly fix: just reallocating when maximum alignment requirement increases, even if there is capacity to spare, but this avoids complex bookeeping logic.