Skip to content

Commit 34b785b

Browse files
committed
Helpful error when the [package] table is missing
1 parent 2e5dd34 commit 34b785b

File tree

2 files changed

+68
-18
lines changed

2 files changed

+68
-18
lines changed

src/cargo/util/toml/mod.rs

Lines changed: 28 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -577,13 +577,40 @@ fn normalize_toml(
577577
normalized_toml.badges = original_toml.badges.clone();
578578
} else {
579579
if let Some(field) = original_toml.requires_package().next() {
580-
bail!("this virtual manifest specifies a `{field}` section, which is not allowed");
580+
return Err(field_requires_package_error(
581+
field,
582+
original_toml.workspace.is_some(),
583+
));
581584
}
582585
}
583586

584587
Ok(normalized_toml)
585588
}
586589

590+
fn field_requires_package_error(field: &str, has_workspace: bool) -> anyhow::Error {
591+
let toml_brackets = if matches!(field, "bin" | "example" | "test" | "bench") {
592+
("[[", "]]")
593+
} else {
594+
("[", "]")
595+
};
596+
let toml_table = format_args!("{}{field}{}", toml_brackets.0, toml_brackets.1);
597+
let suggest_workspace = has_workspace
598+
&& matches!(
599+
field,
600+
"dependencies" | "dev-dependencies" | "build-dependencies" | "lints"
601+
);
602+
let help = if suggest_workspace {
603+
format_args!(
604+
"\nhelp: you can use `[workspace.{field}]` to define a template for workspace members to inherit from"
605+
)
606+
} else {
607+
format_args!("")
608+
};
609+
anyhow!(
610+
"this virtual manifest does not have a `[package]` section, which is required when specifying the `{toml_table}` section{help}"
611+
)
612+
}
613+
587614
fn normalize_patch<'a>(
588615
gctx: &GlobalContext,
589616
original_patch: Option<&BTreeMap<String, BTreeMap<PackageName, TomlDependency>>>,

tests/testsuite/workspaces.rs

Lines changed: 40 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -2281,22 +2281,45 @@ fn ws_rustc_err() {
22812281
}
22822282

22832283
#[cargo_test]
2284-
fn ws_err_unused() {
2285-
for table in &[
2286-
"[lib]",
2287-
"[[bin]]",
2288-
"[[example]]",
2289-
"[[test]]",
2290-
"[[bench]]",
2291-
"[dependencies]",
2292-
"[dev-dependencies]",
2293-
"[build-dependencies]",
2294-
"[features]",
2295-
"[target]",
2296-
"[badges]",
2297-
"[lints]",
2298-
] {
2299-
let key = table.trim_start_matches('[').trim_end_matches(']');
2284+
fn ws_err_unused_inheritable() {
2285+
ws_err_unused_inner(
2286+
&[
2287+
"[dependencies]",
2288+
"[dev-dependencies]",
2289+
"[build-dependencies]",
2290+
"[lints]",
2291+
],
2292+
true,
2293+
);
2294+
}
2295+
2296+
#[cargo_test]
2297+
fn ws_err_unused_package_only() {
2298+
ws_err_unused_inner(
2299+
&[
2300+
"[lib]",
2301+
"[[bin]]",
2302+
"[[example]]",
2303+
"[[test]]",
2304+
"[[bench]]",
2305+
"[features]",
2306+
"[target]",
2307+
"[badges]",
2308+
],
2309+
false,
2310+
);
2311+
}
2312+
2313+
fn ws_err_unused_inner(tables: &[&str], expected_help: bool) {
2314+
for table in tables {
2315+
let expected_help = if expected_help {
2316+
format_args!(
2317+
"\n [HELP] you can use `[workspace.{}]` to define a template for workspace members to inherit from",
2318+
table.trim_matches(['[', ']'])
2319+
)
2320+
} else {
2321+
format_args!("")
2322+
};
23002323
let p = project()
23012324
.file(
23022325
"Cargo.toml",
@@ -2319,7 +2342,7 @@ fn ws_err_unused() {
23192342
[ERROR] failed to parse manifest at `[..]/foo/Cargo.toml`
23202343
23212344
Caused by:
2322-
this virtual manifest specifies a `{key}` section, which is not allowed
2345+
this virtual manifest does not have a `[package]` section, which is required when specifying the `{table}` section{expected_help}
23232346
",
23242347
))
23252348
.run();

0 commit comments

Comments
 (0)