This is exactly the question. We want the match expression you wrote to NOT be UB. However, if you leave away the only branch, then it must be UB as there is no code we could otherwise execute.
Basically, your match is equivalent to
{
let v = x.value.0;
// access only first part of the tuple
}
and hence does not ever touch a T
, so whether there is a valid T
stored there does not matter.
Note that focusing entirely on !
is a bit of a red herring. If T
was bool, the following would be UB:
match x.value {
(v, true) => {
// access only first part of the tuple
}
_ => {}
}
because you are "touching" an uninitialized and hence invalid bool
. However, your match is still fine because it does not care about the value of the bool
. The situation is entirely symmetric for !
, and pattern that "touches" the uninhabited field is !
.
Basically we only want to auto-never if there cannot ever be any valid data anywhere in the thing you are not matching. Matching a (u32, !)
can yield valid data, and hence it does not get auto-nevered. It is still uninhbaited though so you can manually apply the never pattern:
match x.value {
(_, !) // one arm has !, no code needed
}
See Uninhabited types are ZSTs despite partial initialization being allowed in safe code. · Issue #49298 · rust-lang/rust · GitHub for an example of how treating products with one uninhabited field as entirely uninhabited has caused trouble. That was a compiler bug, of course, but partial initialization is something we want unsafe code to be able to do.
This is not entirely simple -- how do you define "unsafe
code"? Checking if the match itself is in an unsafe block is not enough, people often use very localized unsafe blocks. So you have to at least check the entire function. But maybe better check the entire module?
I also think it would be rather surprising to have unsafe blocks affect code generation at all.
Anyway, a nice aspect of this proposal is that we can start with conservative rules for auto-nevering and expand them later to auto-never in more cases, if this is really such a common case.