Description
The following code compiles on nightly (playground):
#![feature(exhaustive_patterns, never_type)]
enum Either<A, B> {
A(A),
B(Wrapper<B>),
}
struct Wrapper<T>(T);
fn foo() -> Either<(), !> {
Either::A(())
}
fn main() {
let Either::A(()) = foo();
}
But if the wrapper type is moved into a module to make the field private, then it does not: (playground):
#![feature(exhaustive_patterns, never_type)]
mod inner {
pub struct Wrapper<T>(T);
}
enum Either<A, B> {
A(A),
B(inner::Wrapper<B>),
}
fn foo() -> Either<(), !> {
Either::A(())
}
fn main() {
let Either::A(()) = foo();
}
error[E0005]: refutable pattern in local binding: `Either::B(_)` not covered
--> src/main.rs:17:9
|
17 | let Either::A(()) = foo();
| ^^^^^^^^^^^^^ pattern `Either::B(_)` not covered
|
= note: `let` bindings require an "irrefutable pattern", like a `struct` or an `enum` with only one variant
= note: for more information, visit https://doc.rust-lang.org/book/ch18-02-refutability.html
note: `Either<(), !>` defined here
--> src/main.rs:9:5
|
7 | enum Either<A, B> {
| ------
8 | A(A),
9 | B(inner::Wrapper<B>),
| ^ not covered
= note: the matched value is of type `Either<(), !>`
help: you might want to use `if let` to ignore the variant that isn't matched
|
17 | if let Either::A(()) = foo() { todo!() }
| ++ ~~~~~~~~~~~
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, like note: 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