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 used foo before the change and has some code which matched on foo::Foo exhaustively.
There's also another library, baz.
Some application pulls in both bar and baz.
baz adds (possibly private) dependency on foowith 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?
A consequence of this is that features should be additive. That is, enabling a feature should not disable functionality, and it should usually be safe to enable any combination of features. A feature should not introduce a SemVer-incompatible change.
I think the downstream crate should not need to anticipate changes, and consequently it cannot be held responsible. A crate should be allowed to enable features of another, 2nd crate, without breaking a different, 3rd crate. If dependencies weren't locally compositional like that, then we would be chasing feature compatibility graphs and resolving conflicts manually all day…
Library bar used foo before the change and has some code which matched on foo::Foo exhaustively.
There's also another library, baz.
Some application pulls in both bar and baz.
Some new library quuz adds a dependency on foowith feature. They have no downstream as of yet. It's impossible for them to break SemVer. They were too excited about the Quuz Project to consider this situation when adding the foo dep, they just had a use for the feature.
baz adds a dependency on quuz
bar in the application's dependencies suddenly stops building.
There's no way to use the feature without breaking something for somebody. The mechanism for avoiding breaking everybody is to bump major version, not add a feature with a warning sticker you hope everyone reads. Even if everyone does, the only way they could be non-breaking is to release their own major version bump, or to opt in to the feature scheme and make their own booby-trapped feature. And if you're a brand-new crate, presumably hoping for adoption, there is no practical version bump option.
That's not something to encourage in the ecosystem.