4 ms·
I don't think errors should have to follow semver. Please, break my match on non-major version bumps, if I didn't explicitly add a catch-all case.
by tempaccount420 2y ago
I don't think errors should have to follow semver. Please, break my match on non-major version bumps, if I didn't explicitly add a catch-all case.
- tialaramex 2y agoThat's what the #[non_exhaustive] attribute is for. If a struct or enum is given this attribute then everybody else is treated as though they cannot exhaustively match it, they must write the catch all case. You (as the owner of the type) can still exhaustively match it, after all you're the one who'll get broken by your own change if you screw up - but everybody else gets told they need to write the "catch all". So, no, errors aren't special and should obey semver but you deliberately can (and should) signal that your users can't exhaustively match a thing you know will change.
- fl0ki 2y agoIt's only fair to call out that #[non_exhaustive] only helps you for the very specific case of adding new enum variants or struct fields. It does nothing for the burden of keeping all existing variants and fields compatible with any way they could have been matched. However it's also only fair to note that the Rust ecosystem does not consider every [potential] breaking change a major one. https://predr.ag/blog/some-rust-breaking-changes-do-not-require-major-version/ https://predr.ag/blog/some-rust-breaking-changes-do-not-requ...
- tempaccount420 2y agoI want to be exhaustive on my error checks. I want my match to fail if a new variant is added, so that I can handle it (even if it's just to ignore it). A big reason why refactors can be so fearless in Rust is thanks to exhaustive checks. While the 'refactor' part applies mostly to your own, 1st party code, it's also useful when upgrading 3rd party dependencies. For this reason I personally don't like `#[non_exhaustive]`. I don't expect my code to keep compiling when I upgrade the minor version of my dependencies, and as long as the reason is simple, like a new enum variant was added, then I'm happy that it errored and will happily fix it. This perfectionist attitude towards semver is why so many projects get stuck forever at v0. https://0ver.org/ https://0ver.org/
- eptcyka 2y agoThe problem is not that a new variant of an enum could be introduced, it is that an error that a library returns has the option to return an *inner* error, which then could be a type defined by another library. Thus, if you develop library A and depend on library B, you cannot reasonably update B if you return it's errors because, by doing so, you're breaking your public API. Emotionally, I'm very much for breaking backwards compatibility and just bumping semver in these cases, but people more reasonable than myself have put forward the argument that such a policy would cause too much churn in the ecosystem.