- Notifications
You must be signed in to change notification settings - Fork 13.8k
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