Skip to content

Commit ff454fd

Browse files
committed
refactor(toml): Consolidate how we track unused keys
This makes it act more like everything else, making this easier to evolve over time.
1 parent 7143592 commit ff454fd

File tree

5 files changed

+29
-19
lines changed

5 files changed

+29
-19
lines changed

Cargo.lock

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ cargo-platform = { path = "crates/cargo-platform", version = "0.1.5" }
3333
cargo-test-macro = { path = "crates/cargo-test-macro" }
3434
cargo-test-support = { path = "crates/cargo-test-support" }
3535
cargo-util = { version = "0.2.9", path = "crates/cargo-util" }
36-
cargo-util-schemas = { version = "0.2.1", path = "crates/cargo-util-schemas" }
36+
cargo-util-schemas = { version = "0.3.0", path = "crates/cargo-util-schemas" }
3737
cargo_metadata = "0.18.1"
3838
clap = "4.5.1"
3939
color-print = "0.3.5"

crates/cargo-util-schemas/Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[package]
22
name = "cargo-util-schemas"
3-
version = "0.2.1"
3+
version = "0.3.0"
44
rust-version = "1.76.0" # MSRV:1
55
edition.workspace = true
66
license.workspace = true

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

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
//! - Keys that exist for bookkeeping but don't correspond to the schema have a `_` prefix
77
88
use std::collections::BTreeMap;
9+
use std::collections::BTreeSet;
910
use std::fmt::{self, Display, Write};
1011
use std::path::PathBuf;
1112
use std::str;
@@ -28,6 +29,7 @@ pub use rust_version::RustVersionError;
2829
#[derive(Debug, Deserialize, Serialize)]
2930
#[serde(rename_all = "kebab-case")]
3031
pub struct TomlManifest {
32+
// when adding new fields, be sure to check whether `requires_package` should disallow them
3133
pub cargo_features: Option<Vec<String>>,
3234
pub package: Option<Box<TomlPackage>>,
3335
pub project: Option<Box<TomlPackage>>,
@@ -51,7 +53,11 @@ pub struct TomlManifest {
5153
pub workspace: Option<TomlWorkspace>,
5254
pub badges: Option<InheritableBtreeMap>,
5355
pub lints: Option<InheritableLints>,
54-
// when adding new fields, be sure to check whether `requires_package` should disallow them
56+
57+
/// Report unused keys (see also nested `_unused_keys`)
58+
/// Note: this is populated by the caller, rather than automatically
59+
#[serde(skip)]
60+
pub _unused_keys: BTreeSet<String>,
5561
}
5662

5763
impl TomlManifest {

src/cargo/util/toml/mod.rs

Lines changed: 19 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ use url::Url;
1818

1919
use crate::core::compiler::{CompileKind, CompileTarget};
2020
use crate::core::dependency::{Artifact, ArtifactTarget, DepKind};
21-
use crate::core::manifest::{ManifestMetadata, TargetSourcePath, Warnings};
21+
use crate::core::manifest::{ManifestMetadata, TargetSourcePath};
2222
use crate::core::resolver::ResolveBehavior;
2323
use crate::core::{find_workspace_root, resolve_relative_path, CliUnstable, FeatureValue};
2424
use crate::core::{Dependency, Manifest, PackageId, Summary, Target};
@@ -52,11 +52,10 @@ pub fn read_manifest(
5252
read_toml_string(path, gctx).map_err(|err| ManifestError::new(err, path.into()))?;
5353
let document =
5454
parse_document(&contents).map_err(|e| emit_diagnostic(e.into(), &contents, path, gctx))?;
55-
let mut unused = BTreeSet::new();
56-
let toml = deserialize_toml(&document, &mut unused)
55+
let toml = deserialize_toml(&document)
5756
.map_err(|e| emit_diagnostic(e.into(), &contents, path, gctx))?;
5857

59-
convert_toml(toml, unused, path, source_id, gctx).map_err(|err| {
58+
convert_toml(toml, path, source_id, gctx).map_err(|err| {
6059
ManifestError::new(
6160
err.context(format!("failed to parse manifest at `{}`", path.display())),
6261
path.into(),
@@ -85,14 +84,16 @@ fn parse_document(contents: &str) -> Result<toml_edit::ImDocument<String>, toml_
8584
#[tracing::instrument(skip_all)]
8685
fn deserialize_toml(
8786
document: &toml_edit::ImDocument<String>,
88-
unused: &mut BTreeSet<String>,
8987
) -> Result<manifest::TomlManifest, toml_edit::de::Error> {
88+
let mut unused = BTreeSet::new();
9089
let deserializer = toml_edit::de::Deserializer::from(document.clone());
91-
serde_ignored::deserialize(deserializer, |path| {
90+
let mut document: manifest::TomlManifest = serde_ignored::deserialize(deserializer, |path| {
9291
let mut key = String::new();
9392
stringify(&mut key, &path);
9493
unused.insert(key);
95-
})
94+
})?;
95+
document._unused_keys = unused;
96+
Ok(document)
9697
}
9798

9899
/// See also `bin/cargo/commands/run.rs`s `is_manifest_command`
@@ -170,7 +171,6 @@ fn emit_diagnostic(
170171
#[tracing::instrument(skip_all)]
171172
fn convert_toml(
172173
manifest: manifest::TomlManifest,
173-
unused: BTreeSet<String>,
174174
manifest_file: &Path,
175175
source_id: SourceId,
176176
gctx: &GlobalContext,
@@ -193,13 +193,11 @@ fn convert_toml(
193193
}
194194
return if manifest.package().is_some() {
195195
let embedded = is_embedded(manifest_file);
196-
let (mut manifest, paths) =
196+
let (manifest, paths) =
197197
to_real_manifest(manifest, embedded, source_id, package_root, gctx)?;
198-
warn_on_unused(&unused, manifest.warnings_mut());
199198
Ok((EitherManifest::Real(manifest), paths))
200199
} else {
201-
let (mut m, paths) = to_virtual_manifest(manifest, source_id, package_root, gctx)?;
202-
warn_on_unused(&unused, m.warnings_mut());
200+
let (m, paths) = to_virtual_manifest(manifest, source_id, package_root, gctx)?;
203201
Ok((EitherManifest::Virtual(m), paths))
204202
};
205203
}
@@ -238,11 +236,11 @@ fn warn_on_deprecated(new_path: &str, name: &str, kind: &str, warnings: &mut Vec
238236
))
239237
}
240238

241-
fn warn_on_unused(unused: &BTreeSet<String>, warnings: &mut Warnings) {
239+
fn warn_on_unused(unused: &BTreeSet<String>, warnings: &mut Vec<String>) {
242240
for key in unused {
243-
warnings.add_warning(format!("unused manifest key: {}", key));
241+
warnings.push(format!("unused manifest key: {}", key));
244242
if key == "profiles.debug" {
245-
warnings.add_warning("use `[profile.dev]` to configure debug builds".to_string());
243+
warnings.push("use `[profile.dev]` to configure debug builds".to_string());
246244
}
247245
}
248246
}
@@ -375,6 +373,7 @@ pub fn prepare_for_publish(
375373
badges: me.badges.clone(),
376374
cargo_features: me.cargo_features.clone(),
377375
lints: me.lints.clone(),
376+
_unused_keys: Default::default(),
378377
};
379378
strip_features(&mut manifest);
380379
return Ok(manifest);
@@ -523,6 +522,8 @@ pub fn to_real_manifest(
523522
let mut warnings = vec![];
524523
let mut errors = vec![];
525524

525+
warn_on_unused(&me._unused_keys, &mut warnings);
526+
526527
// Parse features first so they will be available when parsing other parts of the TOML.
527528
let empty = Vec::new();
528529
let cargo_features = me.cargo_features.as_ref().unwrap_or(&empty);
@@ -1225,6 +1226,7 @@ pub fn to_real_manifest(
12251226
workspace: false,
12261227
lints,
12271228
}),
1229+
_unused_keys: Default::default(),
12281230
};
12291231
let mut manifest = Manifest::new(
12301232
Rc::new(resolved_toml),
@@ -1292,6 +1294,8 @@ fn to_virtual_manifest(
12921294
let cargo_features = me.cargo_features.as_ref().unwrap_or(&empty);
12931295
let features = Features::new(cargo_features, gctx, &mut warnings, source_id.is_path())?;
12941296

1297+
warn_on_unused(&me._unused_keys, &mut warnings);
1298+
12951299
let (replace, patch) = {
12961300
let mut manifest_ctx = ManifestContext {
12971301
deps: &mut deps,

0 commit comments

Comments
 (0)