Skip to content

Pull out dedicated cfg_version syntax test from feature gate test #141552

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
May 27, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
152 changes: 152 additions & 0 deletions tests/ui/cfg/cfg-version/syntax.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,152 @@
//! Check `#[cfg(version(..))]` parsing.

#![feature(cfg_version)]

// Overall grammar
// ===============
//
// `#[cfg(version(..))]` accepts only the `version(VERSION_STRING_LITERAL)` predicate form, where
// only a single string literal is permitted.

#[cfg(version(42))]
//~^ ERROR expected a version literal
fn not_a_string_literal_simple() {}

#[cfg(version(1.20))]
//~^ ERROR expected a version literal
fn not_a_string_literal_semver_like() {}

#[cfg(version(false))]
//~^ ERROR expected a version literal
fn not_a_string_literal_other() {}

#[cfg(version("1.43", "1.44", "1.45"))]
//~^ ERROR expected single version literal
fn multiple_version_literals() {}

// The key-value form `cfg(version = "..")` is not considered a valid `cfg(version(..))` usage, but
// it will only trigger the `unexpected_cfgs` lint and not a hard error.

#[cfg(version = "1.43")]
//~^ WARN unexpected `cfg` condition name: `version`
fn key_value_form() {}

// Additional version string literal constraints
// =============================================
//
// The `VERSION_STRING_LITERAL` ("version literal") has additional constraints on its syntactical
// well-formedness.

// 1. A valid version literal can only constitute of numbers and periods (a "simple" semver version
// string). Non-semver strings or "complex" semver strings (such as build metadata) are not
// considered valid version literals, and will emit a non-lint warning "unknown version literal
// format".

#[cfg(version("1.43.0"))]
fn valid_major_minor_patch() {}

#[cfg(version("0.0.0"))]
fn valid_zero_zero_zero_major_minor_patch() {}

#[cfg(version("foo"))]
//~^ WARN unknown version literal format, assuming it refers to a future version
fn not_numbers_or_periods() {}

#[cfg(version("1.20.0-stable"))]
//~^ WARN unknown version literal format, assuming it refers to a future version
fn complex_semver_with_metadata() {}

// 2. "Shortened" version strings are permitted but *only* for the omission of the patch number.

#[cfg(version("1.0"))]
fn valid_major_minor_1() {}

#[cfg(version("1.43"))]
fn valid_major_minor_2() {}

#[cfg(not(version("1.44")))]
fn valid_major_minor_negated_smoke_test() {}

#[cfg(version("0.0"))]
fn valid_zero_zero_major_minor() {}

#[cfg(version("0.7"))]
fn valid_zero_major_minor() {}

// 3. Major-only, or other non-Semver-like strings are not permitted.

#[cfg(version("1"))]
//~^ WARN unknown version literal format, assuming it refers to a future version
fn invalid_major_only() {}

#[cfg(version("0"))]
//~^ WARN unknown version literal format, assuming it refers to a future version
fn invalid_major_only_zero() {}

#[cfg(version(".7"))]
//~^ WARN unknown version literal format, assuming it refers to a future version
fn invalid_decimal_like() {}

// Misc parsing overflow/underflow edge cases
// ==========================================
//
// Check that we report "unknown version literal format" user-facing warnings and not ICEs.

#[cfg(version("-1"))]
//~^ WARN unknown version literal format, assuming it refers to a future version
fn invalid_major_only_negative() {}

// Implementation detail: we store rustc version as `{ major: u16, minor: u16, patch: u16 }`.

#[cfg(version("65536"))]
//~^ WARN unknown version literal format, assuming it refers to a future version
fn exceed_u16_major() {}

#[cfg(version("1.65536.0"))]
//~^ WARN unknown version literal format, assuming it refers to a future version
fn exceed_u16_minor() {}

#[cfg(version("1.0.65536"))]
//~^ WARN unknown version literal format, assuming it refers to a future version
fn exceed_u16_patch() {}

#[cfg(version("65536.0.65536"))]
//~^ WARN unknown version literal format, assuming it refers to a future version
fn exceed_u16_mixed() {}

// Usage as `cfg!()`
// =================

fn cfg_usage() {
assert!(cfg!(version("1.0")));
assert!(cfg!(version("1.43")));
assert!(cfg!(version("1.43.0")));

assert!(cfg!(version("foo")));
//~^ WARN unknown version literal format, assuming it refers to a future version
assert!(cfg!(version("1.20.0-stable")));
//~^ WARN unknown version literal format, assuming it refers to a future version

assert!(cfg!(version = "1.43"));
//~^ WARN unexpected `cfg` condition name: `version`
}

