For some time now,
MaybeUninit::assume_init call the
panic_if_uninhabited intrinsic, which monomorphizes to a panic for uninhabited types (types considered uninhabited in their layout). This prevents bugs like this, and it provides a clear warning signal: if you are providing a generic API and users can trigger this panic, they can also trigger UB.
mem::zeroed, we could actually do better: we could cause a panic if the type is something like a reference or
fn that has "0" in its niche, and we can check this recursively inside structs/tuples. The nomicon calls producing such values out as being UB. And we could do the same for
mem::uninitialized. (In principle,
mem::uninitialized could get an even stronger check, but starting with the types that do not accept the all-0 bit pattern seems like a good idea.)
Of course, there is the risk that people replace
MaybeUninit::zeroed().assume_init() to work around the panic. But
assume_init has been documented from the start to not permit this, while
mem::zeroed were not properly documented for a long time.
However, as reports like this show, there is code out there (probably more than we know of) that uses
mem::uninitialized incorrectly, and that would cause this panic all the time. This recent PR caused SIGILL for at least some code that uses
mem::uninitialized on types with a niche. This is somewhat comparable to the panic-on-unwind-across-FFI situation. Thus we should probably wait a bit before making this a panic, or provide a flag so users can test their code before this becomes the default, or run this through crater, or something like that? What do you think?