From 419a56f6174cf8d5a9318c092cc491df5f282fe5 Mon Sep 17 00:00:00 2001 From: Weihang Lo Date: Fri, 3 Feb 2023 13:52:51 +0000 Subject: [PATCH 1/2] test: verify source before recompile --- tests/testsuite/freshness.rs | 63 ++++++++++++++++++++++++++++++++++++ 1 file changed, 63 insertions(+) diff --git a/tests/testsuite/freshness.rs b/tests/testsuite/freshness.rs index 6853af13eed..eecbf67b713 100644 --- a/tests/testsuite/freshness.rs +++ b/tests/testsuite/freshness.rs @@ -2744,3 +2744,66 @@ fn changing_linker() { ) .run(); } + +#[cargo_test] +fn verify_source_before_recompile() { + Package::new("bar", "0.1.0") + .file("src/lib.rs", "") + .publish(); + let p = project() + .file( + "Cargo.toml", + r#" + [package] + name = "foo" + version = "0.1.0" + + [dependencies] + bar = "0.1.0" + "#, + ) + .file("src/lib.rs", "") + .build(); + + p.cargo("vendor --respect-source-config").run(); + p.change_file( + ".cargo/config.toml", + r#" + [source.crates-io] + replace-with = 'vendor' + + [source.vendor] + directory = 'vendor' + "#, + ); + // Sanity check: vendoring works correctly. + p.cargo("check --verbose") + .with_stderr_contains("[RUNNING] `rustc --crate-name bar [CWD]/vendor/bar/src/lib.rs[..]") + .run(); + // Now modify vendored crate. + p.change_file( + "vendor/bar/src/lib.rs", + r#"compile_error!("You shall not pass!");"#, + ); + // Should ignore modifed sources without any recompile. + p.cargo("check --verbose") + .with_stderr( + "\ +[FRESH] bar v0.1.0 +[FRESH] foo v0.1.0 ([CWD]) +[FINISHED] dev [..] +", + ) + .run(); + + // Add a `RUSTFLAGS` to trigger a recompile. + // + // Cargo should refuse to build because of checksum verfication failure. + // Cargo shouldn't recompile dependency `bar`. + // TODO: fix this wrong behaviour + p.cargo("check --verbose") + .env("RUSTFLAGS", "-W warnings") + .with_status(101) + .with_stderr_contains("[..]error: You shall not pass![..]") + .run(); +} From 98a73394f17e36d1177a1445a4fe68651d2225bd Mon Sep 17 00:00:00 2001 From: Weihang Lo Date: Fri, 3 Feb 2023 14:14:39 +0000 Subject: [PATCH 2/2] fix: verify source before recompile This fixes a regression introduced by #11407, which Cargo should always verify a source before it recompiles. --- src/cargo/core/compiler/fingerprint.rs | 12 ++++++++---- tests/testsuite/freshness.rs | 11 +++++++++-- 2 files changed, 17 insertions(+), 6 deletions(-) diff --git a/src/cargo/core/compiler/fingerprint.rs b/src/cargo/core/compiler/fingerprint.rs index 10e40e14ffe..fc3ce5e9b9d 100644 --- a/src/cargo/core/compiler/fingerprint.rs +++ b/src/cargo/core/compiler/fingerprint.rs @@ -391,9 +391,9 @@ pub fn prepare_target(cx: &mut Context<'_, '_>, unit: &Unit, force: bool) -> Car let compare = compare_old_fingerprint(&loc, &*fingerprint, mtime_on_use); log_compare(unit, &compare); - // If our comparison failed (e.g., we're going to trigger a rebuild of this - // crate), then we also ensure the source of the crate passes all - // verification checks before we build it. + // If our comparison failed or reported dirty (e.g., we're going to trigger + // a rebuild of this crate), then we also ensure the source of the crate + // passes all verification checks before we build it. // // The `Source::verify` method is intended to allow sources to execute // pre-build checks to ensure that the relevant source code is all @@ -401,7 +401,11 @@ pub fn prepare_target(cx: &mut Context<'_, '_>, unit: &Unit, force: bool) -> Car // directory sources which will use this hook to perform an integrity check // on all files in the source to ensure they haven't changed. If they have // changed then an error is issued. - if compare.is_err() { + if compare + .as_ref() + .map(|dirty| dirty.is_some()) + .unwrap_or(true) + { let source_id = unit.pkg.package_id().source_id(); let sources = bcx.packages.sources(); let source = sources diff --git a/tests/testsuite/freshness.rs b/tests/testsuite/freshness.rs index eecbf67b713..86b186af847 100644 --- a/tests/testsuite/freshness.rs +++ b/tests/testsuite/freshness.rs @@ -2800,10 +2800,17 @@ fn verify_source_before_recompile() { // // Cargo should refuse to build because of checksum verfication failure. // Cargo shouldn't recompile dependency `bar`. - // TODO: fix this wrong behaviour p.cargo("check --verbose") .env("RUSTFLAGS", "-W warnings") .with_status(101) - .with_stderr_contains("[..]error: You shall not pass![..]") + .with_stderr( + "\ +error: the listed checksum of `[CWD]/vendor/bar/src/lib.rs` has changed: +expected: [..] +actual: [..] + +directory sources are not [..] +", + ) .run(); }