Skip to content

Commit 6e86530

Browse files
committed
fix(manifest): Provide unused key warnings for lints table
The use of `flatten` was getting in the way of `serde_ignored`. A common workaround is to add our own `unused` tracking but that would cause duplicates with `workspace.lints` (or we'd just ignore it). Since the manual deserializer was relatively simple, I went that route. Fixes #12917
1 parent e37a04a commit 6e86530

File tree

2 files changed

+50
-13
lines changed

2 files changed

+50
-13
lines changed

crates/cargo-util-schemas/src/manifest.rs

Lines changed: 49 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -437,15 +437,6 @@ impl Default for TomlInheritedField {
437437
}
438438
}
439439

440-
fn bool_no_false<'de, D: de::Deserializer<'de>>(deserializer: D) -> Result<bool, D::Error> {
441-
let b: bool = Deserialize::deserialize(deserializer)?;
442-
if b {
443-
Ok(b)
444-
} else {
445-
Err(de::Error::custom("`workspace` cannot be false"))
446-
}
447-
}
448-
449440
#[derive(Deserialize, Serialize, Copy, Clone, Debug)]
450441
#[serde(try_from = "bool")]
451442
#[serde(into = "bool")]
@@ -1269,12 +1260,9 @@ impl TomlPlatform {
12691260
}
12701261
}
12711262

1272-
#[derive(Deserialize, Serialize, Debug, Clone)]
1273-
#[serde(expecting = "a lints table")]
1274-
#[serde(rename_all = "kebab-case")]
1263+
#[derive(Serialize, Debug, Clone)]
12751264
pub struct InheritableLints {
12761265
#[serde(skip_serializing_if = "is_false")]
1277-
#[serde(deserialize_with = "bool_no_false", default)]
12781266
pub workspace: bool,
12791267
#[serde(flatten)]
12801268
pub lints: TomlLints,
@@ -1284,6 +1272,54 @@ fn is_false(b: &bool) -> bool {
12841272
!b
12851273
}
12861274

1275+
impl<'de> Deserialize<'de> for InheritableLints {
1276+
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
1277+
where
1278+
D: de::Deserializer<'de>,
1279+
{
1280+
struct InheritableLintsVisitor;
1281+
1282+
impl<'de> de::Visitor<'de> for InheritableLintsVisitor {
1283+
// The type that our Visitor is going to produce.
1284+
type Value = InheritableLints;
1285+
1286+
// Format a message stating what data this Visitor expects to receive.
1287+
fn expecting(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
1288+
formatter.write_str("a lints table")
1289+
}
1290+
1291+
// Deserialize MyMap from an abstract "map" provided by the
1292+
// Deserializer. The MapAccess input is a callback provided by
1293+
// the Deserializer to let us see each entry in the map.
1294+
fn visit_map<M>(self, mut access: M) -> Result<Self::Value, M::Error>
1295+
where
1296+
M: de::MapAccess<'de>,
1297+
{
1298+
let mut lints = TomlLints::new();
1299+
let mut workspace = false;
1300+
1301+
// While there are entries remaining in the input, add them
1302+
// into our map.
1303+
while let Some(key) = access.next_key()? {
1304+
if key == "workspace" {
1305+
workspace = match access.next_value()? {
1306+
Some(WorkspaceValue) => true,
1307+
None => false,
1308+
};
1309+
} else {
1310+
let value = access.next_value()?;
1311+
lints.insert(key, value);
1312+
}
1313+
}
1314+
1315+
Ok(InheritableLints { workspace, lints })
1316+
}
1317+
}
1318+
1319+
deserializer.deserialize_map(InheritableLintsVisitor)
1320+
}
1321+
}
1322+
12871323
pub type TomlLints = BTreeMap<String, TomlToolLints>;
12881324

12891325
pub type TomlToolLints = BTreeMap<String, TomlLint>;

tests/testsuite/lints.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -170,6 +170,7 @@ fn warn_on_unused_key() {
170170
foo.cargo("check")
171171
.with_stderr(
172172
"\
173+
[WARNING] [CWD]/Cargo.toml: unused manifest key: lints.rust.rust-2018-idioms.unused
173174
[WARNING] [CWD]/Cargo.toml: unused manifest key: workspace.lints.rust.rust-2018-idioms.unused
174175
[CHECKING] foo v0.0.1 ([CWD])
175176
[FINISHED] dev [unoptimized + debuginfo] target(s) in [..]s

0 commit comments

Comments
 (0)