Skip to content

Commit e420c7b

Browse files
committed
Auto merge of #13841 - epage:i, r=weihanglo
fix(toml): Validate crates_types/proc-macro for bin like others ### What does this PR try to resolve? This is all refactors on my way to skipping inferring of targets when it isn't needed. Along the way, I made the target validation more consistent ### How should we test and review this PR? ### Additional information
2 parents d34d0a1 + cdae596 commit e420c7b

File tree

3 files changed

+311
-82
lines changed

3 files changed

+311
-82
lines changed

src/cargo/util/toml/mod.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -333,6 +333,7 @@ fn resolve_toml(
333333
edition,
334334
original_package.autobins,
335335
warnings,
336+
errors,
336337
resolved_toml.lib.is_some(),
337338
)?);
338339
resolved_toml.example = Some(targets::resolve_examples(
@@ -1070,7 +1071,7 @@ fn to_real_manifest(
10701071
manifest_file: &Path,
10711072
gctx: &GlobalContext,
10721073
warnings: &mut Vec<String>,
1073-
errors: &mut Vec<String>,
1074+
_errors: &mut Vec<String>,
10741075
) -> CargoResult<Manifest> {
10751076
let embedded = is_embedded(manifest_file);
10761077
let package_root = manifest_file.parent().unwrap();
@@ -1212,7 +1213,6 @@ fn to_real_manifest(
12121213
edition,
12131214
&resolved_package.metabuild,
12141215
warnings,
1215-
errors,
12161216
)?;
12171217

12181218
if targets.iter().all(|t| t.is_custom_build()) {

src/cargo/util/toml/targets.rs

+101-77
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,6 @@ pub(super) fn to_targets(
4040
edition: Edition,
4141
metabuild: &Option<StringOrVec>,
4242
warnings: &mut Vec<String>,
43-
errors: &mut Vec<String>,
4443
) -> CargoResult<Vec<Target>> {
4544
let mut targets = Vec::new();
4645

@@ -64,7 +63,6 @@ pub(super) fn to_targets(
6463
resolved_toml.bin.as_deref().unwrap_or_default(),
6564
package_root,
6665
edition,
67-
errors,
6866
)?);
6967

7068
targets.extend(to_example_targets(
@@ -143,10 +141,10 @@ pub fn resolve_lib(
143141
let Some(mut lib) = lib else { return Ok(None) };
144142
lib.name
145143
.get_or_insert_with(|| package_name.replace("-", "_"));
144+
146145
// Check early to improve error messages
147146
validate_lib_name(&lib, warnings)?;
148147

149-
// Checking the original lib
150148
validate_proc_macro(&lib, "library", edition, warnings)?;
151149
validate_crate_types(&lib, "library", edition, warnings)?;
152150

@@ -260,6 +258,7 @@ pub fn resolve_bins(
260258
edition: Edition,
261259
autodiscover: Option<bool>,
262260
warnings: &mut Vec<String>,
261+
errors: &mut Vec<String>,
263262
has_lib: bool,
264263
) -> CargoResult<Vec<TomlBinTarget>> {
265264
let inferred = inferred_bins(package_root, package_name);
@@ -277,8 +276,12 @@ pub fn resolve_bins(
277276
);
278277

279278
for bin in &mut bins {
279+
// Check early to improve error messages
280280
validate_bin_name(bin, warnings)?;
281281

282+
validate_bin_crate_types(bin, edition, warnings, errors)?;
283+
validate_bin_proc_macro(bin, edition, warnings, errors)?;
284+
282285
let path = target_path(bin, &inferred, "bin", package_root, edition, &mut |_| {
283286
if let Some(legacy_path) = legacy_bin_path(package_root, name_or_panic(bin), has_lib) {
284287
warnings.push(format!(
@@ -308,7 +311,6 @@ fn to_bin_targets(
308311
bins: &[TomlBinTarget],
309312
package_root: &Path,
310313
edition: Edition,
311-
errors: &mut Vec<String>,
312314
) -> CargoResult<Vec<Target>> {
313315
// This loop performs basic checks on each of the TomlTarget in `bins`.
314316
for bin in bins {
@@ -317,27 +319,6 @@ fn to_bin_targets(
317319
if bin.filename.is_some() {
318320
features.require(Feature::different_binary_name())?;
319321
}
320-
321-
if let Some(crate_types) = bin.crate_types() {
322-
if !crate_types.is_empty() {
323-
let name = name_or_panic(bin);
324-
errors.push(format!(
325-
"the target `{}` is a binary and can't have any \
326-
crate-types set (currently \"{}\")",
327-
name,
328-
crate_types.join(", ")
329-
));
330-
}
331-
}
332-
333-
if bin.proc_macro() == Some(true) {
334-
let name = name_or_panic(bin);
335-
errors.push(format!(
336-
"the target `{}` is a binary and can't have `proc-macro` \
337-
set `true`",
338-
name
339-
));
340-
}
341322
}
342323

343324
validate_unique_names(&bins, "binary")?;
@@ -608,7 +589,9 @@ fn resolve_targets_with_legacy_path(
608589
);
609590

610591
for target in &toml_targets {
592+
// Check early to improve error messages
611593
validate_target_name(target, target_kind_human, target_kind, warnings)?;
594+
612595
validate_proc_macro(target, target_kind_human, edition, warnings)?;
613596
validate_crate_types(target, target_kind_human, edition, warnings)?;
614597
}
@@ -812,58 +795,6 @@ fn inferred_to_toml_targets(inferred: &[(String, PathBuf)]) -> Vec<TomlTarget> {
812795
.collect()
813796
}
814797

815-
fn validate_lib_name(target: &TomlTarget, warnings: &mut Vec<String>) -> CargoResult<()> {
816-
validate_target_name(target, "library", "lib", warnings)?;
817-
let name = name_or_panic(target);
818-
if name.contains('-') {
819-
anyhow::bail!("library target names cannot contain hyphens: {}", name)
820-
}
821-
822-
Ok(())
823-
}
824-
825-
fn validate_bin_name(bin: &TomlTarget, warnings: &mut Vec<String>) -> CargoResult<()> {
826-
validate_target_name(bin, "binary", "bin", warnings)?;
827-
let name = name_or_panic(bin).to_owned();
828-
if restricted_names::is_conflicting_artifact_name(&name) {
829-
anyhow::bail!(
830-
"the binary target name `{name}` is forbidden, \
831-
it conflicts with cargo's build directory names",
832-
)
833-
}
834-
835-
Ok(())
836-
}
837-
838-
fn validate_target_name(
839-
target: &TomlTarget,
840-
target_kind_human: &str,
841-
target_kind: &str,
842-
warnings: &mut Vec<String>,
843-
) -> CargoResult<()> {
844-
match target.name {
845-
Some(ref name) => {
846-
if name.trim().is_empty() {
847-
anyhow::bail!("{} target names cannot be empty", target_kind_human)
848-
}
849-
if cfg!(windows) && restricted_names::is_windows_reserved(name) {
850-
warnings.push(format!(
851-
"{} target `{}` is a reserved Windows filename, \
852-
this target will not work on Windows platforms",
853-
target_kind_human, name
854-
));
855-
}
856-
}
857-
None => anyhow::bail!(
858-
"{} target {}.name is required",
859-
target_kind_human,
860-
target_kind
861-
),
862-
}
863-
864-
Ok(())
865-
}
866-
867798
/// Will check a list of toml targets, and make sure the target names are unique within a vector.
868799
fn validate_unique_names(targets: &[TomlTarget], target_kind: &str) -> CargoResult<()> {
869800
let mut seen = HashSet::new();
@@ -1076,6 +1007,77 @@ fn name_or_panic(target: &TomlTarget) -> &str {
10761007
.unwrap_or_else(|| panic!("target name is required"))
10771008
}
10781009

1010+
fn validate_lib_name(target: &TomlTarget, warnings: &mut Vec<String>) -> CargoResult<()> {
1011+
validate_target_name(target, "library", "lib", warnings)?;
1012+
let name = name_or_panic(target);
1013+
if name.contains('-') {
1014+
anyhow::bail!("library target names cannot contain hyphens: {}", name)
1015+
}
1016+
1017+
Ok(())
1018+
}
1019+
1020+
fn validate_bin_name(bin: &TomlTarget, warnings: &mut Vec<String>) -> CargoResult<()> {
1021+
validate_target_name(bin, "binary", "bin", warnings)?;
1022+
let name = name_or_panic(bin).to_owned();
1023+
if restricted_names::is_conflicting_artifact_name(&name) {
1024+
anyhow::bail!(
1025+
"the binary target name `{name}` is forbidden, \
1026+
it conflicts with cargo's build directory names",
1027+
)
1028+
}
1029+
1030+
Ok(())
1031+
}
1032+
1033+
fn validate_target_name(
1034+
target: &TomlTarget,
1035+
target_kind_human: &str,
1036+
target_kind: &str,
1037+
warnings: &mut Vec<String>,
1038+
) -> CargoResult<()> {
1039+
match target.name {
1040+
Some(ref name) => {
1041+
if name.trim().is_empty() {
1042+
anyhow::bail!("{} target names cannot be empty", target_kind_human)
1043+
}
1044+
if cfg!(windows) && restricted_names::is_windows_reserved(name) {
1045+
warnings.push(format!(
1046+
"{} target `{}` is a reserved Windows filename, \
1047+
this target will not work on Windows platforms",
1048+
target_kind_human, name
1049+
));
1050+
}
1051+
}
1052+
None => anyhow::bail!(
1053+
"{} target {}.name is required",
1054+
target_kind_human,
1055+
target_kind
1056+
),
1057+
}
1058+
1059+
Ok(())
1060+
}
1061+
1062+
fn validate_bin_proc_macro(
1063+
target: &TomlTarget,
1064+
edition: Edition,
1065+
warnings: &mut Vec<String>,
1066+
errors: &mut Vec<String>,
1067+
) -> CargoResult<()> {
1068+
if target.proc_macro() == Some(true) {
1069+
let name = name_or_panic(target);
1070+
errors.push(format!(
1071+
"the target `{}` is a binary and can't have `proc-macro` \
1072+
set `true`",
1073+
name
1074+
));
1075+
} else {
1076+
validate_proc_macro(target, "binary", edition, warnings)?;
1077+
}
1078+
Ok(())
1079+
}
1080+
10791081
fn validate_proc_macro(
10801082
target: &TomlTarget,
10811083
kind: &str,
@@ -1093,6 +1095,28 @@ fn validate_proc_macro(
10931095
)
10941096
}
10951097

1098+
fn validate_bin_crate_types(
1099+
target: &TomlTarget,
1100+
edition: Edition,
1101+
warnings: &mut Vec<String>,
1102+
errors: &mut Vec<String>,
1103+
) -> CargoResult<()> {
1104+
if let Some(crate_types) = target.crate_types() {
1105+
if !crate_types.is_empty() {
1106+
let name = name_or_panic(target);
1107+
errors.push(format!(
1108+
"the target `{}` is a binary and can't have any \
1109+
crate-types set (currently \"{}\")",
1110+
name,
1111+
crate_types.join(", ")
1112+
));
1113+
} else {
1114+
validate_crate_types(target, "binary", edition, warnings)?;
1115+
}
1116+
}
1117+
Ok(())
1118+
}
1119+
10961120
fn validate_crate_types(
10971121
target: &TomlTarget,
10981122
kind: &str,

0 commit comments

Comments
 (0)