Making crates optionally compatible with the beta


#1

What is the best way to make a crate compatible with the beta (and eventually stable) channel, while using unstable features/APIs if compiled with a nightly channel release? As an example, take the ecs-rs crate: it’s only incompatible with the beta because it uses Vec<T>::drain and VecMap<T> which are behind feature gates. There are less efficient alternatives in the beta channel that could be easily substituted for these unstable features (cf. https://github.com/tomjakubowski/ecs-rs/commit/52cfc692224e634d882e3feb5347109db4e2e84e).

Would this be an appropriate use of Cargo features (combined with #[cfg_attr(.)] and #[cfg(..)], to swap out implementations depending on Rust release one wishes to use? It seems like it could be problematic (consider if ecs-rs is a transitive dependency, for example). Is this a feature worth supporting directly in Cargo?


#2

As I read the cargo docs, that’s exactly what features are for. And they are supported directly in Cargo.


#3

It’s awfully inconvenient to use them for this purpose because every library crate that depends on such a library would need to have its own ad-hoc beta/nightly support feature, so it could build its dependencies with the correct beta/nightly feature as well. That sounds like a nightmare to me.

I found this thread on internals which suggests an appropriate enhancement to the Rust distribution to support this use case. https://internals.rust-lang.org/t/setting-cfg-nightly-on-nightly-by-default/1893


#4

Exactly. Cargo features are not flags. They are not designed for these kind of things.


#5

In that case I misread the cargo docs and you should disregard my previous comment.


#6

My two cents:

I think cargo features really are what you should use for this, with a ‘nightly-features’ feature which depends on the nightly versions of all of your crate’s dependencies.

I would oppose a method to compile code depending on rust channel without having input from the end binary crate (like enabling the nightly feature).

The problem I see with having some way to change the code depending on release channel is that you can then have a crate which compiles on the latest release, and then fails to compile on the nightly directly after. If your crate compiles on the latest beta/stable, there should be a guarantee that is compiles on later versions (even if those are nightly).

Allowing a crate that compiles on 1.0.0 to be subject to breaking changes in unstable features on nightlies without the user explicitly choosing to have the library use unstable features is a breach of contract.