Description
A common pattern in the wild is to do this kind of thing in build.rs
:
if channel == "nightly" {
println!("cargo:rustc-cfg=feature=\"something\"");
}
Where something
is a Cargo feature that is used in code as #![cfg_attr(feature = something, feature(cool_new_feature))]
.
This is generally considered an anti-pattern. However, despite being proscribed, it is found often in the ecosystem.
A more advanced version that actually build-tests some code with the feature is found in some popular crates; that version is less problematic as it will silently fall back to the stable behavior when the feature changes.
This leads to a really bad situation when the feature is has its name changed or split up into smaller features. It is currently occuring with the ahash crate, as can be seen in tkaitchuck/aHash#200.
People depending on the crate and running nightly get a hard error with the crate because the feature flag "no longer exists". If the crate removes the feature flag, that's an immediate MSRV bump for everyone else since the crate uses still-unstable APIs.
It's particularly annoying in CI where people typically have a single Cargo.lock.
Most of the time a nightly feature has its name changed; there's a decent gap between the point in time in the name changes and when actual changes to the APIs behind it happen. Which means in most of these cases, the only thing broken about this code on nightly is the feature(cool_new_feature)
line, the rest will still work.
Given that this is a technique found in the wild, would it make sense to have this error behave according to cap-lints
instead, at least in the short run after a feature is renamed, with some tracking of the rename? Every time I've seen this cause breakage there's a whole lot of should-be-unnecessary scrambling to fix transitive dependencies.