From b33f175d5509166e794216c097786815d5303074 Mon Sep 17 00:00:00 2001 From: Urgau Date: Fri, 4 Oct 2024 15:23:06 +0200 Subject: [PATCH] Add support for boolean literals in target cfgs --- crates/cargo-platform/src/cfg.rs | 12 +++- crates/cargo-platform/src/lib.rs | 31 +++------ crates/cargo-platform/tests/test_cfg.rs | 7 ++ tests/testsuite/cfg.rs | 88 ++----------------------- 4 files changed, 34 insertions(+), 104 deletions(-) diff --git a/crates/cargo-platform/src/cfg.rs b/crates/cargo-platform/src/cfg.rs index 79aaa02c23f..5928e4c2d6c 100644 --- a/crates/cargo-platform/src/cfg.rs +++ b/crates/cargo-platform/src/cfg.rs @@ -11,6 +11,8 @@ pub enum CfgExpr { All(Vec), Any(Vec), Value(Cfg), + True, + False, } /// A cfg value. @@ -147,6 +149,8 @@ impl CfgExpr { CfgExpr::All(ref e) => e.iter().all(|e| e.matches(cfg)), CfgExpr::Any(ref e) => e.iter().any(|e| e.matches(cfg)), CfgExpr::Value(ref e) => cfg.contains(e), + CfgExpr::True => true, + CfgExpr::False => false, } } } @@ -174,6 +178,8 @@ impl fmt::Display for CfgExpr { CfgExpr::All(ref e) => write!(f, "all({})", CommaSep(e)), CfgExpr::Any(ref e) => write!(f, "any({})", CommaSep(e)), CfgExpr::Value(ref e) => write!(f, "{}", e), + CfgExpr::True => write!(f, "true"), + CfgExpr::False => write!(f, "false"), } } } @@ -229,7 +235,11 @@ impl<'a> Parser<'a> { self.eat(&Token::RightParen)?; Ok(CfgExpr::Not(Box::new(e))) } - Some(Ok(..)) => self.cfg().map(CfgExpr::Value), + Some(Ok(..)) => self.cfg().map(|v| match v { + Cfg::Name(n) if n == "true" => CfgExpr::True, + Cfg::Name(n) if n == "false" => CfgExpr::False, + v => CfgExpr::Value(v), + }), Some(Err(..)) => Err(self.t.next().unwrap().err().unwrap()), None => Err(ParseError::new( self.t.orig, diff --git a/crates/cargo-platform/src/lib.rs b/crates/cargo-platform/src/lib.rs index f91b61708bb..96b2485775a 100644 --- a/crates/cargo-platform/src/lib.rs +++ b/crates/cargo-platform/src/lib.rs @@ -98,6 +98,7 @@ impl Platform { )) }, } + CfgExpr::True | CfgExpr::False => {}, } } @@ -115,30 +116,18 @@ impl Platform { check_cfg_expr(e, warnings, path); } } + CfgExpr::True | CfgExpr::False => {} CfgExpr::Value(ref e) => match e { Cfg::Name(name) | Cfg::KeyPair(name, _) => { if !name.raw && KEYWORDS.contains(&name.as_str()) { - if name.as_str() == "true" || name.as_str() == "false" { - warnings.push(format!( - "[{}] future-incompatibility: the meaning of `cfg({e})` will change in the future\n \ - | Cargo is erroneously allowing `cfg(true)` and `cfg(false)`, but both forms are interpreted as false unless manually overridden with `--cfg`.\n \ - | In the future these will be built-in defines that will have the corresponding true/false value.\n \ - | It is recommended to avoid using these configs until they are properly supported.\n \ - | See for more information.\n \ - |\n \ - | help: use raw-idents instead: `cfg(r#{name})`", - path.display() - )); - } else { - warnings.push(format!( - "[{}] future-incompatibility: `cfg({e})` is deprecated as `{name}` is a keyword \ - and not an identifier and should not have have been accepted in this position.\n \ - | this was previously accepted by Cargo but is being phased out; it will become a hard error in a future release!\n \ - |\n \ - | help: use raw-idents instead: `cfg(r#{name})`", - path.display() - )); - } + warnings.push(format!( + "[{}] future-incompatibility: `cfg({e})` is deprecated as `{name}` is a keyword \ + and not an identifier and should not have have been accepted in this position.\n \ + | this was previously accepted by Cargo but is being phased out; it will become a hard error in a future release!\n \ + |\n \ + | help: use raw-idents instead: `cfg(r#{name})`", + path.display() + )); } } }, diff --git a/crates/cargo-platform/tests/test_cfg.rs b/crates/cargo-platform/tests/test_cfg.rs index 0fdf307fab7..59cb27d54f4 100644 --- a/crates/cargo-platform/tests/test_cfg.rs +++ b/crates/cargo-platform/tests/test_cfg.rs @@ -39,6 +39,8 @@ macro_rules! e { (any($($t:tt),*)) => (CfgExpr::Any(vec![$(e!($t)),*])); (all($($t:tt),*)) => (CfgExpr::All(vec![$(e!($t)),*])); (not($($t:tt)*)) => (CfgExpr::Not(Box::new(e!($($t)*)))); + (true) => (CfgExpr::True); + (false) => (CfgExpr::False); (($($t:tt)*)) => (e!($($t)*)); ($($t:tt)*) => (CfgExpr::Value(c!($($t)*))); } @@ -122,6 +124,9 @@ fn cfg_expr() { good(" foo=\"3\" ", e!(foo = "3")); good("foo = \"3 e\"", e!(foo = "3 e")); + good("true", e!(true)); + good("false", e!(false)); + good("all()", e!(all())); good("all(a)", e!(all(a))); good("all(a, b)", e!(all(a, b))); @@ -249,6 +254,8 @@ fn check_cfg_attributes() { ok("windows"); ok("any(not(unix), windows)"); ok("foo"); + ok("true"); + ok("false"); ok("target_arch = \"abc\""); ok("target_feature = \"abc\""); diff --git a/tests/testsuite/cfg.rs b/tests/testsuite/cfg.rs index 7dc875bf157..cac36f92621 100644 --- a/tests/testsuite/cfg.rs +++ b/tests/testsuite/cfg.rs @@ -545,6 +545,7 @@ fn cfg_raw_idents() { p.cargo("check") .with_stderr_data(str![[r#" [LOCKING] 1 package to latest compatible version +[CHECKING] b v0.0.1 ([ROOT]/foo/b) [CHECKING] foo v0.1.0 ([ROOT]/foo) [FINISHED] `dev` profile [unoptimized + debuginfo] target(s) in [ELAPSED]s @@ -638,21 +639,8 @@ fn cfg_keywords() { p.cargo("check") .with_stderr_data(str![[r#" -[WARNING] [[ROOT]/foo/Cargo.toml] future-incompatibility: the meaning of `cfg(true)` will change in the future - | Cargo is erroneously allowing `cfg(true)` and `cfg(false)`, but both forms are interpreted as false unless manually overridden with `--cfg`. - | In the future these will be built-in defines that will have the corresponding true/false value. - | It is recommended to avoid using these configs until they are properly supported. - | See for more information. - | - | [HELP] use raw-idents instead: `cfg(r#true)` -[WARNING] [.cargo/config.toml] future-incompatibility: the meaning of `cfg(false)` will change in the future - | Cargo is erroneously allowing `cfg(true)` and `cfg(false)`, but both forms are interpreted as false unless manually overridden with `--cfg`. - | In the future these will be built-in defines that will have the corresponding true/false value. - | It is recommended to avoid using these configs until they are properly supported. - | See for more information. - | - | [HELP] use raw-idents instead: `cfg(r#false)` [LOCKING] 1 package to latest compatible version +[CHECKING] b v0.0.1 ([ROOT]/foo/b) [CHECKING] foo v0.1.0 ([ROOT]/foo) [FINISHED] `dev` profile [unoptimized + debuginfo] target(s) in [ELAPSED]s @@ -687,23 +675,10 @@ fn cfg_booleans() { .build(); p.cargo("check") - // FIXME: `b` should be compiled + .masquerade_as_nightly_cargo(&["cfg-boolean-literals feature"]) .with_stderr_data(str![[r#" -[WARNING] [[ROOT]/foo/Cargo.toml] future-incompatibility: the meaning of `cfg(false)` will change in the future - | Cargo is erroneously allowing `cfg(true)` and `cfg(false)`, but both forms are interpreted as false unless manually overridden with `--cfg`. - | In the future these will be built-in defines that will have the corresponding true/false value. - | It is recommended to avoid using these configs until they are properly supported. - | See for more information. - | - | [HELP] use raw-idents instead: `cfg(r#false)` -[WARNING] [[ROOT]/foo/Cargo.toml] future-incompatibility: the meaning of `cfg(true)` will change in the future - | Cargo is erroneously allowing `cfg(true)` and `cfg(false)`, but both forms are interpreted as false unless manually overridden with `--cfg`. - | In the future these will be built-in defines that will have the corresponding true/false value. - | It is recommended to avoid using these configs until they are properly supported. - | See for more information. - | - | [HELP] use raw-idents instead: `cfg(r#true)` [LOCKING] 2 packages to latest compatible versions +[CHECKING] b v0.0.1 ([ROOT]/foo/b) [CHECKING] a v0.0.1 ([ROOT]/foo) [FINISHED] `dev` profile [unoptimized + debuginfo] target(s) in [ELAPSED]s @@ -735,13 +710,6 @@ fn cfg_booleans_config() { p.cargo("check") .with_stderr_data(str![[r#" -[WARNING] [.cargo/config.toml] future-incompatibility: the meaning of `cfg(true)` will change in the future - | Cargo is erroneously allowing `cfg(true)` and `cfg(false)`, but both forms are interpreted as false unless manually overridden with `--cfg`. - | In the future these will be built-in defines that will have the corresponding true/false value. - | It is recommended to avoid using these configs until they are properly supported. - | See for more information. - | - | [HELP] use raw-idents instead: `cfg(r#true)` [CHECKING] a v0.0.1 ([ROOT]/foo) [FINISHED] `dev` profile [unoptimized + debuginfo] target(s) in [ELAPSED]s @@ -772,13 +740,6 @@ fn cfg_booleans_not() { p.cargo("check") .with_stderr_data(str![[r#" -[WARNING] [[ROOT]/foo/Cargo.toml] future-incompatibility: the meaning of `cfg(false)` will change in the future - | Cargo is erroneously allowing `cfg(true)` and `cfg(false)`, but both forms are interpreted as false unless manually overridden with `--cfg`. - | In the future these will be built-in defines that will have the corresponding true/false value. - | It is recommended to avoid using these configs until they are properly supported. - | See for more information. - | - | [HELP] use raw-idents instead: `cfg(r#false)` [LOCKING] 1 package to latest compatible version [CHECKING] b v0.0.1 ([ROOT]/foo/b) [CHECKING] a v0.0.1 ([ROOT]/foo) @@ -810,30 +771,9 @@ fn cfg_booleans_combinators() { .build(); p.cargo("check") - // FIXME: `b` should be compiled .with_stderr_data(str![[r#" -[WARNING] [[ROOT]/foo/Cargo.toml] future-incompatibility: the meaning of `cfg(true)` will change in the future - | Cargo is erroneously allowing `cfg(true)` and `cfg(false)`, but both forms are interpreted as false unless manually overridden with `--cfg`. - | In the future these will be built-in defines that will have the corresponding true/false value. - | It is recommended to avoid using these configs until they are properly supported. - | See for more information. - | - | [HELP] use raw-idents instead: `cfg(r#true)` -[WARNING] [[ROOT]/foo/Cargo.toml] future-incompatibility: the meaning of `cfg(false)` will change in the future - | Cargo is erroneously allowing `cfg(true)` and `cfg(false)`, but both forms are interpreted as false unless manually overridden with `--cfg`. - | In the future these will be built-in defines that will have the corresponding true/false value. - | It is recommended to avoid using these configs until they are properly supported. - | See for more information. - | - | [HELP] use raw-idents instead: `cfg(r#false)` -[WARNING] [[ROOT]/foo/Cargo.toml] future-incompatibility: the meaning of `cfg(true)` will change in the future - | Cargo is erroneously allowing `cfg(true)` and `cfg(false)`, but both forms are interpreted as false unless manually overridden with `--cfg`. - | In the future these will be built-in defines that will have the corresponding true/false value. - | It is recommended to avoid using these configs until they are properly supported. - | See for more information. - | - | [HELP] use raw-idents instead: `cfg(r#true)` [LOCKING] 1 package to latest compatible version +[CHECKING] b v0.0.1 ([ROOT]/foo/b) [CHECKING] a v0.0.1 ([ROOT]/foo) [FINISHED] `dev` profile [unoptimized + debuginfo] target(s) in [ELAPSED]s @@ -868,29 +808,13 @@ fn cfg_booleans_rustflags_no_effect() { .build(); p.cargo("check") - // FIXME: only `b` should be compiled, the rustflags don't take effect .with_stderr_data(str![[r#" -[WARNING] [[ROOT]/foo/Cargo.toml] future-incompatibility: the meaning of `cfg(false)` will change in the future - | Cargo is erroneously allowing `cfg(true)` and `cfg(false)`, but both forms are interpreted as false unless manually overridden with `--cfg`. - | In the future these will be built-in defines that will have the corresponding true/false value. - | It is recommended to avoid using these configs until they are properly supported. - | See for more information. - | - | [HELP] use raw-idents instead: `cfg(r#false)` -[WARNING] [[ROOT]/foo/Cargo.toml] future-incompatibility: the meaning of `cfg(true)` will change in the future - | Cargo is erroneously allowing `cfg(true)` and `cfg(false)`, but both forms are interpreted as false unless manually overridden with `--cfg`. - | In the future these will be built-in defines that will have the corresponding true/false value. - | It is recommended to avoid using these configs until they are properly supported. - | See for more information. - | - | [HELP] use raw-idents instead: `cfg(r#true)` [LOCKING] 2 packages to latest compatible versions [CHECKING] b v0.0.1 ([ROOT]/foo/b) -[CHECKING] c v0.0.1 ([ROOT]/foo/c) [CHECKING] a v0.0.1 ([ROOT]/foo) [FINISHED] `dev` profile [unoptimized + debuginfo] target(s) in [ELAPSED]s "#]]) - .env("RUSTFLAGS", "--cfg true --cfg false") + .env("RUSTFLAGS", "--cfg false") .run(); }