User avatar
mei @mei@donotsta.re
9mo
new and exciting rustc edge cases in your area: “removing a #[non_exhaustive] attribute can cause another crate to stop compiling” neocat_sweat

github.com/rust-lang/reference/pull/1837#discussion_r2630423434
1
0
0
0
User avatar
celeste_hearts_lesbianceleste_hearts_transceleste_hearts_demisexual flori_ava_star:~cursor_blinking @star@amazonawaws.com
9mo
@mei Why is that new? Adding/removing #[non_exhaustive] has always been a breaking API change for your crate if I am not mistaken?
1
0
0
0
User avatar
mei @mei@donotsta.re
9mo
@star I mean, adding #[non_exhaustive] would be a breaking change, because you’re essentially adding a “imagine there are more variants you don’t know about”.

But removing
#[non_exhaustive] is essentially providing more guarantees: “I’m done changing this type, you can rely on it not getting any extra variants in the future”.

Do you have any specific cases in mind where removing a
#[non_exhaustive] attribute can be a breaking change on e.g. current stable Rust?
1
0
1
0
User avatar
celeste_hearts_lesbianceleste_hearts_transceleste_hearts_demisexual flori_ava_star:~cursor_blinking @star@amazonawaws.com
9mo
@mei Not "breaking" as in "won't compile", but as in "the API you have written now has a different set of guarantees compared to what it did before, in a manner where behavior relying on the old assumptions will be triggered differently or not at all". Idk. I think I would consider this a breaking change, even if both compile. Therefore, I do think that the planned(?) change to represent this as "doesn't compile" makes a lot of sense
1
0
0
0

User avatar
mei @mei@donotsta.re
9mo
@star what do you mean? if you remove #[non_exhaustive], you’re giving the users of your library strictly more guarantees. the only thing it affects is “if you’re pattern matching on the enum, you need a wildcard”, or at least that’s the story we want to tell even though right now there are some subtleties in the lowering to MIR that we’re working out.

apart from the aforementioned lowering weirdness, there is no way to write code that is only correct because the
#[non_exhaustive] is there. the purpose of this attribute is to give the author of the library more freedom in how they want to change the API between versions. there’s no way to write code that relies on “this enum might have more variants in the future”. that just doesn’t make sense.

I guess you
could make a contrived example where you explicitly mark the “this branch is now unused” lint with #[deny(...)] and then if the #[non_exhaustive] is removed, the branch will become statically unreachable and the compiler will give you a warning that will turn into an error? but I’d expect this to explicitly be a “you brought this upon yourself” carveout in the stability guarantees
0
0
0
0