Skip to content

Commit 6972630

Browse files
committed
Auto merge of #12783 - dvdhrm:pr/libname2, r=ehuss
cargo: prevent dashes in lib.name The TOML parser of Cargo currently refuses `lib.name` entries that contain dashes. Unfortunately, it uses the package-name as default if no explicit `lib.name` entry is specified. This package-name, however, can contain dashes. Cargo documentation states that the package name is converted first, yet this was never implemented by the code-base. Fix this inconsistency and convert the package name to a suitable crate-name first. This fixes #12780. It is an alternative to #12640.
2 parents 2fe739f + 3ca04e2 commit 6972630

File tree

8 files changed

+62
-22
lines changed

8 files changed

+62
-22
lines changed

src/cargo/core/compiler/artifact.rs

+27-3
Original file line numberDiff line numberDiff line change
@@ -29,15 +29,39 @@ pub fn get_env(
2929
let path = artifact_path.parent().expect("parent dir for artifacts");
3030
env.insert(var, path.to_owned().into());
3131

32-
let var = format!(
32+
let var_file = format!(
3333
"CARGO_{}_FILE_{}_{}",
3434
artifact_type_upper,
3535
dep_name_upper,
3636
unit_dep.unit.target.name()
3737
);
38-
env.insert(var, artifact_path.to_owned().into());
3938

40-
if unit_dep.unit.target.name() == dep_name.as_str() {
39+
// In older releases, lib-targets defaulted to the name of the package. Newer releases
40+
// use the same name as default, but with dashes replaced. Hence, if the name of the
41+
// target was inferred by Cargo, we also set the env-var with the unconverted name for
42+
// backwards compatibility.
43+
let need_compat = unit_dep.unit.target.is_lib() && unit_dep.unit.target.name_inferred();
44+
if need_compat {
45+
let var_compat = format!(
46+
"CARGO_{}_FILE_{}_{}",
47+
artifact_type_upper,
48+
dep_name_upper,
49+
unit_dep.unit.pkg.name(),
50+
);
51+
if var_compat != var_file {
52+
env.insert(var_compat, artifact_path.to_owned().into());
53+
}
54+
}
55+
56+
env.insert(var_file, artifact_path.to_owned().into());
57+
58+
// If the name of the target matches the name of the dependency, we strip the
59+
// repetition and provide the simpler env-var as well.
60+
// For backwards-compatibility of inferred names, we compare against the name of the
61+
// package as well, since that used to be the default for library targets.
62+
if unit_dep.unit.target.name() == dep_name.as_str()
63+
|| (need_compat && unit_dep.unit.pkg.name() == dep_name.as_str())
64+
{
4165
let var = format!("CARGO_{}_FILE_{}", artifact_type_upper, dep_name_upper,);
4266
env.insert(var, artifact_path.to_owned().into());
4367
}

src/cargo/core/manifest.rs

+11
Original file line numberDiff line numberDiff line change
@@ -213,6 +213,8 @@ pub struct Target {
213213
struct TargetInner {
214214
kind: TargetKind,
215215
name: String,
216+
// Whether the name was inferred by Cargo, or explicitly given.
217+
name_inferred: bool,
216218
// Note that `bin_name` is used for the cargo-feature `different_binary_name`
217219
bin_name: Option<String>,
218220
// Note that the `src_path` here is excluded from the `Hash` implementation
@@ -372,6 +374,7 @@ compact_debug! {
372374
[debug_the_fields(
373375
kind
374376
name
377+
name_inferred
375378
bin_name
376379
src_path
377380
required_features
@@ -679,6 +682,7 @@ impl Target {
679682
inner: Arc::new(TargetInner {
680683
kind: TargetKind::Bin,
681684
name: String::new(),
685+
name_inferred: false,
682686
bin_name: None,
683687
src_path,
684688
required_features: None,
@@ -812,6 +816,9 @@ impl Target {
812816
pub fn name(&self) -> &str {
813817
&self.inner.name
814818
}
819+
pub fn name_inferred(&self) -> bool {
820+
self.inner.name_inferred
821+
}
815822
pub fn crate_name(&self) -> String {
816823
self.name().replace("-", "_")
817824
}
@@ -986,6 +993,10 @@ impl Target {
986993
Arc::make_mut(&mut self.inner).name = name.to_string();
987994
self
988995
}
996+
pub fn set_name_inferred(&mut self, inferred: bool) -> &mut Target {
997+
Arc::make_mut(&mut self.inner).name_inferred = inferred;
998+
self
999+
}
9891000
pub fn set_binary_name(&mut self, bin_name: Option<String>) -> &mut Target {
9901001
Arc::make_mut(&mut self.inner).bin_name = bin_name;
9911002
self

src/cargo/util/toml/targets.rs

+6-3
Original file line numberDiff line numberDiff line change
@@ -156,18 +156,20 @@ fn clean_lib(
156156
let lib = match toml_lib {
157157
Some(lib) => {
158158
if let Some(ref name) = lib.name {
159-
// XXX: other code paths dodge this validation
160159
if name.contains('-') {
161160
anyhow::bail!("library target names cannot contain hyphens: {}", name)
162161
}
163162
}
164163
Some(TomlTarget {
165-
name: lib.name.clone().or_else(|| Some(package_name.to_owned())),
164+
name: lib
165+
.name
166+
.clone()
167+
.or_else(|| Some(package_name.replace("-", "_"))),
166168
..lib.clone()
167169
})
168170
}
169171
None => inferred.as_ref().map(|lib| TomlTarget {
170-
name: Some(package_name.to_string()),
172+
name: Some(package_name.replace("-", "_")),
171173
path: Some(PathValue(lib.clone())),
172174
..TomlTarget::new()
173175
}),
@@ -262,6 +264,7 @@ fn clean_lib(
262264

263265
let mut target = Target::lib_target(name_or_panic(lib), crate_types, path, edition);
264266
configure(lib, &mut target)?;
267+
target.set_name_inferred(toml_lib.map_or(true, |v| v.name.is_none()));
265268
Ok(Some(target))
266269
}
267270

tests/testsuite/artifact_dep.rs

+2
Original file line numberDiff line numberDiff line change
@@ -841,8 +841,10 @@ fn lib_with_selected_dashed_bin_artifact_and_lib_true() {
841841
let _b = include_bytes!(env!("CARGO_BIN_FILE_BAR_BAZ_baz-suffix"));
842842
let _b = include_bytes!(env!("CARGO_STATICLIB_FILE_BAR_BAZ"));
843843
let _b = include_bytes!(env!("CARGO_STATICLIB_FILE_BAR_BAZ_bar-baz"));
844+
let _b = include_bytes!(env!("CARGO_STATICLIB_FILE_BAR_BAZ_bar_baz"));
844845
let _b = include_bytes!(env!("CARGO_CDYLIB_FILE_BAR_BAZ"));
845846
let _b = include_bytes!(env!("CARGO_CDYLIB_FILE_BAR_BAZ_bar-baz"));
847+
let _b = include_bytes!(env!("CARGO_CDYLIB_FILE_BAR_BAZ_bar_baz"));
846848
}
847849
"#,
848850
)

tests/testsuite/collisions.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -550,7 +550,7 @@ fn collision_with_root() {
550550
[DOWNLOADING] crates ...
551551
[DOWNLOADED] foo-macro v1.0.0 [..]
552552
warning: output filename collision.
553-
The lib target `foo-macro` in package `foo-macro v1.0.0` has the same output filename as the lib target `foo-macro` in package `foo-macro v1.0.0 [..]`.
553+
The lib target `foo_macro` in package `foo-macro v1.0.0` has the same output filename as the lib target `foo_macro` in package `foo-macro v1.0.0 [..]`.
554554
Colliding filename is: [CWD]/target/doc/foo_macro/index.html
555555
The targets should have unique names.
556556
This is a known bug where multiple crates with the same name use

tests/testsuite/doc.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -2203,7 +2203,7 @@ fn doc_test_in_workspace() {
22032203
)
22042204
.build();
22052205
p.cargo("test --doc -vv")
2206-
.with_stderr_contains("[DOCTEST] crate-a")
2206+
.with_stderr_contains("[DOCTEST] crate_a")
22072207
.with_stdout_contains(
22082208
"
22092209
running 1 test
@@ -2212,7 +2212,7 @@ test crate-a/src/lib.rs - (line 1) ... ok
22122212
test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out[..]
22132213
",
22142214
)
2215-
.with_stderr_contains("[DOCTEST] crate-b")
2215+
.with_stderr_contains("[DOCTEST] crate_b")
22162216
.with_stdout_contains(
22172217
"
22182218
running 1 test

tests/testsuite/metadata.rs

+5-5
Original file line numberDiff line numberDiff line change
@@ -1622,7 +1622,7 @@ fn workspace_metadata_with_dependencies_and_resolve() {
16221622
"kind": [
16231623
"lib"
16241624
],
1625-
"name": "non-artifact",
1625+
"name": "non_artifact",
16261626
"src_path": "[..]/foo/non-artifact/src/lib.rs",
16271627
"test": true
16281628
}
@@ -3114,7 +3114,7 @@ fn filter_platform() {
31143114
"crate_types": [
31153115
"lib"
31163116
],
3117-
"name": "alt-dep",
3117+
"name": "alt_dep",
31183118
"src_path": "[..]/alt-dep-0.0.1/src/lib.rs",
31193119
"edition": "2015",
31203120
"test": true,
@@ -3158,7 +3158,7 @@ fn filter_platform() {
31583158
"crate_types": [
31593159
"lib"
31603160
],
3161-
"name": "cfg-dep",
3161+
"name": "cfg_dep",
31623162
"src_path": "[..]/cfg-dep-0.0.1/src/lib.rs",
31633163
"edition": "2015",
31643164
"test": true,
@@ -3202,7 +3202,7 @@ fn filter_platform() {
32023202
"crate_types": [
32033203
"lib"
32043204
],
3205-
"name": "host-dep",
3205+
"name": "host_dep",
32063206
"src_path": "[..]/host-dep-0.0.1/src/lib.rs",
32073207
"edition": "2015",
32083208
"test": true,
@@ -3246,7 +3246,7 @@ fn filter_platform() {
32463246
"crate_types": [
32473247
"lib"
32483248
],
3249-
"name": "normal-dep",
3249+
"name": "normal_dep",
32503250
"src_path": "[..]/normal-dep-0.0.1/src/lib.rs",
32513251
"edition": "2015",
32523252
"test": true,

tests/testsuite/test.rs

+8-8
Original file line numberDiff line numberDiff line change
@@ -4864,9 +4864,9 @@ fn test_workspaces_cwd() {
48644864
.build();
48654865

48664866
p.cargo("test --workspace --all")
4867-
.with_stderr_contains("[DOCTEST] root-crate")
4868-
.with_stderr_contains("[DOCTEST] nested-crate")
4869-
.with_stderr_contains("[DOCTEST] deep-crate")
4867+
.with_stderr_contains("[DOCTEST] root_crate")
4868+
.with_stderr_contains("[DOCTEST] nested_crate")
4869+
.with_stderr_contains("[DOCTEST] deep_crate")
48704870
.with_stdout_contains("test test_unit_root_cwd ... ok")
48714871
.with_stdout_contains("test test_unit_nested_cwd ... ok")
48724872
.with_stdout_contains("test test_unit_deep_cwd ... ok")
@@ -4876,33 +4876,33 @@ fn test_workspaces_cwd() {
48764876
.run();
48774877

48784878
p.cargo("test -p root-crate --all")
4879-
.with_stderr_contains("[DOCTEST] root-crate")
4879+
.with_stderr_contains("[DOCTEST] root_crate")
48804880
.with_stdout_contains("test test_unit_root_cwd ... ok")
48814881
.with_stdout_contains("test test_integration_root_cwd ... ok")
48824882
.run();
48834883

48844884
p.cargo("test -p nested-crate --all")
4885-
.with_stderr_contains("[DOCTEST] nested-crate")
4885+
.with_stderr_contains("[DOCTEST] nested_crate")
48864886
.with_stdout_contains("test test_unit_nested_cwd ... ok")
48874887
.with_stdout_contains("test test_integration_nested_cwd ... ok")
48884888
.run();
48894889

48904890
p.cargo("test -p deep-crate --all")
4891-
.with_stderr_contains("[DOCTEST] deep-crate")
4891+
.with_stderr_contains("[DOCTEST] deep_crate")
48924892
.with_stdout_contains("test test_unit_deep_cwd ... ok")
48934893
.with_stdout_contains("test test_integration_deep_cwd ... ok")
48944894
.run();
48954895

48964896
p.cargo("test --all")
48974897
.cwd("nested-crate")
4898-
.with_stderr_contains("[DOCTEST] nested-crate")
4898+
.with_stderr_contains("[DOCTEST] nested_crate")
48994899
.with_stdout_contains("test test_unit_nested_cwd ... ok")
49004900
.with_stdout_contains("test test_integration_nested_cwd ... ok")
49014901
.run();
49024902

49034903
p.cargo("test --all")
49044904
.cwd("very/deeply/nested/deep-crate")
4905-
.with_stderr_contains("[DOCTEST] deep-crate")
4905+
.with_stderr_contains("[DOCTEST] deep_crate")
49064906
.with_stdout_contains("test test_unit_deep_cwd ... ok")
49074907
.with_stdout_contains("test test_integration_deep_cwd ... ok")
49084908
.run();

0 commit comments

Comments
 (0)