You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Several perry-codegen integration suites are red on main (f05ae3b), arm64 macOS, debug:
suite
default
tests/shadow_slot_hygiene.rs
0 passed, 12 failed
tests/scalar_replaced_slot_roots.rs
2 passed, 9 failed
tests/temp_root_operand_temporaries.rs
12 passed, 7 failed
tests/temp_root_argument_temporaries.rs
3 passed, 4 failed
tests/native_proof_regressions.rs
249 passed, 4 failed (3 of them this cause)
Every one of these failures reproduces when the test is run alone, so this is not order dependence and it is unrelated to #7490 (whose cascade was a poisoned mutex in typed_feedback.rs, fixed in #7492).
Cause
#7370 made native roots (statepoints) the default lowering. These suites assert on the shadow-stack lowering — they used to get it by accident, because there was only one default. The failure text says so directly:
box pointer slot should be stored as i64 before helper edges:
call i64 @js_box_alloc_bits(i64 9222246136947933185)
%rs4gc.s3 = inttoptr i64 %r1 to ptr addrspace(1)
That much was already understood: codegen/helpers.rs grew NativeRootsPin::shadow() for exactly this, with the comment "a test that asserts on shadow-stack IR has to SAY so … Eight tests broke on exactly this when the default flipped, and every one of them was correct about what it asserted."
But NativeRootsPin is #[cfg(test)], so it is compiled only into the crate's own unit-test build and is unreachable from tests/*.rs. The in-crate unit tests were repaired; the integration suites had no pin to reach for and were left red. They do not run per-PR (nightly/tag only — the CLAUDE.md pitfall), so nothing turned red on the merge.
Evidence that the lowering is the variable
Full --no-fail-fast -- --test-threads=1 sweeps of -p perry-codegen --tests, default vs. the process-global override:
shadow_slot_hygiene going 0/12 → 11/12 is the diagnosis. But native_proof_regressions loses 13 tests under PERRY_RS4GC=0 — its whole invalidation::* family asserts the native-roots lowering and is correct today. So there is no single global setting that satisfies the set: the pin has to be per test, which is precisely what NativeRootsPin is for.
Within native_proof_regressions, three of the four default failures are healed by PERRY_RS4GC=0 and belong here:
(The fourth, integer_modulo::i32_counter_mod_unsafe_or_nonliteral_divisors_keep_frem, is unmoved by the lowering and is tracked in the sibling issue.)
PERRY_RS4GC is also the wrong instrument for a test to reach for: rs4gc_env_override() caches it in a process-global OnceLock, so the first caller in the binary pins the answer for every later test — a fresh instance of the same first-caller-wins hazard.
Pin each suite to the lowering it actually asserts, and say so at the top of the file. Both lowerings are correct rooting mechanisms; a test asserting one has to declare which.
Triage the residue — the lowering default is the dominant cause but not the only one. Under PERRY_RS4GC=0, shadow_slot_hygiene still has 1 failure, scalar_replaced_slot_roots 6, temp_root_operand_temporaries 6, and temp_root_argument_temporaries is completely unmoved at 3/7.
Consider whether any of these belong in a per-PR gate. A suite that can sit 0/12 red without anything going red is documentation, not a gate.
Repro
cargo test -p perry-codegen --tests --no-fail-fast -- --test-threads=1
# then the same command prefixed with PERRY_RS4GC=0 for the contrast above
Beware truncating that output — piping it through head silently drops the tail of the target list, which is how temp_root_operand_temporaries and typed_shape_descriptors were initially missed here.
Symptom
Several
perry-codegenintegration suites are red onmain(f05ae3b), arm64 macOS, debug:tests/shadow_slot_hygiene.rstests/scalar_replaced_slot_roots.rstests/temp_root_operand_temporaries.rstests/temp_root_argument_temporaries.rstests/native_proof_regressions.rsEvery one of these failures reproduces when the test is run alone, so this is not order dependence and it is unrelated to #7490 (whose cascade was a poisoned mutex in
typed_feedback.rs, fixed in #7492).Cause
#7370 made native roots (statepoints) the default lowering. These suites assert on the shadow-stack lowering — they used to get it by accident, because there was only one default. The failure text says so directly:
That much was already understood:
codegen/helpers.rsgrewNativeRootsPin::shadow()for exactly this, with the comment "a test that asserts on shadow-stack IR has to SAY so … Eight tests broke on exactly this when the default flipped, and every one of them was correct about what it asserted."But
NativeRootsPinis#[cfg(test)], so it is compiled only into the crate's own unit-test build and is unreachable fromtests/*.rs. The in-crate unit tests were repaired; the integration suites had no pin to reach for and were left red. They do not run per-PR (nightly/tag only — the CLAUDE.md pitfall), so nothing turned red on the merge.Evidence that the lowering is the variable
Full
--no-fail-fast -- --test-threads=1sweeps of-p perry-codegen --tests, default vs. the process-global override:shadow_slot_hygienegoing 0/12 → 11/12 is the diagnosis. Butnative_proof_regressionsloses 13 tests underPERRY_RS4GC=0— its wholeinvalidation::*family asserts the native-roots lowering and is correct today. So there is no single global setting that satisfies the set: the pin has to be per test, which is precisely whatNativeRootsPinis for.Within
native_proof_regressions, three of the four default failures are healed byPERRY_RS4GC=0and belong here:boxed_local_slot_uses_i64_js_value_bits_until_helper_edgesboxed_param_slot_uses_i64_js_value_bits_until_helper_edgestyped_f64_receiver_method_clone_raw_loads_after_composed_guards(The fourth,
integer_modulo::i32_counter_mod_unsafe_or_nonliteral_divisors_keep_frem, is unmoved by the lowering and is tracked in the sibling issue.)PERRY_RS4GCis also the wrong instrument for a test to reach for:rs4gc_env_override()caches it in a process-globalOnceLock, so the first caller in the binary pins the answer for every later test — a fresh instance of the same first-caller-wins hazard.Suggested shape
#[doc(hidden)] pubbehind atestingcargo feature, or move these suites' bodies into in-crate#[cfg(test)]modules (which also gets them into the per-PRcargo-testgate, per CI: PR cargo-test never executes crates/perry integration suites; main-push full run starves under merge trains (documented near-miss) #5960).PERRY_RS4GC=0,shadow_slot_hygienestill has 1 failure,scalar_replaced_slot_roots6,temp_root_operand_temporaries6, andtemp_root_argument_temporariesis completely unmoved at 3/7.Repro
Beware truncating that output — piping it through
headsilently drops the tail of the target list, which is howtemp_root_operand_temporariesandtyped_shape_descriptorswere initially missed here.