Subtle breaking change with match patterns on uninhabited types #38889
Labels
I-needs-decision
Issue: In need of a decision.
P-high
High priority
regression-from-stable-to-nightly
Performance or correctness regression from stable to nightly.
T-compiler
Relevant to the compiler team, which will review and decide on the PR/issue.
T-lang
Relevant to the language team, which will review and decide on the PR/issue.
If an enum contained an uninhabited type, it is now valid to ignore matching that variant (and in fact encouraged, since include that pattern or
_
now receives a warning).I'll take a reduced example from hyper:
hyper::Error
Currently,
hyper::Error
includes a__DontMatchMe
variant as part of its way of saying that theError
enum could grow more variants. People should instead use a_
pattern. This is the best one can do to imitatestd::io::ErrorKind
, but without the additional#[unstable]
attribute protecting it.Since the
__DontMatchMe
variant should never actually be created, I filled it with an uninhabited type, so allow the optimizer to remove arms using it instd::error::Error
and other such impls.With rustc 1.14, this is correct:
With nightly after #38069 was landed, the above will warn that the user should remove the
_
pattern. If they do so, then the contract that__DontMatchMe
was supposed to provide is broken. With the_
removed, it looks like every variant is handled, and so any upgrade in hyper that adds a new variant will break this code. And that code will look innocent, where as before at least someone you need to explitictly do amatch e { Error::__DontMatchMe => () }
and know that it could break.I can remove the uninhabited type in hyper, but this behavior change does feel like one of the subtlely breaking kind.
The text was updated successfully, but these errors were encountered: