-
Notifications
You must be signed in to change notification settings - Fork 12.8k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
#[feature(exhaustive_patterns)]
thinks irrefutable pattern is refutable when enum contains struct with private fields.
#104034
Comments
@rustbot label +F-exhaustive_patterns |
…imulacrum Add a few known-bug tests The labels of these tests should be changed from `S-bug-has-mcve` to `S-bug-has-test` once this is merged. cc: rust-lang#101518 rust-lang#99492 rust-lang#90950 rust-lang#89196 rust-lang#104034 rust-lang#101350 rust-lang#103705 rust-lang#103899 I couldn't reproduce the failures in rust-lang#101962 and rust-lang#100772 (so either these have started passing, or I didn't repro properly), so leaving those out for now. rust-lang#102065 was a bit more complicated, since it uses `rustc_private` and I didn't want to mess with that.
@jackh726 are we sure this is actually a bug? As I said, I could understand how it's not:
|
I'm not sure either way - however at the very least, as you point out, it makes sense to have some better diagnostics |
This is definitely intentional. But yeah, it should have a better error message.
Not currently I don't think. It would probably require us to add an trait Uninhabited {
fn uninhabited(self) -> !;
}
impl<T> Uninhabited for Wrapper<T>
where
T: Uninhabited,
{
fn uninhabited(self) -> ! {
let Wrapper(inner) = self;
match inner {}
}
} This trait would then need to be a lang item so that the exhaustiveness check could make use of it. Adding this trait would require an RFC but I doubt there'll be much enthusiasm for adding another special trait for such a niche use-case. Alternatively, you could give let a = match foo() {
Either::A(a) => a,
Either::B(wrapper) => match wrapper.get_ref() {},
}; |
Is |
If the type implementing |
Making |
The following code compiles on nightly (playground):
But if the wrapper type is moved into a module to make the field private, then it does not: (playground):
Making the field
pub
makes it compile again.Is this expected? I suppose I could understand if it is; the private fields could change to make
Wrapper<!>
actually be constructable and therefore make the pattern refutable. But if that's the case, then I think the compiler should point this out, likenote: the pattern is currently irrefutable, but the type contains private fields which may change in the future to make the pattern refutable
.If indeed this is expected, is there any way for me as a library author to somehow convince the compiler that I will never change the fields to make the type constructable? I want users of my library to be able to elide match arms when I give them an
Either<A, !>
.@rustbot label +T-compiler +F-never_type +D-confusing +requires-nightly +S-bug-has-mcve
The text was updated successfully, but these errors were encountered: