Open
Description
openedon Dec 23, 2023
In rust-lang/rfcs#3535 (comment) it was noticed that it is possible to match a #[non_exhaustive]
struct exhaustively outside the originating crate,
if constants for all posible states are accessible or definable in the other crate.
As a result adding fields such that the struct has new states is a breaking change, as the existing constants won't be able to cover all states anymore.
Which makes #[non_exhaustive]
ineffective.
For Example:
// bar/src/lib.rs
#[non_exhaustive]
#[derive(PartialEq, Eq)]
pub struct Bar(bool);
pub const TRUE: Bar = Bar(true);
pub const FALSE: Bar = Bar(false);
// foo/src/main.rs
fn main() {
match bar::TRUE {
bar::TRUE => {}
bar::FALSE => {}
}
}
Changing the bar crate to the following is then a breaking change:
// bar/src/lib.rs
#[non_exhaustive]
#[derive(PartialEq, Eq)]
pub struct Bar(bool, bool);
pub const TRUE: Bar = Bar(true, true);
pub const FALSE: Bar = Bar(false, false);
This breaks the foo crate, eventhough Bar was marked #[non_exhaustive]
to allow expanding.
Meta
rustc +stable --version
rustc 1.74.1 (a28077b28 2023-12-04)
rustc +beta --version
rustc 1.76.0-beta.1 (0e09125c6 2023-12-21)
rustc +nightly --version
rustc 1.77.0-nightly (d6d7a9386 2023-12-22)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment