Skip to content

Commit 4946828

Browse files
committed
Add future-incompatibility warning against some keyword-as-ident
1 parent ac10b55 commit 4946828

File tree

5 files changed

+71
-3
lines changed

5 files changed

+71
-3
lines changed

crates/cargo-platform/src/cfg.rs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,14 @@ enum Token<'a> {
3131
String(&'a str),
3232
}
3333

34+
/// The list of keywords.
35+
///
36+
/// We should consider all the keywords, but some are conditional on
37+
/// the edition so for now we just consider true/false.
38+
///
39+
/// <https://doc.rust-lang.org/reference/keywords.html>
40+
pub(crate) const KEYWORDS: &[&str; 2] = &["true", "false"];
41+
3442
#[derive(Clone)]
3543
struct Tokenizer<'a> {
3644
s: iter::Peekable<str::CharIndices<'a>>,

crates/cargo-platform/src/lib.rs

Lines changed: 42 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,12 +11,13 @@
1111
//!
1212
//! [`Platform`]: enum.Platform.html
1313
14-
use std::fmt;
1514
use std::str::FromStr;
15+
use std::{fmt, path::Path};
1616

1717
mod cfg;
1818
mod error;
1919

20+
use cfg::KEYWORDS;
2021
pub use cfg::{Cfg, CfgExpr};
2122
pub use error::{ParseError, ParseErrorKind};
2223

@@ -104,6 +105,46 @@ impl Platform {
104105
check_cfg_expr(cfg, warnings);
105106
}
106107
}
108+
109+
pub fn check_cfg_keywords(&self, warnings: &mut Vec<String>, path: &Path) {
110+
fn check_cfg_expr(expr: &CfgExpr, warnings: &mut Vec<String>, path: &Path) {
111+
match *expr {
112+
CfgExpr::Not(ref e) => check_cfg_expr(e, warnings, path),
113+
CfgExpr::All(ref e) | CfgExpr::Any(ref e) => {
114+
for e in e {
115+
check_cfg_expr(e, warnings, path);
116+
}
117+
}
118+
CfgExpr::Value(ref e) => match e {
119+
Cfg::Name(name) | Cfg::KeyPair(name, _) => {
120+
if KEYWORDS.contains(&name.as_str()) {
121+
if name.as_str() == "true" || name.as_str() == "false" {
122+
warnings.push(format!(
123+
"[{}] future-incompatibility: the meaning of `cfg({e})` will change in the future\n \
124+
| Cargo is erroneously allowing `cfg(true)` and `cfg(false)`, but both forms are interpreted as false unless manually overridden with `--cfg`.\n \
125+
| In the future these will be built-in defines that will have the corresponding true/false value.\n \
126+
| It is recommended to avoid using these configs until they are properly supported.\n \
127+
| See <https://github.com/rust-lang/rust/issues/131204> for more information.",
128+
path.display()
129+
));
130+
} else {
131+
warnings.push(format!(
132+
"[{}] future-incompatibility: `cfg({e})` is deprecated as `{name}` is a keyword \
133+
and not an identifier and should not have have been accepted in this position.\n \
134+
| this was previously accepted by Cargo but is being phased out; it will become a hard error in a future release!",
135+
path.display()
136+
));
137+
}
138+
}
139+
}
140+
},
141+
}
142+
}
143+
144+
if let Platform::Cfg(cfg) = self {
145+
check_cfg_expr(cfg, warnings, path);
146+
}
147+
}
107148
}
108149

109150
impl serde::Serialize for Platform {

src/cargo/util/context/target.rs

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ use crate::core::compiler::{BuildOutput, LinkArgTarget};
33
use crate::util::CargoResult;
44
use serde::Deserialize;
55
use std::collections::{BTreeMap, HashMap};
6-
use std::path::PathBuf;
6+
use std::path::{Path, PathBuf};
77
use std::rc::Rc;
88

99
/// Config definition of a `[target.'cfg(…)']` table.
@@ -53,6 +53,13 @@ pub(super) fn load_target_cfgs(
5353
let target: BTreeMap<String, TargetCfgConfig> = gctx.get("target")?;
5454
tracing::debug!("Got all targets {:#?}", target);
5555
for (key, cfg) in target {
56+
if let Ok(platform) = key.parse::<cargo_platform::Platform>() {
57+
let mut warnings = Vec::new();
58+
platform.check_cfg_keywords(&mut warnings, &Path::new(".cargo/config.toml"));
59+
for w in warnings {
60+
gctx.shell().warn(w)?;
61+
}
62+
}
5663
if key.starts_with("cfg(") {
5764
// Unfortunately this is not able to display the location of the
5865
// unused key. Using config::Value<toml::Value> doesn't work. One

src/cargo/util/toml/mod.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1314,6 +1314,7 @@ pub fn to_real_manifest(
13141314
for (name, platform) in original_toml.target.iter().flatten() {
13151315
let platform_kind: Platform = name.parse()?;
13161316
platform_kind.check_cfg_attributes(warnings);
1317+
platform_kind.check_cfg_keywords(warnings, manifest_file);
13171318
let platform_kind = Some(platform_kind);
13181319
validate_dependencies(
13191320
platform.dependencies.as_ref(),

tests/testsuite/cfg.rs

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -550,9 +550,20 @@ fn cfg_keywords() {
550550

551551
p.cargo("check")
552552
.with_stderr_data(str![[r#"
553+
[WARNING] [[ROOT]/foo/Cargo.toml] future-incompatibility: the meaning of `cfg(true)` will change in the future
554+
| Cargo is erroneously allowing `cfg(true)` and `cfg(false)`, but both forms are interpreted as false unless manually overridden with `--cfg`.
555+
| In the future these will be built-in defines that will have the corresponding true/false value.
556+
| It is recommended to avoid using these configs until they are properly supported.
557+
| See <https://github.com/rust-lang/rust/issues/131204> for more information.
558+
[WARNING] [.cargo/config.toml] future-incompatibility: the meaning of `cfg(false)` will change in the future
559+
| Cargo is erroneously allowing `cfg(true)` and `cfg(false)`, but both forms are interpreted as false unless manually overridden with `--cfg`.
560+
| In the future these will be built-in defines that will have the corresponding true/false value.
561+
| It is recommended to avoid using these configs until they are properly supported.
562+
| See <https://github.com/rust-lang/rust/issues/131204> for more information.
553563
[LOCKING] 1 package to latest compatible version
554564
[CHECKING] foo v0.1.0 ([ROOT]/foo)
555-
...
565+
[FINISHED] `dev` profile [unoptimized + debuginfo] target(s) in [ELAPSED]s
566+
556567
"#]])
557568
.run();
558569
}

0 commit comments

Comments
 (0)