Skip to content

Commit

Permalink
Auto merge of #6493 - ehuss:fix-fingerprint-patch, r=alexcrichton
Browse files Browse the repository at this point in the history
Fix fingerprint calculation for patched deps.

If you have A→B→C where B and C are in a registry, and you `[patch]` C, the fingerprint calculation wasn't working correctly when C changes. The following sequence illustrates the problem:

1. Do a build from scratch.
2. Touch a file in C.
3. Build again. Everything rebuilds as expected.
4. Build again. You would expect this to be all fresh, but it rebuilds A.

The problem is the hash-busting doesn't propagate up to parents from dependencies. Normal targets normally aren't a problem because they have a `LocalFingerprint::MtimeBased` style local value which always recomputes the hash. However, registry dependencies have a `Precalculated` style local value which never recomputes the hash.

The solution here is to always recompute the hash. This shouldn't be too expensive, and is only done when writing the fingerprint, which should only happen when the target is dirty. I'm not entirely certain why the caching logic was added in #4125.

Fixes rust-lang/rust#57142
  • Loading branch information
bors committed Jan 2, 2019
2 parents 6e10374 + ed98cab commit 9bfaf2e
Show file tree
Hide file tree
Showing 2 changed files with 59 additions and 6 deletions.
6 changes: 1 addition & 5 deletions src/cargo/core/compiler/fingerprint.rs
Original file line number Diff line number Diff line change
Expand Up @@ -236,7 +236,6 @@ impl Fingerprint {
}

fn update_local(&self, root: &Path) -> CargoResult<()> {
let mut hash_busted = false;
for local in self.local.iter() {
match *local {
LocalFingerprint::MtimeBased(ref slot, ref path) => {
Expand All @@ -246,12 +245,9 @@ impl Fingerprint {
}
LocalFingerprint::EnvBased(..) | LocalFingerprint::Precalculated(..) => continue,
}
hash_busted = true;
}

if hash_busted {
*self.memoized_hash.lock().unwrap() = None;
}
*self.memoized_hash.lock().unwrap() = None;
Ok(())
}

Expand Down
59 changes: 58 additions & 1 deletion tests/testsuite/freshness.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ use std::io::prelude::*;
use crate::support::paths::CargoPathExt;
use crate::support::registry::Package;
use crate::support::sleep_ms;
use crate::support::{basic_manifest, project};
use crate::support::{basic_manifest, is_coarse_mtime, project};

#[test]
fn modifying_and_moving() {
Expand Down Expand Up @@ -1252,3 +1252,60 @@ fn reuse_panic_pm() {
)
.run();
}

#[test]
fn bust_patched_dep() {
Package::new("registry1", "0.1.0").publish();
Package::new("registry2", "0.1.0")
.dep("registry1", "0.1.0")
.publish();

let p = project()
.file(
"Cargo.toml",
r#"
[package]
name = "foo"
version = "0.0.1"
[dependencies]
registry2 = "0.1.0"
[patch.crates-io]
registry1 = { path = "reg1new" }
"#,
)
.file("src/lib.rs", "")
.file("reg1new/Cargo.toml", &basic_manifest("registry1", "0.1.0"))
.file("reg1new/src/lib.rs", "")
.build();

p.cargo("build").run();

File::create(&p.root().join("reg1new/src/lib.rs")).unwrap();
if is_coarse_mtime() {
sleep_ms(1000);
}

p.cargo("build")
.with_stderr(
"\
[COMPILING] registry1 v0.1.0 ([..])
[COMPILING] registry2 v0.1.0
[COMPILING] foo v0.0.1 ([..])
[FINISHED] [..]
",
)
.run();

p.cargo("build -v")
.with_stderr(
"\
[FRESH] registry1 v0.1.0 ([..])
[FRESH] registry2 v0.1.0
[FRESH] foo v0.0.1 ([..])
[FINISHED] [..]
",
)
.run();
}

0 comments on commit 9bfaf2e

Please sign in to comment.