Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 12 additions & 4 deletions src/cargo/core/compiler/fingerprint/dep_info.rs
Original file line number Diff line number Diff line change
Expand Up @@ -503,11 +503,19 @@ fn make_absolute_path(
build_root: &Path,
path: PathBuf,
) -> PathBuf {
match ty {
DepInfoPathType::PackageRootRelative => pkg_root.join(path),
// N.B. path might be absolute here in which case the join will have no effect
DepInfoPathType::BuildRootRelative => build_root.join(path),
let relative_to = match ty {
DepInfoPathType::PackageRootRelative => pkg_root,
// N.B. path might be absolute here in which case the join below will have no effect
DepInfoPathType::BuildRootRelative => build_root,
};

if path.as_os_str().is_empty() {
// Joining with an empty path causes Rust to add a trailing path separator. On Windows, this
// would add an invalid trailing backslash to the .d file.
return relative_to.to_path_buf();
}

relative_to.join(path)
}

/// Some algorithms are here to ensure compatibility with possible rustc outputs.
Expand Down
15 changes: 12 additions & 3 deletions src/cargo/core/compiler/output_depinfo.rs
Original file line number Diff line number Diff line change
Expand Up @@ -84,9 +84,18 @@ fn add_deps_for_unit(
.get(metadata)
{
for path in &output.rerun_if_changed {
// The paths we have saved from the unit are of arbitrary relativeness and may be
// relative to the crate root of the dependency.
let path = unit.pkg.root().join(path);
let package_root = unit.pkg.root();

let path = if path.as_os_str().is_empty() {
// Joining with an empty path causes Rust to add a trailing path separator.
// On Windows, this would add an invalid trailing backslash to the .d file.
package_root.to_path_buf()
} else {
// The paths we have saved from the unit are of arbitrary relativeness and
// may be relative to the crate root of the dependency.
package_root.join(path)
};

deps.insert(path);
}
}
Expand Down
100 changes: 100 additions & 0 deletions tests/testsuite/dep_info.rs
Original file line number Diff line number Diff line change
Expand Up @@ -552,3 +552,103 @@ fn non_local_build_script() {
"#]],
);
}

#[cargo_test]
fn no_trailing_separator_after_package_root_build_script() {
let p = project()
.file(
"Cargo.toml",
r#"
[package]
name = "foo"
version = "0.0.1"
authors = []
"#,
)
.file("src/main.rs", "fn main() {}")
.file(
"build.rs",
r#"
fn main() {
println!("cargo::rerun-if-changed=");
}
"#,
)
.build();

p.cargo("build").run();
let contents = p.read_file("target/debug/foo.d");

assert_e2e().eq(
&contents,
str![[r#"
[ROOT]/foo/target/debug/foo[EXE]: [ROOT]/foo [ROOT]/foo/build.rs [ROOT]/foo/src/main.rs
"#]],
);
}

#[cargo_test(nightly, reason = "proc_macro::tracked_path is unstable")]
fn no_trailing_separator_after_package_root_proc_macro() {
let p = project()
.file(
"Cargo.toml",
r#"
[package]
name = "foo"
version = "0.0.1"
authors = []
edition = "2018"
[dependencies]
pm = { path = "pm" }
"#,
)
.file(
"src/main.rs",
"
pm::noop!{}
fn main() {}
",
)
.file(
"pm/Cargo.toml",
r#"
[package]
name = "pm"
version = "0.1.0"
edition = "2018"
[lib]
proc-macro = true
"#,
)
.file(
"pm/src/lib.rs",
r#"
#![feature(track_path)]
extern crate proc_macro;
use proc_macro::TokenStream;
#[proc_macro]
pub fn noop(_item: TokenStream) -> TokenStream {
proc_macro::tracked_path::path(
std::env::current_dir().unwrap().to_str().unwrap()
);
"".parse().unwrap()
}
"#,
)
.build();

p.cargo("build").run();
let contents = p.read_file("target/debug/foo.d");

assert_e2e().eq(
&contents,
str![[r#"
[ROOT]/foo/target/debug/foo[EXE]: [ROOT]/foo [ROOT]/foo/pm/src/lib.rs [ROOT]/foo/src/main.rs
"#]],
);
}