Skip to content

Commit b4b38e1

Browse files
committed
fix(depinfo): prevent invalid trailing backslash on Windows
Joining an empty path adds a trailing path separator. On Windows, this causes cargo to emit an invalid depfile, where a dependency ends in a backslash, which is invalid. This patch fixes the two known cases where this issue can happen _without_ the user passing in any path with a trailing backslash.
1 parent e83f8dd commit b4b38e1

File tree

3 files changed

+28
-11
lines changed

3 files changed

+28
-11
lines changed

src/cargo/core/compiler/fingerprint/dep_info.rs

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -503,11 +503,19 @@ fn make_absolute_path(
503503
build_root: &Path,
504504
path: PathBuf,
505505
) -> PathBuf {
506-
match ty {
507-
DepInfoPathType::PackageRootRelative => pkg_root.join(path),
508-
// N.B. path might be absolute here in which case the join will have no effect
509-
DepInfoPathType::BuildRootRelative => build_root.join(path),
506+
let relative_to = match ty {
507+
DepInfoPathType::PackageRootRelative => pkg_root,
508+
// N.B. path might be absolute here in which case the join below will have no effect
509+
DepInfoPathType::BuildRootRelative => build_root,
510+
};
511+
512+
if path.as_os_str().is_empty() {
513+
// Joining with an empty path causes Rust to add a trailing path separator. On Windows, this
514+
// would add an invalid trailing backslash to the .d file.
515+
return relative_to.to_path_buf();
510516
}
517+
518+
relative_to.join(path)
511519
}
512520

513521
/// Some algorithms are here to ensure compatibility with possible rustc outputs.

src/cargo/core/compiler/output_depinfo.rs

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -84,9 +84,18 @@ fn add_deps_for_unit(
8484
.get(metadata)
8585
{
8686
for path in &output.rerun_if_changed {
87-
// The paths we have saved from the unit are of arbitrary relativeness and may be
88-
// relative to the crate root of the dependency.
89-
let path = unit.pkg.root().join(path);
87+
let package_root = unit.pkg.root();
88+
89+
let path = if path.as_os_str().is_empty() {
90+
// Joining with an empty path causes Rust to add a trailing path separator.
91+
// On Windows, this would add an invalid trailing backslash to the .d file.
92+
package_root.to_path_buf()
93+
} else {
94+
// The paths we have saved from the unit are of arbitrary relativeness and
95+
// may be relative to the crate root of the dependency.
96+
package_root.join(path)
97+
};
98+
9099
deps.insert(path);
91100
}
92101
}

tests/testsuite/dep_info.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -554,7 +554,7 @@ fn non_local_build_script() {
554554
}
555555

556556
#[cargo_test]
557-
fn trailing_separator_after_package_root_build_script() {
557+
fn no_trailing_separator_after_package_root_build_script() {
558558
let p = project()
559559
.file(
560560
"Cargo.toml",
@@ -582,14 +582,14 @@ fn trailing_separator_after_package_root_build_script() {
582582
assert_e2e().eq(
583583
&contents,
584584
str![[r#"
585-
[ROOT]/foo/target/debug/foo[EXE]: [ROOT]/foo/ [ROOT]/foo/build.rs [ROOT]/foo/src/main.rs
585+
[ROOT]/foo/target/debug/foo[EXE]: [ROOT]/foo [ROOT]/foo/build.rs [ROOT]/foo/src/main.rs
586586
587587
"#]],
588588
);
589589
}
590590

591591
#[cargo_test(nightly, reason = "proc_macro::tracked_path is unstable")]
592-
fn trailing_separator_after_package_root_proc_macro() {
592+
fn no_trailing_separator_after_package_root_proc_macro() {
593593
let p = project()
594594
.file(
595595
"Cargo.toml",
@@ -647,7 +647,7 @@ fn trailing_separator_after_package_root_proc_macro() {
647647
assert_e2e().eq(
648648
&contents,
649649
str![[r#"
650-
[ROOT]/foo/target/debug/foo[EXE]: [ROOT]/foo/ [ROOT]/foo/pm/src/lib.rs [ROOT]/foo/src/main.rs
650+
[ROOT]/foo/target/debug/foo[EXE]: [ROOT]/foo [ROOT]/foo/pm/src/lib.rs [ROOT]/foo/src/main.rs
651651
652652
"#]],
653653
);

0 commit comments

Comments
 (0)