fn main() {
cfg_usage();

// `cfg(version = "..")` is not a valid `cfg_version` form, but it only triggers
// `unexpected_cfgs` lint, and `cfg(version = "..")` eval to `false`.
key_value_form(); //~ ERROR cannot find function

// Invalid version literal formats within valid `cfg(version(..))` form should also cause
// `cfg(version(..))` eval to `false`.
not_numbers_or_periods(); //~ ERROR cannot find function
complex_semver_with_metadata(); //~ ERROR cannot find function
invalid_major_only(); //~ ERROR cannot find function
invalid_major_only_zero(); //~ ERROR cannot find function
invalid_major_only_negative(); //~ ERROR cannot find function
exceed_u16_major(); //~ ERROR cannot find function
exceed_u16_minor(); //~ ERROR cannot find function
exceed_u16_patch(); //~ ERROR cannot find function
exceed_u16_mixed(); //~ ERROR cannot find function
}
188 changes: 188 additions & 0 deletions tests/ui/cfg/cfg-version/syntax.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,188 @@
error: expected a version literal
--> $DIR/syntax.rs:11:15
|
LL | #[cfg(version(42))]
| ^^

error: expected a version literal
--> $DIR/syntax.rs:15:15
|
LL | #[cfg(version(1.20))]
| ^^^^

error: expected a version literal
--> $DIR/syntax.rs:19:15
|
LL | #[cfg(version(false))]
| ^^^^^

error: expected single version literal
--> $DIR/syntax.rs:23:7
|
LL | #[cfg(version("1.43", "1.44", "1.45"))]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

warning: unknown version literal format, assuming it refers to a future version
--> $DIR/syntax.rs:51:15
|
LL | #[cfg(version("foo"))]
| ^^^^^

warning: unknown version literal format, assuming it refers to a future version
--> $DIR/syntax.rs:55:15
|
LL | #[cfg(version("1.20.0-stable"))]
| ^^^^^^^^^^^^^^^

warning: unknown version literal format, assuming it refers to a future version
--> $DIR/syntax.rs:78:15
|
LL | #[cfg(version("1"))]
| ^^^

warning: unknown version literal format, assuming it refers to a future version
--> $DIR/syntax.rs:82:15
|
LL | #[cfg(version("0"))]
| ^^^

warning: unknown version literal format, assuming it refers to a future version
--> $DIR/syntax.rs:86:15
|
LL | #[cfg(version(".7"))]
| ^^^^

warning: unknown version literal format, assuming it refers to a future version
--> $DIR/syntax.rs:95:15
|
LL | #[cfg(version("-1"))]
| ^^^^

warning: unknown version literal format, assuming it refers to a future version
--> $DIR/syntax.rs:101:15
|
LL | #[cfg(version("65536"))]
| ^^^^^^^

warning: unknown version literal format, assuming it refers to a future version
--> $DIR/syntax.rs:105:15
|
LL | #[cfg(version("1.65536.0"))]
| ^^^^^^^^^^^

warning: unknown version literal format, assuming it refers to a future version
--> $DIR/syntax.rs:109:15
|
LL | #[cfg(version("1.0.65536"))]
| ^^^^^^^^^^^

warning: unknown version literal format, assuming it refers to a future version
--> $DIR/syntax.rs:113:15
|
LL | #[cfg(version("65536.0.65536"))]
| ^^^^^^^^^^^^^^^

warning: unknown version literal format, assuming it refers to a future version
--> $DIR/syntax.rs:125:26
|
LL | assert!(cfg!(version("foo")));
| ^^^^^

warning: unknown version literal format, assuming it refers to a future version
--> $DIR/syntax.rs:127:26
|
LL | assert!(cfg!(version("1.20.0-stable")));
| ^^^^^^^^^^^^^^^

warning: unexpected `cfg` condition name: `version`
--> $DIR/syntax.rs:30:7
|
LL | #[cfg(version = "1.43")]
| ^^^^^^^^^^^^^^^^
|
= help: to expect this configuration use `--check-cfg=cfg(version, values("1.43"))`
= 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(version = "1.43")]
LL + #[cfg(version("1.43"))]
|

warning: unexpected `cfg` condition name: `version`
--> $DIR/syntax.rs:130:18
|
LL | assert!(cfg!(version = "1.43"));
| ^^^^^^^^^^^^^^^^
|
= help: to expect this configuration use `--check-cfg=cfg(version, values("1.43"))`
= note: see <https://doc.rust-lang.org/nightly/rustc/check-cfg.html> for more information about checking conditional configuration
help: there is a similar config predicate: `version("..")`
|
LL - assert!(cfg!(version = "1.43"));
LL + assert!(cfg!(version("1.43")));
|

error[E0425]: cannot find function `key_value_form` in this scope
--> $DIR/syntax.rs:139:5
|
LL | key_value_form();
| ^^^^^^^^^^^^^^ not found in this scope

error[E0425]: cannot find function `not_numbers_or_periods` in this scope
--> $DIR/syntax.rs:143:5
|
LL | not_numbers_or_periods();
| ^^^^^^^^^^^^^^^^^^^^^^ not found in this scope

