this post was submitted on 07 Oct 2026
26 points (100.0% liked)
Rust
8317 readers
3 users here now
Welcome to the Rust community! This is a place to discuss about the Rust programming language.
Wormhole
Credits
- The icon is a modified version of the official rust logo (changing the colors to a gradient and black background)
founded 3 years ago
MODERATORS
you are viewing a single comment's thread
view the rest of the comments
view the rest of the comments
I'm not sure non-exhsustive makes sense — you want the caller to handle everything you may return to them, and the new errors won't be handled. Maybe a default branch in the handler could do, though
Had to just think about why
#[non_exhaustive]exists, so perhaps this helps you as well:Imagine you're developing a really important core library, something like TCP. And then other libraries depend on your library.
Now, if you change your implementation, you may need to introduce a new error case, even though the rest of the API still works the same.
You have two choices to deal with that:
#[non_exhaustive]before going 1.0 and therefore forced all depending libraries to implement a default match case. You can sneak in the new error case in version 1.1 without all those depending libraries needing to manually upgrade. The ecosystem does not split in half between 1.0 vs. 2.0.Obviously, if it's a really egregious new error case that needs specific handling, then you might still want to release version 2.0, but by adding the
#[non_exhaustive], you can decide later on and if you are such a central library, there's definitely going to be situations where you want to make use of it.I have been thinking of semver incorrectly, you're right: https://doc.rust-lang.org/cargo/reference/semver.html#enum-variant-new
This is exactly what it's for.
#[non_exhaustive]forces you to add a default branch when matching on the error. It's already used a lot, so without a way to do that, it becomes less useful in library code.