| //! 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 |
| } |