diff --git a/src/cargo/core/compiler/fingerprint/mod.rs b/src/cargo/core/compiler/fingerprint/mod.rs index e6fff9093..0b8a55059 100644 --- a/src/cargo/core/compiler/fingerprint/mod.rs +++ b/src/cargo/core/compiler/fingerprint/mod.rs @@ -362,8 +362,8 @@ mod dirty_reason; use std::collections::hash_map::{Entry, HashMap}; - use std::env; +use std::ffi::OsString; use std::fmt::{self, Display}; use std::fs::{self, File}; use std::hash::{self, Hash, Hasher}; @@ -849,7 +849,11 @@ impl LocalFingerprint { .to_string(), ) } else { - gctx.get_env(key).ok() + if let Some(value) = gctx.env_config()?.get(key) { + value.to_str().and_then(|s| Some(s.to_string())) + } else { + gctx.get_env(key).ok() + } }; if current == *previous { continue; @@ -2124,6 +2128,9 @@ enum DepInfoPathType { /// /// The serialized Cargo format will contain a list of files, all of which are /// relative if they're under `root`. or absolute if they're elsewhere. +/// +/// The `env_config` argument is a set of environment variables that are +/// defined in `[env]` table of the `config.toml`. pub fn translate_dep_info( rustc_dep_info: &Path, cargo_dep_info: &Path, @@ -2132,6 +2139,7 @@ pub fn translate_dep_info( target_root: &Path, rustc_cmd: &ProcessBuilder, allow_package: bool, + env_config: &Arc>, ) -> CargoResult<()> { let depinfo = parse_rustc_dep_info(rustc_dep_info)?; @@ -2168,9 +2176,11 @@ pub fn translate_dep_info( // This also includes `CARGO` since if the code is explicitly wanting to // know that path, it should be rebuilt if it changes. The CARGO path is // not tracked elsewhere in the fingerprint. - on_disk_info - .env - .retain(|(key, _)| !rustc_cmd.get_envs().contains_key(key) || key == CARGO_ENV); + // + // For cargo#13280, We trace env vars that are defined in the `[env]` config table. + on_disk_info.env.retain(|(key, _)| { + env_config.contains_key(key) || !rustc_cmd.get_envs().contains_key(key) || key == CARGO_ENV + }); let serialize_path = |file| { // The path may be absolute or relative, canonical or not. Make sure diff --git a/src/cargo/core/compiler/mod.rs b/src/cargo/core/compiler/mod.rs index ff830c66d..5d0e2962c 100644 --- a/src/cargo/core/compiler/mod.rs +++ b/src/cargo/core/compiler/mod.rs @@ -330,7 +330,7 @@ fn rustc( if hide_diagnostics_for_scrape_unit { output_options.show_diagnostics = false; } - + let env_config = Arc::clone(build_runner.bcx.gctx.env_config()?); return Ok(Work::new(move |state| { // Artifacts are in a different location than typical units, // hence we must assure the crate- and target-dependent @@ -459,6 +459,7 @@ fn rustc( &rustc, // Do not track source files in the fingerprint for registry dependencies. is_local, + &env_config, ) .with_context(|| { internal(format!( diff --git a/tests/testsuite/cargo_env_config.rs b/tests/testsuite/cargo_env_config.rs index 3f10efd2f..5f420d311 100644 --- a/tests/testsuite/cargo_env_config.rs +++ b/tests/testsuite/cargo_env_config.rs @@ -315,10 +315,11 @@ from-config p.cargo("run") .env("ENV_TEST", "from-env") .with_stdout_data(str![[r#" -from-config +from-env "#]]) .with_stderr_data(str![[r#" +[COMPILING] foo v0.5.0 ([ROOT]/foo) [FINISHED] `dev` profile [unoptimized + debuginfo] target(s) in [ELAPSED]s [RUNNING] `target/debug/foo[EXE]` @@ -328,7 +329,7 @@ from-config p.cargo("run") .env("ENV_TEST", "from-env") .with_stdout_data(str![[r#" -from-config +from-env "#]]) .with_stderr_data(str![[r#" @@ -417,10 +418,11 @@ one p.cargo(r#"run --config 'env.ENV_TEST="two"'"#) .with_stdout_data(str![[r#" -one +two "#]]) .with_stderr_data(str![[r#" +[COMPILING] foo v0.5.0 ([ROOT]/foo) [FINISHED] `dev` profile [unoptimized + debuginfo] target(s) in [ELAPSED]s [RUNNING] `target/debug/foo[EXE]` @@ -429,7 +431,7 @@ one // This identical cargo invocation is to ensure no rebuild happen. p.cargo(r#"run --config 'env.ENV_TEST="two"'"#) .with_stdout_data(str![[r#" -one +two "#]]) .with_stderr_data(str![[r#"