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
This commit is contained in:
commit
b0ae228007
4 changed files with 71 additions and 2 deletions
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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) => {
|
||||
|
|
|
|||
30
tests/ui/cfg/cfg-version/cfg-version-expand.rs
Normal file
30
tests/ui/cfg/cfg-version/cfg-version-expand.rs
Normal file
|
|
@ -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")));
|
||||
}
|
||||
17
tests/ui/cfg/cfg-version/cfg-version-expand.stderr
Normal file
17
tests/ui/cfg/cfg-version/cfg-version-expand.stderr
Normal file
|
|
@ -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
|
||||
|
||||
Loading…
Add table
Add a link
Reference in a new issue