Skip to content

Commit bae3daf

Browse files
committed
Auto merge of #6785 - ehuss:fingerprint-cleanup, r=dwijnand
Some fingerprint cleanup. Just a minor cleanup. Move `CARGO_PKG_*` values from Metadata to Fingerprint (added in #3857). Closes #6208. This prevents stale artifacts from being left behind when these values change. Also tracks changes to the "repository" value (added in #6096). Remove `edition` as a separate field. It is already tracked in `target`. This was required previously to #5816 which added per-target editions. Also adds a helper to the testsuite to make globbing easier.
2 parents 1ebf6ef + 27a95d0 commit bae3daf

File tree

7 files changed

+126
-91
lines changed

7 files changed

+126
-91
lines changed

src/cargo/core/compiler/context/compilation_files.rs

-7
Original file line numberDiff line numberDiff line change
@@ -469,13 +469,6 @@ fn compute_metadata<'a, 'cfg>(
469469
.stable_hash(bcx.ws.root())
470470
.hash(&mut hasher);
471471

472-
// Add package properties which map to environment variables
473-
// exposed by Cargo.
474-
let manifest_metadata = unit.pkg.manifest().metadata();
475-
manifest_metadata.authors.hash(&mut hasher);
476-
manifest_metadata.description.hash(&mut hasher);
477-
manifest_metadata.homepage.hash(&mut hasher);
478-
479472
// Also mix in enabled features to our metadata. This'll ensure that
480473
// when changing feature sets each lib is separately cached.
481474
bcx.resolve

src/cargo/core/compiler/fingerprint.rs

+29-12
Original file line numberDiff line numberDiff line change
@@ -51,20 +51,17 @@
5151
//! Immediate dependency’s hashes | ✓[^1] | ✓
5252
//! Target or Host mode | | ✓
5353
//! __CARGO_DEFAULT_LIB_METADATA[^4] | | ✓
54-
//! authors, description, homepage | | ✓[^2]
5554
//! package_id | | ✓
55+
//! authors, description, homepage, repo | ✓ |
5656
//! Target src path | ✓ |
5757
//! Target path relative to ws | ✓ |
5858
//! Target flags (test/bench/for_host/edition) | ✓ |
59-
//! Edition | ✓ |
6059
//! -C incremental=… flag | ✓ |
6160
//! mtime of sources | ✓[^3] |
6261
//! RUSTFLAGS/RUSTDOCFLAGS | ✓ |
6362
//!
6463
//! [^1]: Build script and bin dependencies are not included.
6564
//!
66-
//! [^2]: This is a bug, see https://github.com/rust-lang/cargo/issues/6208
67-
//!
6865
//! [^3]: The mtime is only tracked for workspace members and path
6966
//! dependencies. Git dependencies track the git revision.
7067
//!
@@ -175,7 +172,7 @@ use serde::de;
175172
use serde::ser;
176173
use serde::{Deserialize, Serialize};
177174

178-
use crate::core::{Edition, Package};
175+
use crate::core::Package;
179176
use crate::util;
180177
use crate::util::errors::{CargoResult, CargoResultExt};
181178
use crate::util::paths;
@@ -337,17 +334,34 @@ struct DepFingerprint {
337334
/// graph.
338335
#[derive(Serialize, Deserialize)]
339336
pub struct Fingerprint {
337+
/// Hash of the version of `rustc` used.
340338
rustc: u64,
339+
/// Sorted list of cfg features enabled.
341340
features: String,
341+
/// Hash of the `Target` struct, including the target name,
342+
/// package-relative source path, edition, etc.
342343
target: u64,
344+
/// Hash of the `Profile`, `CompileMode`, and any extra flags passed via
345+
/// `cargo rustc` or `cargo rustdoc`.
343346
profile: u64,
347+
/// Hash of the path to the base source file. This is relative to the
348+
/// workspace root for path members, or absolute for other sources.
344349
path: u64,
350+
/// Fingerprints of dependencies.
345351
deps: Vec<DepFingerprint>,
352+
/// Information about the inputs that affect this Unit (such as source
353+
/// file mtimes or build script environment variables).
346354
local: Vec<LocalFingerprint>,
355+
/// Cached hash of the `Fingerprint` struct. Used to improve performance
356+
/// for hashing.
347357
#[serde(skip_serializing, skip_deserializing)]
348358
memoized_hash: Mutex<Option<u64>>,
359+
/// RUSTFLAGS/RUSTDOCFLAGS environment variable value (or config value).
349360
rustflags: Vec<String>,
350-
edition: Edition,
361+
/// Hash of some metadata from the manifest, such as "authors", or
362+
/// "description", which are exposed as environment variables during
363+
/// compilation.
364+
metadata: u64,
351365
}
352366

353367
impl Serialize for DepFingerprint {
@@ -407,8 +421,8 @@ impl Fingerprint {
407421
deps: Vec::new(),
408422
local: Vec::new(),
409423
memoized_hash: Mutex::new(None),
410-
edition: Edition::Edition2015,
411424
rustflags: Vec::new(),
425+
metadata: 0,
412426
}
413427
}
414428

@@ -463,8 +477,8 @@ impl Fingerprint {
463477
if self.local.len() != old.local.len() {
464478
bail!("local lens changed");
465479
}
466-
if self.edition != old.edition {
467-
bail!("edition changed")
480+
if self.metadata != old.metadata {
481+
bail!("metadata changed")
468482
}
469483
for (new, old) in self.local.iter().zip(&old.local) {
470484
match (new, old) {
@@ -546,12 +560,12 @@ impl hash::Hash for Fingerprint {
546560
profile,
547561
ref deps,
548562
ref local,
549-
edition,
563+
metadata,
550564
ref rustflags,
551565
..
552566
} = *self;
553567
(
554-
rustc, features, target, path, profile, local, edition, rustflags,
568+
rustc, features, target, path, profile, local, metadata, rustflags,
555569
)
556570
.hash(h);
557571

@@ -678,6 +692,9 @@ fn calculate<'a, 'cfg>(
678692
bcx.rustflags_args(unit)?
679693
};
680694
let profile_hash = util::hash_u64(&(&unit.profile, unit.mode, bcx.extra_args_for(unit)));
695+
// Include metadata since it is exposed as environment variables.
696+
let m = unit.pkg.manifest().metadata();
697+
let metadata = util::hash_u64(&(&m.authors, &m.description, &m.homepage, &m.repository));
681698
let fingerprint = Arc::new(Fingerprint {
682699
rustc: util::hash_u64(&bcx.rustc.verbose_version),
683700
target: util::hash_u64(&unit.target),
@@ -689,7 +706,7 @@ fn calculate<'a, 'cfg>(
689706
deps,
690707
local,
691708
memoized_hash: Mutex::new(None),
692-
edition: unit.target.edition(),
709+
metadata,
693710
rustflags: extra_flags,
694711
});
695712
cx.fingerprints.insert(*unit, Arc::clone(&fingerprint));

tests/testsuite/check.rs

+11-21
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@ use crate::support::install::exe;
44
use crate::support::paths::CargoPathExt;
55
use crate::support::registry::Package;
66
use crate::support::{basic_manifest, project};
7-
use glob::glob;
87

98
#[test]
109
fn check_success() {
@@ -623,43 +622,34 @@ fn check_artifacts() {
623622
.file("benches/b1.rs", "")
624623
.build();
625624

626-
let assert_glob = |path: &str, count: usize| {
627-
assert_eq!(
628-
glob(&p.root().join(path).to_str().unwrap())
629-
.unwrap()
630-
.count(),
631-
count
632-
);
633-
};
634-
635625
p.cargo("check").run();
636626
assert!(!p.root().join("target/debug/libfoo.rmeta").is_file());
637627
assert!(!p.root().join("target/debug/libfoo.rlib").is_file());
638628
assert!(!p.root().join("target/debug").join(exe("foo")).is_file());
639-
assert_glob("target/debug/deps/libfoo-*.rmeta", 2);
629+
assert_eq!(p.glob("target/debug/deps/libfoo-*.rmeta").count(), 2);
640630

641631
p.root().join("target").rm_rf();
642632
p.cargo("check --lib").run();
643633
assert!(!p.root().join("target/debug/libfoo.rmeta").is_file());
644634
assert!(!p.root().join("target/debug/libfoo.rlib").is_file());
645635
assert!(!p.root().join("target/debug").join(exe("foo")).is_file());
646-
assert_glob("target/debug/deps/libfoo-*.rmeta", 1);
636+
assert_eq!(p.glob("target/debug/deps/libfoo-*.rmeta").count(), 1);
647637

648638
p.root().join("target").rm_rf();
649639
p.cargo("check --bin foo").run();
650640
assert!(!p.root().join("target/debug/libfoo.rmeta").is_file());
651641
assert!(!p.root().join("target/debug/libfoo.rlib").is_file());
652642
assert!(!p.root().join("target/debug").join(exe("foo")).is_file());
653-
assert_glob("target/debug/deps/libfoo-*.rmeta", 2);
643+
assert_eq!(p.glob("target/debug/deps/libfoo-*.rmeta").count(), 2);
654644

655645
p.root().join("target").rm_rf();
656646
p.cargo("check --test t1").run();
657647
assert!(!p.root().join("target/debug/libfoo.rmeta").is_file());
658648
assert!(!p.root().join("target/debug/libfoo.rlib").is_file());
659649
assert!(!p.root().join("target/debug").join(exe("foo")).is_file());
660-
assert_glob("target/debug/t1-*", 0);
661-
assert_glob("target/debug/deps/libfoo-*.rmeta", 1);
662-
assert_glob("target/debug/deps/libt1-*.rmeta", 1);
650+
assert_eq!(p.glob("target/debug/t1-*").count(), 0);
651+
assert_eq!(p.glob("target/debug/deps/libfoo-*.rmeta").count(), 1);
652+
assert_eq!(p.glob("target/debug/deps/libt1-*.rmeta").count(), 1);
663653

664654
p.root().join("target").rm_rf();
665655
p.cargo("check --example ex1").run();
@@ -670,17 +660,17 @@ fn check_artifacts() {
670660
.join("target/debug/examples")
671661
.join(exe("ex1"))
672662
.is_file());
673-
assert_glob("target/debug/deps/libfoo-*.rmeta", 1);
674-
assert_glob("target/debug/examples/libex1-*.rmeta", 1);
663+
assert_eq!(p.glob("target/debug/deps/libfoo-*.rmeta").count(), 1);
664+
assert_eq!(p.glob("target/debug/examples/libex1-*.rmeta").count(), 1);
675665

676666
p.root().join("target").rm_rf();
677667
p.cargo("check --bench b1").run();
678668
assert!(!p.root().join("target/debug/libfoo.rmeta").is_file());
679669
assert!(!p.root().join("target/debug/libfoo.rlib").is_file());
680670
assert!(!p.root().join("target/debug").join(exe("foo")).is_file());
681-
assert_glob("target/debug/b1-*", 0);
682-
assert_glob("target/debug/deps/libfoo-*.rmeta", 1);
683-
assert_glob("target/debug/deps/libb1-*.rmeta", 1);
671+
assert_eq!(p.glob("target/debug/b1-*").count(), 0);
672+
assert_eq!(p.glob("target/debug/deps/libfoo-*.rmeta").count(), 1);
673+
assert_eq!(p.glob("target/debug/deps/libb1-*.rmeta").count(), 1);
684674
}
685675

686676
#[test]

tests/testsuite/doc.rs

+2-19
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,6 @@ use std::fs::{self, File};
22
use std::io::Read;
33
use std::str;
44

5-
use glob::glob;
6-
75
use crate::support::paths::CargoPathExt;
86
use crate::support::registry::Package;
97
use crate::support::{basic_lib_manifest, basic_manifest, git, project};
@@ -113,23 +111,8 @@ fn doc_deps() {
113111
assert!(p.root().join("target/doc/bar/index.html").is_file());
114112

115113
// Verify that it only emits rmeta for the dependency.
116-
assert_eq!(
117-
glob(&p.root().join("target/debug/**/*.rlib").to_str().unwrap())
118-
.unwrap()
119-
.count(),
120-
0
121-
);
122-
assert_eq!(
123-
glob(
124-
&p.root()
125-
.join("target/debug/deps/libbar-*.rmeta")
126-
.to_str()
127-
.unwrap()
128-
)
129-
.unwrap()
130-
.count(),
131-
1
132-
);
114+
assert_eq!(p.glob("target/debug/**/*.rlib").count(), 0);
115+
assert_eq!(p.glob("target/debug/deps/libbar-*.rmeta").count(), 1);
133116

134117
p.cargo("doc")
135118
.env("RUST_LOG", "cargo::ops::cargo_rustc::fingerprint")

tests/testsuite/freshness.rs

+73
Original file line numberDiff line numberDiff line change
@@ -1885,3 +1885,76 @@ fn simulated_docker_deps_stay_cached() {
18851885
.run();
18861886
}
18871887
}
1888+
1889+
#[test]
1890+
fn metadata_change_invalidates() {
1891+
let p = project()
1892+
.file(
1893+
"Cargo.toml",
1894+
r#"
1895+
[package]
1896+
name = "foo"
1897+
version = "0.1.0"
1898+
"#,
1899+
)
1900+
.file("src/lib.rs", "")
1901+
.build();
1902+
1903+
p.cargo("build").run();
1904+
1905+
for attr in &[
1906+
"authors = [\"foo\"]",
1907+
"description = \"desc\"",
1908+
"homepage = \"https://example.com\"",
1909+
"repository =\"https://example.com\"",
1910+
] {
1911+
let mut file = OpenOptions::new()
1912+
.write(true)
1913+
.append(true)
1914+
.open(p.root().join("Cargo.toml"))
1915+
.unwrap();
1916+
writeln!(file, "{}", attr).unwrap();
1917+
p.cargo("build")
1918+
.with_stderr_contains("[COMPILING] foo [..]")
1919+
.run();
1920+
}
1921+
p.cargo("build -v")
1922+
.with_stderr_contains("[FRESH] foo[..]")
1923+
.run();
1924+
assert_eq!(p.glob("target/debug/deps/libfoo-*.rlib").count(), 1);
1925+
}
1926+
1927+
#[test]
1928+
fn edition_change_invalidates() {
1929+
const MANIFEST: &str = r#"
1930+
[package]
1931+
name = "foo"
1932+
version = "0.1.0"
1933+
"#;
1934+
let p = project()
1935+
.file("Cargo.toml", MANIFEST)
1936+
.file("src/lib.rs", "")
1937+
.build();
1938+
p.cargo("build").run();
1939+
p.change_file("Cargo.toml", &format!("{}edition = \"2018\"", MANIFEST));
1940+
p.cargo("build")
1941+
.with_stderr_contains("[COMPILING] foo [..]")
1942+
.run();
1943+
p.change_file(
1944+
"Cargo.toml",
1945+
&format!(
1946+
r#"{}edition = "2018"
1947+
[lib]
1948+
edition = "2015"
1949+
"#,
1950+
MANIFEST
1951+
),
1952+
);
1953+
p.cargo("build")
1954+
.with_stderr_contains("[COMPILING] foo [..]")
1955+
.run();
1956+
p.cargo("build -v")
1957+
.with_stderr_contains("[FRESH] foo[..]")
1958+
.run();
1959+
assert_eq!(p.glob("target/debug/deps/libfoo-*.rlib").count(), 1);
1960+
}

tests/testsuite/metabuild.rs

+3-31
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@ use crate::support::{
22
basic_lib_manifest, basic_manifest, is_coarse_mtime, project, registry::Package, rustc_host,
33
Project,
44
};
5-
use glob::glob;
65
use serde_json;
76
use std::str;
87

@@ -537,17 +536,7 @@ fn metabuild_build_plan() {
537536
)
538537
.run();
539538

540-
assert_eq!(
541-
glob(
542-
&p.root()
543-
.join("target/.metabuild/metabuild-foo-*.rs")
544-
.to_str()
545-
.unwrap()
546-
)
547-
.unwrap()
548-
.count(),
549-
1
550-
);
539+
assert_eq!(p.glob("target/.metabuild/metabuild-foo-*.rs").count(), 1);
551540
}
552541

553542
#[test]
@@ -623,14 +612,7 @@ fn metabuild_two_versions() {
623612
.run();
624613

625614
assert_eq!(
626-
glob(
627-
&p.root()
628-
.join("target/.metabuild/metabuild-member?-*.rs")
629-
.to_str()
630-
.unwrap()
631-
)
632-
.unwrap()
633-
.count(),
615+
p.glob("target/.metabuild/metabuild-member?-*.rs").count(),
634616
2
635617
);
636618
}
@@ -681,17 +663,7 @@ fn metabuild_external_dependency() {
681663
.with_stdout_contains("[dep 1.0.0] Hello mb")
682664
.run();
683665

684-
assert_eq!(
685-
glob(
686-
&p.root()
687-
.join("target/.metabuild/metabuild-dep-*.rs")
688-
.to_str()
689-
.unwrap()
690-
)
691-
.unwrap()
692-
.count(),
693-
1
694-
);
666+
assert_eq!(p.glob("target/.metabuild/metabuild-dep-*.rs").count(), 1);
695667
}
696668

697669
#[test]

0 commit comments

Comments
 (0)