cuviper / autocfg

Automatic cfg for Rust compiler features
Apache License 2.0
95 stars 24 forks source link

Probing for nightly #28

Open maxbla opened 3 years ago

maxbla commented 3 years ago

Would it be a good idea to allow consumers of autocfg to probe if their compiler is nightly or not? This could be used in instances where a crate uses a nightly api, but it is not essential to the functioning of the crate. For example, a nightly-only api might make a function faster, or enable more functionality. Allowing probing if the compiler is nightly could allow a crate to automatically enable a "nightly" feature, so nightly users don't have to manually enable the feature. Alternatively crates that require nightly (like the popular rocket not so long ago) could give custom error messages with links to explanations of why they need nightly.

The argument against such an api is that it could be too magic and it could be bad for crater i.e. did nightly break the code or was the code always broken with the nightly feature enabled.

cuviper commented 3 years ago

I'm open to it. We could add some nightly detection in the version part of the API (and dev is the equivalent), but I would also want to see some principled feature probing. There could be methods to set global #![feature(...)], like what I'm doing for no_std in #27, and then folks can use probes to see whether a feature works as they expect. Maybe the feature flags should be set on a per-probe basis, but I don't want to double the entire API, so this needs consideration.

The argument against such an api is that it could be too magic and it could be bad for crater i.e. did nightly break the code or was the code always broken with the nightly feature enabled.

I think there are other version-detection build crates that already deal with nightly, so that cat is out of the bag...

But I do agree that this should be used carefully, if at all.

maxbla commented 3 years ago

Per-probe features seems excesive. Here's the API I'm imagining.

autocfg::set_feature(&mut self, &str feature)

which adds

#![feature(example_feature)]

at the start of all probes as you described. But setting features fails on stable and beta, so consumers of this api must probe which channel they're on

enum Channel {
    Stable,
    Beta,
    Nightly,
}

autocfg::probe_channel(&self) -> Channel

Alternatively, we cold have an api that looks something like

autocfg::set_feature(&mut self, &str feature)
autocfg::probe_expression(&self, expr: &str) -> Result<bool, InvalidChannelError>

With no explicit probe_channel. All probes would return a Result type that indicates if a feature was used in a non-nightly channel.

matklad commented 3 years ago

As a case study, it would be nice to switch https://github.com/Xudong-Huang/generator-rs from rustc_version to autocfg.

As an option for stateless API, we coud consider this:

impl AutoCfg {
  // Checks that `#[features(my-feature)]` doesn't get "you need nightly" / "unknown feature" error
  pub fn probe_features(&self, features: &[str]) -> bool;
  // Checks that feature *exists* and that it work as expected (by compiling expr with features enabled)
  pub fn probe_features_with(&self, features &[str], expr: &str) -> bool;
}