Inspired by this SO question - rust - Is it bad practice to create a feature-gated enum variant? - Stack Overflow, I'd like to ask the community's opinion: what do you think about adding feature-gated breaking changes to the library?
For the specific example, let's see the (slightly modified) code from question. Imagine there's some library foo
, which exports this enum:
pub enum Foo {
Variant,
}
It's not marked as non-exhaustive, so any downstream crate can match on the value of this enum exhaustively by handling the (only) existing variant.
Now imagine, that foo
's maintainers add another variant to Foo
, but enable it conditionally based on newly-created (and non-default) feature flag:
pub enum Foo {
Variant,
#[cfg(feature = "gate")] GatedVariant,
}
Now, any downstream crates which were using the library before can update without breakage, since by default it will still have only the first variant, and foo
's maintainers might assume that they may do semver-compatible version bump.
However, if it was used as a transitive dependency, here's the possibility for breakage to happen indirectly:
- Library
bar
usedfoo
before the change and has some code which matched onfoo::Foo
exhaustively. - There's also another library,
baz
. - Some application pulls in both
bar
andbaz
. -
baz
adds (possibly private) dependency onfoo
with feature. -
bar
in the application's dependencies suddenly stops building.
The question is, who is responsible for this breakage? foo
, which should treat feature-gated breaking changes as still breaking and bump the major version? Or some of the downstream crates, which could anticipate the change?