diff options
| author | Guillaume Gomez <guillaume1.gomez@gmail.com> | 2025-05-25 15:11:47 +0200 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2025-05-25 15:11:47 +0200 |
| commit | b0ae2280079c55c526f31255cf69b005fe3ddb92 (patch) | |
| tree | 161e510a774b71c6d747b0575631bcf10b7fd4ce | |
| parent | aa57e46e24a4a08cc336325e92567b40b0c2ba62 (diff) | |
| parent | f3245e48f98497856fa238f903f738c0681150ee (diff) | |
| download | rust-b0ae2280079c55c526f31255cf69b005fe3ddb92.tar.gz rust-b0ae2280079c55c526f31255cf69b005fe3ddb92.zip | |
Rollup merge of #141413 - est31:cfg_version_env_var, r=jieyouxu
Make #[cfg(version)] respect RUSTC_OVERRIDE_VERSION_STRING The `#[cfg(version(...))]` feature is currently under-tested. Part of it is the difficulty that it is hard to write a test that never changes, while the version of the Rust compiler indeed *does* change. PR #81468 added the first and so far only test of `#[cfg(version(...))]`'s functionality (there is one other test for the *syntax*, that also acts as feature gate). But that test uses a proc macro that parses the version: the text of the test doesn't contain the actual `#[cfg(version(...))]`. This PR makes `#[cfg(version(...))]` respect `RUSTC_OVERRIDE_VERSION_STRING`, added by PR #124339, allowing us to virtually pin the rustc version and write tests from all directions against some specific version. The PR also adds a functional test of `#[cfg(version(...))]` that leverages `RUSTC_OVERRIDE_VERSION_STRING`. Pulled out of #141137. Tracking issue: #64796
| -rw-r--r-- | compiler/rustc_attr_data_structures/src/version.rs | 22 | ||||
| -rw-r--r-- | compiler/rustc_attr_parsing/src/attributes/cfg.rs | 4 | ||||
| -rw-r--r-- | tests/ui/cfg/cfg-version/cfg-version-expand.rs | 30 | ||||
| -rw-r--r-- | tests/ui/cfg/cfg-version/cfg-version-expand.stderr | 17 |
4 files changed, 71 insertions, 2 deletions
diff --git a/compiler/rustc_attr_data_structures/src/version.rs b/compiler/rustc_attr_data_structures/src/version.rs index 69b0e041d81..030e9520940 100644 --- a/compiler/rustc_attr_data_structures/src/version.rs +++ b/compiler/rustc_attr_data_structures/src/version.rs @@ -1,4 +1,5 @@ use std::fmt::{self, Display}; +use std::sync::OnceLock; use rustc_macros::{ Decodable, Encodable, HashStable_Generic, PrintAttribute, current_rustc_version, @@ -16,8 +17,29 @@ pub struct RustcVersion { impl RustcVersion { pub const CURRENT: Self = current_rustc_version!(); + pub fn current_overridable() -> Self { + *CURRENT_OVERRIDABLE.get_or_init(|| { + if let Ok(override_var) = std::env::var("RUSTC_OVERRIDE_VERSION_STRING") + && let Some(override_) = Self::parse_str(&override_var) + { + override_ + } else { + Self::CURRENT + } + }) + } + fn parse_str(value: &str) -> Option<Self> { + // Ignore any suffixes such as "-dev" or "-nightly". + let mut components = value.split('-').next().unwrap().splitn(3, '.'); + let major = components.next()?.parse().ok()?; + let minor = components.next()?.parse().ok()?; + let patch = components.next().unwrap_or("0").parse().ok()?; + Some(RustcVersion { major, minor, patch }) + } } +static CURRENT_OVERRIDABLE: OnceLock<RustcVersion> = OnceLock::new(); + impl Display for RustcVersion { fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result { write!(formatter, "{}.{}.{}", self.major, self.minor, self.patch) diff --git a/compiler/rustc_attr_parsing/src/attributes/cfg.rs b/compiler/rustc_attr_parsing/src/attributes/cfg.rs index 7cb1fede174..528f56dfac7 100644 --- a/compiler/rustc_attr_parsing/src/attributes/cfg.rs +++ b/compiler/rustc_attr_parsing/src/attributes/cfg.rs @@ -129,9 +129,9 @@ pub fn eval_condition( // See https://github.com/rust-lang/rust/issues/64796#issuecomment-640851454 for details if sess.psess.assume_incomplete_release { - RustcVersion::CURRENT > min_version + RustcVersion::current_overridable() > min_version } else { - RustcVersion::CURRENT >= min_version + RustcVersion::current_overridable() >= min_version } } MetaItemKind::List(mis) => { diff --git a/tests/ui/cfg/cfg-version/cfg-version-expand.rs b/tests/ui/cfg/cfg-version/cfg-version-expand.rs new file mode 100644 index 00000000000..8c426b4a41f --- /dev/null +++ b/tests/ui/cfg/cfg-version/cfg-version-expand.rs @@ -0,0 +1,30 @@ +//@ run-pass +//@ rustc-env:RUSTC_OVERRIDE_VERSION_STRING=1.50.3 + +#![feature(cfg_version)] + +#[cfg(version("1.49.0"))] +const ON_1_49_0: bool = true; +#[cfg(version("1.50"))] +const ON_1_50_0: bool = true; +#[cfg(not(version("1.51")))] +const ON_1_51_0: bool = false; + +// This one uses the wrong syntax, so doesn't eval to true +#[warn(unexpected_cfgs)] +#[cfg(not(version = "1.48.0"))] //~ WARN unexpected `cfg` condition name: `version` +const ON_1_48_0: bool = false; + +fn main() { + assert!(!ON_1_48_0); + assert!(ON_1_49_0); + assert!(ON_1_50_0); + assert!(!ON_1_51_0); + assert!(cfg!(version("1.1"))); + assert!(cfg!(version("1.49"))); + assert!(cfg!(version("1.50.0"))); + assert!(cfg!(version("1.50.3"))); + assert!(!cfg!(version("1.50.4"))); + assert!(!cfg!(version("1.51"))); + assert!(!cfg!(version("1.100"))); +} diff --git a/tests/ui/cfg/cfg-version/cfg-version-expand.stderr b/tests/ui/cfg/cfg-version/cfg-version-expand.stderr new file mode 100644 index 00000000000..a9a8d86c0fa --- /dev/null +++ b/tests/ui/cfg/cfg-version/cfg-version-expand.stderr @@ -0,0 +1,17 @@ +warning: unexpected `cfg` condition name: `version` + --> $DIR/cfg-version-expand.rs:15:11 + | +LL | #[cfg(not(version = "1.48.0"))] + | ^^^^^^^^^^^^^^^^^^ + | + = help: to expect this configuration use `--check-cfg=cfg(version, values("1.48.0"))` + = note: see <https://doc.rust-lang.org/nightly/rustc/check-cfg.html> for more information about checking conditional configuration + = note: `#[warn(unexpected_cfgs)]` on by default +help: there is a similar config predicate: `version("..")` + | +LL - #[cfg(not(version = "1.48.0"))] +LL + #[cfg(not(version("1.48.0")))] + | + +warning: 1 warning emitted + |
