You can find the relevant test with this link.
// Zero-sized type for verifying zst handling.
struct ZST;
#[test]
fn zst_iter() {
// (signal: 11, SIGSEGV: invalid memory reference)
let mut vec = super::ErasedVec::new(super::ErasedInfo::of::<Zst>());
// segfault occurs before this executes.
eprintln!("You are Here");
vec.write(Zst);
vec.write(Zst);
vec.write(Zst);
for ptr in vec.iter() {
unsafe {
assert_eq!(*ptr.cast::<Zst>(), Zst);
}
}
}
I am implementing type erasure for a game engine, I've narrowed down the issue to be coming from this function:
impl ErasedVec {
/// Create a new ErasedVec for elements of the specified type.
pub fn new(info: ErasedInfo) -> Self {
Self {
// guaranteed to be well-aligned, but dangling.
// created with NonNull::dangling::<T>(), for the
// type this erased vec stores.
data: unsafe { ptr::NonNull::new_unchecked(info.dangling) },
cap: if info.is_zero_sized() { usize::MAX } else { 0 },
// By default, the offset is set to 'size_of_one', but this
// may not be accurate for operating on the array, since
// this default value will not include the padding between
// elements.
//
// This value will be updated when `grow` is called.
offs: info.size_of_one(),
info,
len: 0,
}
}
}
I've also tested ErasedInfo::is_zero_sized()
and ErasedInfo::size_of_one()
and found no issues.
When running with the debugger, there is no error, so I don't have a good way to pinpoint the issue. I'm never dereferencing a pointer in new
, so this shouldn't even happen (at least to my knowledge).
Full Error:
Finished `test` profile [unoptimized + debuginfo] target(s) in 0.05s
Running unittests src/lib.rs (/home/wade/minecraft2/target/debug/deps/ecs-f1fd0862f572df9e)
running 1 test
error: test failed, to rerun pass `--lib`
Caused by:
process didn't exit successfully: `/home/wade/minecraft2/target/debug/deps/ecs-f1fd0862f572df9e zst_iter` (signal: 11, SIGSEGV: invalid memory reference)