blob: 22aab47e1ecdf7bc8e785db1f5662f54f30b8ba1 [file] [log] [blame]
//! 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
}