From beee41d3ca3be170ec511d4a445766f5566225fb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ralph=20K=C3=BCpper?= Date: Sat, 5 Sep 2026 06:51:58 +0200 Subject: [PATCH 1/2] fix(compile): key the build cache on PERRY_CONCAT_SITE_CACHE MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit `codegen_env_vars_are_build_cache_inputs` scans `crates/perry-codegen/src` for every `env::var("PERRY_…")` and requires each one to be either a build-cache input or an explicit, justified exclusion. Since #9514 added the per-site concat cache, `PERRY_CONCAT_SITE_CACHE` has been neither, so the `cargo-test` job fails: test commands::compile::build_cache::tests::codegen_env_vars_are_build_cache_inputs ... FAILED panicked at crates/perry/src/commands/compile/build_cache.rs:410:9 these codegen env vars key neither the build cache nor an exclusion (#6394's rule): ["PERRY_CONCAT_SITE_CACHE"] This is the guard working, not a stale test. `concat_site_cache.rs:78` reads the var as a build-time kill switch — its own module doc says "`PERRY_CONCAT_SITE_CACHE=0` removes the lane at build time" — and `crates/perry/tests/concat_site_cache.rs:243` compiles with the switch off and asserts the emitted code differs. So it demonstrably changes generated code, which makes it a cache *input*, not an exclusion: without this entry a build with the switch flipped can be served a stale cached object from a build with it in the other state. Culprit: 0b68a25cf perf(strings): per-site concat cache for "literal" + proven-small value (#9514) Claude-Session: https://claude.ai/code/session_01YPfnmWZmSpSWpmnoXvH8z2 --- crates/perry/src/commands/compile/build_cache.rs | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/crates/perry/src/commands/compile/build_cache.rs b/crates/perry/src/commands/compile/build_cache.rs index 285918a5f9..340efb9a06 100644 --- a/crates/perry/src/commands/compile/build_cache.rs +++ b/crates/perry/src/commands/compile/build_cache.rs @@ -94,6 +94,11 @@ const BUILD_CACHE_ENV_VARS: &[&str] = &[ // #9026: gates the once-per-closure-entry resolution of read-only boxed // capture cells — flipping it changes every closure body that qualifies. "PERRY_BOX_CAPTURE_ENTRY_CELLS", + // #9514: gates the per-site concat cache. `PERRY_CONCAT_SITE_CACHE=0` + // removes the lane at build time, so a qualifying `"literal" + value` + // site lowers to a different sequence with it on and off and a cached + // object from one setting must not serve the other. + "PERRY_CONCAT_SITE_CACHE", // The guarded-preinline IR-size ceiling: functions on either side of the // budget inline differently, so a run with a raised ceiling must not be // served objects a default run produced (same rule as the RS4GC budget From 0a1c4677bc466cf8820dff9b79d182d56425e5c3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ralph=20K=C3=BCpper?= Date: Sat, 5 Sep 2026 06:52:27 +0200 Subject: [PATCH 2/2] docs(changelog): add PR 9777 fragment Claude-Session: https://claude.ai/code/session_01YPfnmWZmSpSWpmnoXvH8z2 --- changelog.d/9777-build-cache-concat-site-cache.md | 10 ++++++++++ 1 file changed, 10 insertions(+) create mode 100644 changelog.d/9777-build-cache-concat-site-cache.md diff --git a/changelog.d/9777-build-cache-concat-site-cache.md b/changelog.d/9777-build-cache-concat-site-cache.md new file mode 100644 index 0000000000..fa6c1dedf7 --- /dev/null +++ b/changelog.d/9777-build-cache-concat-site-cache.md @@ -0,0 +1,10 @@ +**`PERRY_CONCAT_SITE_CACHE` is now a build-cache input.** #9514's per-site +concat cache reads the variable as a build-time kill switch — setting it to +`0` removes the lowering lane entirely — but it was registered neither in +`BUILD_CACHE_ENV_VARS` nor as a justified exclusion. A build with the switch +flipped could therefore be served a cached object produced with it in the +other state. + +`codegen_env_vars_are_build_cache_inputs` caught this by scanning +`crates/perry-codegen/src` for every `env::var("PERRY_…")`, which is why the +check scans the source instead of trusting a hand-maintained list.