diff --git a/src/workspace/parser/mod.rs b/src/workspace/parser/mod.rs index 6790c746a9b..e42d5274bd6 100644 --- a/src/workspace/parser/mod.rs +++ b/src/workspace/parser/mod.rs @@ -582,7 +582,14 @@ fn normalize_toml( normalized_toml.badges = original_toml.badges.clone(); } else { if let Some(field) = original_toml.requires_package().next() { - bail!("this virtual manifest specifies a `{field}` section, which is not allowed"); + let suggestion = if field == "lints" { + "\nhelp: a similar field exists: `[workspace.lints]`" + } else { + "" + }; + bail!( + "this virtual manifest specifies a `{field}` section, which is not allowed{suggestion}" + ); } } diff --git a/tests/testsuite/workspaces.rs b/tests/testsuite/workspaces.rs index 1870cf1d4eb..f5589e2d7f8 100644 --- a/tests/testsuite/workspaces.rs +++ b/tests/testsuite/workspaces.rs @@ -2345,7 +2345,6 @@ fn ws_err_unused() { "[features]", "[target]", "[badges]", - "[lints]", ] { let key = table.trim_start_matches('[').trim_end_matches(']'); let p = project() @@ -2377,6 +2376,55 @@ Caused by: } } +#[cargo_test] +fn ws_err_unused_similar_suggest() { + let cases: &[(&str, &str)] = &[ + ( + "[lints]", + "[HELP] a similar field exists: `[workspace.lints]`", + ), + ( + "[lints.rust]", + "[HELP] a similar field exists: `[workspace.lints]`", + ), + ( + "[lints.clippy]", + "[HELP] a similar field exists: `[workspace.lints]`", + ), + ]; + for (table, suggestion) in cases { + let key = table.trim_start_matches('[').trim_end_matches(']'); + let key = key.split_once('.').map(|p| p.0).unwrap_or(key); + let p = project() + .file( + "Cargo.toml", + &format!( + r#" + [workspace] + members = ["a"] + + {table} + "#, + ), + ) + .file("a/Cargo.toml", &basic_lib_manifest("a")) + .file("a/src/lib.rs", "") + .build(); + p.cargo("check") + .with_status(101) + .with_stderr_data(&format!( + "\ +[ERROR] failed to parse manifest at `[..]/foo/Cargo.toml` + +Caused by: + this virtual manifest specifies a `{key}` section, which is not allowed + {suggestion} +", + )) + .run(); + } +} + #[cargo_test] fn ws_warn_unused() { for (key, name) in &[