diff --git a/src/cargo/util/toml/mod.rs b/src/cargo/util/toml/mod.rs index 12ecb806222..4e1426147e2 100644 --- a/src/cargo/util/toml/mod.rs +++ b/src/cargo/util/toml/mod.rs @@ -106,17 +106,6 @@ fn read_manifest_from_str( parse_document(contents, pretty_filename, config)? }; - // Provide a helpful error message for a common user error. - if let Some(package) = toml.get("package").or_else(|| toml.get("project")) { - if let Some(feats) = package.get("cargo-features") { - bail!( - "cargo-features = {} was found in the wrong location: it \ - should be set at the top of Cargo.toml before any tables", - feats - ); - } - } - let mut unused = BTreeSet::new(); let manifest: TomlManifest = serde_ignored::deserialize(toml.into_deserializer(), |path| { let mut key = String::new(); @@ -1536,6 +1525,10 @@ pub struct TomlPackage { repository: Option, resolver: Option, + // Provide a helpful error message for a common user error. + #[serde(rename = "cargo-features", skip_serializing)] + _invalid_cargo_features: Option, + // Note that this field must come last due to the way toml serialization // works which requires tables to be emitted after all values. metadata: Option, @@ -3546,3 +3539,20 @@ impl TomlLintLevel { } } } + +#[derive(Copy, Clone, Debug)] +#[non_exhaustive] +struct InvalidCargoFeatures {} + +impl<'de> de::Deserialize<'de> for InvalidCargoFeatures { + fn deserialize(_d: D) -> Result + where + D: de::Deserializer<'de>, + { + use serde::de::Error as _; + + Err(D::Error::custom( + "the field `cargo-features` should be set at the top of Cargo.toml before any tables", + )) + } +} diff --git a/tests/testsuite/cargo_features.rs b/tests/testsuite/cargo_features.rs index ed5f53a1e6d..5f3a96eff5b 100644 --- a/tests/testsuite/cargo_features.rs +++ b/tests/testsuite/cargo_features.rs @@ -676,8 +676,8 @@ fn wrong_position() { error: failed to parse manifest at [..] Caused by: - cargo-features = [\"test-dummy-unstable\"] was found in the wrong location: it \ - should be set at the top of Cargo.toml before any tables + the field `cargo-features` should be set at the top of Cargo.toml before any tables + in `package.cargo-features` ", ) .run();