I suspect the rules will need to be slightly changed if the
feature attribute itself becomes stable, like this post proposes.
#![feature(ident)] is a feature error if
ident belongs to the list of unstable features, and a lint from the
unused group otherwise (probably deny-by-default).
This way we can garbage collect stable features as we want, it will only affect diagnostics wording.
There is a minor compatibility issue though - introduction of a new feature
foo is technically a breaking change since it moves
#![feature(foo)] from a lint to a hard error, but that’s probably not an issue in practice.
It’s not entirely clear how the “unstable” list is collected though.
For language features it’s hard-coded, but for library features it needs to be actively collected, which may be unfriendly to lazy compilation (i.e. want to check
feature(foo) -> look through the whole standard library? other dependencies?).