error[E0425]: cannot find function `complex_semver_with_metadata` in this scope
--> $DIR/syntax.rs:144:5
|
LL | complex_semver_with_metadata();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ not found in this scope

error[E0425]: cannot find function `invalid_major_only` in this scope
--> $DIR/syntax.rs:145:5
|
LL | invalid_major_only();
| ^^^^^^^^^^^^^^^^^^ not found in this scope

error[E0425]: cannot find function `invalid_major_only_zero` in this scope
--> $DIR/syntax.rs:146:5
|
LL | invalid_major_only_zero();
| ^^^^^^^^^^^^^^^^^^^^^^^ not found in this scope

error[E0425]: cannot find function `invalid_major_only_negative` in this scope
--> $DIR/syntax.rs:147:5
|
LL | invalid_major_only_negative();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^ not found in this scope

error[E0425]: cannot find function `exceed_u16_major` in this scope
--> $DIR/syntax.rs:148:5
|
LL | exceed_u16_major();
| ^^^^^^^^^^^^^^^^ not found in this scope

error[E0425]: cannot find function `exceed_u16_minor` in this scope
--> $DIR/syntax.rs:149:5
|
LL | exceed_u16_minor();
| ^^^^^^^^^^^^^^^^ not found in this scope

error[E0425]: cannot find function `exceed_u16_patch` in this scope
--> $DIR/syntax.rs:150:5
|
LL | exceed_u16_patch();
| ^^^^^^^^^^^^^^^^ not found in this scope

error[E0425]: cannot find function `exceed_u16_mixed` in this scope
--> $DIR/syntax.rs:151:5
|
LL | exceed_u16_mixed();
| ^^^^^^^^^^^^^^^^ not found in this scope

error: aborting due to 14 previous errors; 14 warnings emitted

For more information about this error, try `rustc --explain E0425`.
49 changes: 6 additions & 43 deletions tests/ui/feature-gates/feature-gate-cfg-version.rs
Original file line number Diff line number Diff line change
@@ -1,49 +1,12 @@
#[cfg(version(42))] //~ ERROR: expected a version literal
//~^ ERROR `cfg(version)` is experimental and subject to change
fn foo() {}
#[cfg(version(1.20))] //~ ERROR: expected a version literal
//~^ ERROR `cfg(version)` is experimental and subject to change
fn foo() -> bool { true }
#[cfg(version("1.44"))]
//~^ ERROR `cfg(version)` is experimental and subject to change
fn foo() -> bool { true }
#[cfg(not(version("1.44")))]
//~^ ERROR `cfg(version)` is experimental and subject to change
fn foo() -> bool { false }
//! Feature gate test for `cfg_version`.
//!
//! Tracking issue: #64796.

#[cfg(version("1.43", "1.44", "1.45"))] //~ ERROR: expected single version literal
//~^ ERROR `cfg(version)` is experimental and subject to change
fn bar() -> bool { false }
#[cfg(version(false))] //~ ERROR: expected a version literal
//~^ ERROR `cfg(version)` is experimental and subject to change
fn bar() -> bool { false }
#[cfg(version("foo"))] //~ WARNING: unknown version literal format
//~^ ERROR `cfg(version)` is experimental and subject to change
fn bar() -> bool { false }
#[cfg(version("999"))] //~ WARNING: unknown version literal format
//~^ ERROR `cfg(version)` is experimental and subject to change
fn bar() -> bool { false }
#[cfg(version("-1"))] //~ WARNING: unknown version literal format
//~^ ERROR `cfg(version)` is experimental and subject to change
fn bar() -> bool { false }
#[cfg(version("65536"))] //~ WARNING: unknown version literal format
//~^ ERROR `cfg(version)` is experimental and subject to change
fn bar() -> bool { false }
#[cfg(version("0"))] //~ WARNING: unknown version literal format
//~^ ERROR `cfg(version)` is experimental and subject to change
fn bar() -> bool { true }
#[cfg(version("1.0"))]
//~^ ERROR `cfg(version)` is experimental and subject to change
fn bar() -> bool { true }
#[cfg(version("1.65536.2"))] //~ WARNING: unknown version literal format
//~^ ERROR `cfg(version)` is experimental and subject to change
fn bar() -> bool { false }
#[cfg(version("1.20.0-stable"))] //~ WARNING: unknown version literal format
#[cfg(version("1.42"))]
//~^ ERROR `cfg(version)` is experimental and subject to change
fn bar() {}

fn main() {
assert!(foo());
assert!(bar());
assert!(cfg!(version("1.42"))); //~ ERROR `cfg(version)` is experimental and subject to change
assert!(cfg!(version("1.42")));
//~^ ERROR `cfg(version)` is experimental and subject to change
}
Loading
Loading