From e7ca1af04797ead11fc066ef96844d1d6e0fe07a Mon Sep 17 00:00:00 2001 From: LuuuX Date: Sat, 16 Mar 2024 19:21:13 +0800 Subject: [PATCH 1/3] Add test to ensure fix it --- tests/testsuite/cargo_env_config.rs | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/tests/testsuite/cargo_env_config.rs b/tests/testsuite/cargo_env_config.rs index d38847fad64..61789163aa5 100644 --- a/tests/testsuite/cargo_env_config.rs +++ b/tests/testsuite/cargo_env_config.rs @@ -239,3 +239,32 @@ fn env_applied_to_target_info_discovery_rustc() { .with_stderr_contains("MAIN ENV_TEST:from-env") .run(); } + +#[cargo_test] +fn env_reset() { + let p = project() + .file("Cargo.toml", &basic_bin_manifest("foo")) + .file( + "src/main.rs", + r#" + use std::env; + fn main() { + println!( "{}", env!("ENV_TEST") ); + } + "#, + ) + .file( + ".cargo/config.toml", + r#" + [env] + ENV_TEST = "from-config" + "#, + ) + .build(); + + p.cargo("run").with_stdout_contains("from-config").run(); + p.cargo("run") + .env("ENV_TEST", "from-env") + .with_stdout_contains("from-env") + .run(); +} From 02a0e0918ee704d4e50e19248b868350ec5be767 Mon Sep 17 00:00:00 2001 From: LuuuX Date: Sat, 16 Mar 2024 19:29:08 +0800 Subject: [PATCH 2/3] Add detect while using environment variable --- src/cargo/core/compiler/mod.rs | 57 ++++++++++++++++++++++------------ 1 file changed, 37 insertions(+), 20 deletions(-) diff --git a/src/cargo/core/compiler/mod.rs b/src/cargo/core/compiler/mod.rs index bed881d50db..3f8e54491d1 100644 --- a/src/cargo/core/compiler/mod.rs +++ b/src/cargo/core/compiler/mod.rs @@ -190,27 +190,29 @@ fn compile<'gctx>( } else { let force = exec.force_rebuild(unit) || force_rebuild; let mut job = fingerprint::prepare_target(build_runner, unit, force)?; - job.before(if job.freshness().is_dirty() { - let work = if unit.mode.is_doc() || unit.mode.is_doc_scrape() { - rustdoc(build_runner, unit)? + job.before( + if job.freshness().is_dirty() || env_config_modified(bcx.gctx)? { + let work = if unit.mode.is_doc() || unit.mode.is_doc_scrape() { + rustdoc(build_runner, unit)? + } else { + rustc(build_runner, unit, exec)? + }; + work.then(link_targets(build_runner, unit, false)?) } else { - rustc(build_runner, unit, exec)? - }; - work.then(link_targets(build_runner, unit, false)?) - } else { - // We always replay the output cache, - // since it might contain future-incompat-report messages - let work = replay_output_cache( - unit.pkg.package_id(), - PathBuf::from(unit.pkg.manifest_path()), - &unit.target, - build_runner.files().message_cache_path(unit), - build_runner.bcx.build_config.message_format, - unit.show_warnings(bcx.gctx), - ); - // Need to link targets on both the dirty and fresh. - work.then(link_targets(build_runner, unit, true)?) - }); + // We always replay the output cache, + // since it might contain future-incompat-report messages + let work = replay_output_cache( + unit.pkg.package_id(), + PathBuf::from(unit.pkg.manifest_path()), + &unit.target, + build_runner.files().message_cache_path(unit), + build_runner.bcx.build_config.message_format, + unit.show_warnings(bcx.gctx), + ); + // Need to link targets on both the dirty and fresh. + work.then(link_targets(build_runner, unit, true)?) + }, + ); job }; @@ -1926,6 +1928,21 @@ fn should_include_scrape_units(bcx: &BuildContext<'_, '_>, unit: &Unit) -> bool unit.mode.is_doc() && bcx.scrape_units.len() > 0 && bcx.ws.unit_needs_doc_scrape(unit) } +/// Detects if environment variables from config `[env]` is newly modified. +fn env_config_modified(gctx: &crate::GlobalContext) -> CargoResult { + for (key, value) in gctx.env_config()?.iter() { + if !gctx.env().any(|(k, _)| k == key) { + continue; + } + + if !value.is_force() && gctx.env().find(|(k, _)| k == key).is_some() { + return Ok(true); + } + } + + Ok(false) +} + /// Gets the file path of function call information output from `rustdoc`. fn scrape_output_path(build_runner: &BuildRunner<'_, '_>, unit: &Unit) -> CargoResult { assert!(unit.mode.is_doc() || unit.mode.is_doc_scrape()); From c166c14e0b385baae6e64b44cef59c5ac7bc1f67 Mon Sep 17 00:00:00 2001 From: LuuuX Date: Sun, 17 Mar 2024 00:34:38 +0800 Subject: [PATCH 3/3] Move detection to be in the fingerprint code --- .../core/compiler/fingerprint/dirty_reason.rs | 4 ++ src/cargo/core/compiler/fingerprint/mod.rs | 24 +++++++- src/cargo/core/compiler/mod.rs | 57 +++++++------------ 3 files changed, 46 insertions(+), 39 deletions(-) diff --git a/src/cargo/core/compiler/fingerprint/dirty_reason.rs b/src/cargo/core/compiler/fingerprint/dirty_reason.rs index cb6548a41a5..ba43e358973 100644 --- a/src/cargo/core/compiler/fingerprint/dirty_reason.rs +++ b/src/cargo/core/compiler/fingerprint/dirty_reason.rs @@ -29,6 +29,7 @@ pub enum DirtyReason { MetadataChanged, ConfigSettingsChanged, CompileKindChanged, + EnvConfigChanged, LocalLengthsChanged, PrecalculatedComponentsChanged { old: String, @@ -172,6 +173,9 @@ impl DirtyReason { DirtyReason::CompileKindChanged => { s.dirty_because(unit, "the rustc compile kind changed") } + DirtyReason::EnvConfigChanged => { + s.dirty_because(unit, "the environment variable changed") + } DirtyReason::LocalLengthsChanged => { s.dirty_because(unit, "the local lengths changed")?; s.note( diff --git a/src/cargo/core/compiler/fingerprint/mod.rs b/src/cargo/core/compiler/fingerprint/mod.rs index 4fdbed220c1..c474d5f24b4 100644 --- a/src/cargo/core/compiler/fingerprint/mod.rs +++ b/src/cargo/core/compiler/fingerprint/mod.rs @@ -420,8 +420,14 @@ pub fn prepare_target( let mtime_on_use = build_runner.bcx.gctx.cli_unstable().mtime_on_use; let dirty_reason = compare_old_fingerprint(unit, &loc, &*fingerprint, mtime_on_use, force); - let Some(dirty_reason) = dirty_reason else { - return Ok(Job::new_fresh()); + let dirty_reason = match dirty_reason { + Some(dr) => dr, + None => { + let Some(dr) = env_config_modified(bcx.gctx) else { + return Ok(Job::new_fresh()); + }; + dr + } }; // We're going to rebuild, so ensure the source of the crate passes all @@ -2231,3 +2237,17 @@ pub fn parse_rustc_dep_info(rustc_dep_info: &Path) -> CargoResult Ok(ret) } } + +/// Detects if environment variables from config `[env]` is newly seted. +fn env_config_modified(gctx: &crate::GlobalContext) -> Option { + for (key, value) in gctx.env_config().unwrap().iter() { + if !gctx.env().any(|(k, _)| k == key) { + continue; + } + + if !value.is_force() && gctx.env().find(|(k, _)| k == key).is_some() { + return Some(DirtyReason::EnvConfigChanged); + } + } + None +} diff --git a/src/cargo/core/compiler/mod.rs b/src/cargo/core/compiler/mod.rs index 3f8e54491d1..bed881d50db 100644 --- a/src/cargo/core/compiler/mod.rs +++ b/src/cargo/core/compiler/mod.rs @@ -190,29 +190,27 @@ fn compile<'gctx>( } else { let force = exec.force_rebuild(unit) || force_rebuild; let mut job = fingerprint::prepare_target(build_runner, unit, force)?; - job.before( - if job.freshness().is_dirty() || env_config_modified(bcx.gctx)? { - let work = if unit.mode.is_doc() || unit.mode.is_doc_scrape() { - rustdoc(build_runner, unit)? - } else { - rustc(build_runner, unit, exec)? - }; - work.then(link_targets(build_runner, unit, false)?) + job.before(if job.freshness().is_dirty() { + let work = if unit.mode.is_doc() || unit.mode.is_doc_scrape() { + rustdoc(build_runner, unit)? } else { - // We always replay the output cache, - // since it might contain future-incompat-report messages - let work = replay_output_cache( - unit.pkg.package_id(), - PathBuf::from(unit.pkg.manifest_path()), - &unit.target, - build_runner.files().message_cache_path(unit), - build_runner.bcx.build_config.message_format, - unit.show_warnings(bcx.gctx), - ); - // Need to link targets on both the dirty and fresh. - work.then(link_targets(build_runner, unit, true)?) - }, - ); + rustc(build_runner, unit, exec)? + }; + work.then(link_targets(build_runner, unit, false)?) + } else { + // We always replay the output cache, + // since it might contain future-incompat-report messages + let work = replay_output_cache( + unit.pkg.package_id(), + PathBuf::from(unit.pkg.manifest_path()), + &unit.target, + build_runner.files().message_cache_path(unit), + build_runner.bcx.build_config.message_format, + unit.show_warnings(bcx.gctx), + ); + // Need to link targets on both the dirty and fresh. + work.then(link_targets(build_runner, unit, true)?) + }); job }; @@ -1928,21 +1926,6 @@ fn should_include_scrape_units(bcx: &BuildContext<'_, '_>, unit: &Unit) -> bool unit.mode.is_doc() && bcx.scrape_units.len() > 0 && bcx.ws.unit_needs_doc_scrape(unit) } -/// Detects if environment variables from config `[env]` is newly modified. -fn env_config_modified(gctx: &crate::GlobalContext) -> CargoResult { - for (key, value) in gctx.env_config()?.iter() { - if !gctx.env().any(|(k, _)| k == key) { - continue; - } - - if !value.is_force() && gctx.env().find(|(k, _)| k == key).is_some() { - return Ok(true); - } - } - - Ok(false) -} - /// Gets the file path of function call information output from `rustdoc`. fn scrape_output_path(build_runner: &BuildRunner<'_, '_>, unit: &Unit) -> CargoResult { assert!(unit.mode.is_doc() || unit.mode.is_doc_scrape());