Summary
crates/perry-codegen/tests/argless_builtin_extra_args.rs::any_call_result_trim_emits_string_tag_dispatch fails on clean main and has done for at least nine days. It is currently reddening e2e-scoped on every open PR that touches perry-codegen, where it reads as that PR's fault.
Proof it is not any PR's fault
Fresh worktree at origin/main (7c22189aa), nothing applied:
failures:
any_call_result_trim_emits_string_tag_dispatch
test result: FAILED. 3 passed; 1 failed; 0 ignored
The assertion is:
assert_eq!(ir.matches("= call double @perry_fn_schema_ts__make(").count(), 2,
"the receiver must be evaluated once in the init body (plus the generated extern wrapper)");
Observed count is 1, expected 2. The fixture is make().trim() where make is an imported extern returning Any.
Bisect so far
| commit |
date |
result |
debefa55c |
2026-08-10 |
PASS |
8bfdac447 |
2026-08-19 |
FAIL |
6173ff9f6 |
2026-08-20 |
FAIL |
8d1cca158 … 7c22189aa |
08-20/21 |
FAIL |
497 commits in the good→bad window. An automated git bisect run was started and paused when free disk fell to 7.7 GiB — ENOSPC manufactures false failures, so a paused bisect is better than a wrong answer. It needs roughly nine build-and-test rounds with ~10 GiB headroom.
Why nobody noticed
crates/*/tests/*.rs run per-PR only when the diff names them (e2e-scoped, see scripts/ci_plan.py). A break in this suite is therefore invisible on main and only surfaces on whichever PR happens to touch perry-codegen — wearing that PR's name.
This has already cost real time: it was mis-attributed to #8540, and an agent was dispatched to "fix" a receiver-evaluation bug that PR did not introduce. #8537, #8543 and #8525 carry the same inherited red.
Why it matters beyond CI noise
The count pins how many times the receiver expression is evaluated, and the receiver is a call. A count of 1 instead of 2 means the receiver is no longer materialized in the init body before the string-tag dispatch. If that reflects real emitted code rather than a changed wrapper shape, a side-effecting receiver's semantics have shifted. That needs answering before the assertion is adjusted — do not "fix" this by editing the expected count.
Suggested approach
- Finish the bisect with adequate disk (
git bisect start; git bisect bad <main>; git bisect good debefa55c, then git bisect run on that one test).
- Diff the emitted IR for the fixture at the culprit commit against its parent — faster than reading the pass.
- Decide from JS semantics whether the new evaluation count is correct. If it is, prove observable behaviour is unchanged with a runtime fixture whose
make() has a side effect, then update the assertion with that reasoning recorded. If it is not, fix the lowering.
Related
The same structural gap — a suite that only runs when a PR happens to touch it — is worth a separate look: a main-only sweep that runs the integration suites unconditionally would have caught this on the day it landed.
Summary
crates/perry-codegen/tests/argless_builtin_extra_args.rs::any_call_result_trim_emits_string_tag_dispatchfails on cleanmainand has done for at least nine days. It is currently reddeninge2e-scopedon every open PR that touchesperry-codegen, where it reads as that PR's fault.Proof it is not any PR's fault
Fresh worktree at
origin/main(7c22189aa), nothing applied:The assertion is:
Observed count is 1, expected 2. The fixture is
make().trim()wheremakeis an imported extern returningAny.Bisect so far
debefa55c8bfdac4476173ff9f68d1cca158…7c22189aa497 commits in the good→bad window. An automated
git bisect runwas started and paused when free disk fell to 7.7 GiB — ENOSPC manufactures false failures, so a paused bisect is better than a wrong answer. It needs roughly nine build-and-test rounds with ~10 GiB headroom.Why nobody noticed
crates/*/tests/*.rsrun per-PR only when the diff names them (e2e-scoped, seescripts/ci_plan.py). A break in this suite is therefore invisible onmainand only surfaces on whichever PR happens to touchperry-codegen— wearing that PR's name.This has already cost real time: it was mis-attributed to #8540, and an agent was dispatched to "fix" a receiver-evaluation bug that PR did not introduce. #8537, #8543 and #8525 carry the same inherited red.
Why it matters beyond CI noise
The count pins how many times the receiver expression is evaluated, and the receiver is a call. A count of 1 instead of 2 means the receiver is no longer materialized in the init body before the string-tag dispatch. If that reflects real emitted code rather than a changed wrapper shape, a side-effecting receiver's semantics have shifted. That needs answering before the assertion is adjusted — do not "fix" this by editing the expected count.
Suggested approach
git bisect start; git bisect bad <main>; git bisect good debefa55c, thengit bisect runon that one test).make()has a side effect, then update the assertion with that reasoning recorded. If it is not, fix the lowering.Related
The same structural gap — a suite that only runs when a PR happens to touch it — is worth a separate look: a
main-only sweep that runs the integration suites unconditionally would have caught this on the day it landed.