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
{{ message }}
Repository navigation
test(gc): #10491's sabotage twin cannot fail under cargo test --release — its observable is debug-only #10604
gc::tests::copy_slot_decode::sabotaged_remembering_arm_is_refused_by_the_coverage_cross_check, added by #10491, cannot fire in the configuration the GC work is gated on, and currently fails there.
This is my own PR's test, reported here rather than quietly patched because the shape is worth recording: it is the second witness in this suite that is inert or failing in --release.
Evidence
Fails under cargo test --releaseon the untouched base arm, not only on a branch — so it is not caused by any in-flight change.
Fails alone as well as in the full suite, so it is not cross-test interference.
Passes in a debug build.
The cause is in its own doc comment: the observable it asserts is restore_surviving_dirty_coverage's cross-check, which is debug-only. cargo test defaults to debug, so it passed when written; every gate run in the #10362 campaign uses cargo test --release, where the cross-check is compiled out and the sabotage has nothing to refuse.
Why it matters
The sabotage twin exists to prove the remembering arm's behaviour is load-bearing rather than decorative. In --release it proves nothing, and a green suite there is not evidence about that arm. The same category as the inert stress gate found earlier in this campaign (a harness that read head's exit status rather than the program's) and the dark CI gate in #9847's notes: a check that cannot fail is documentation.
Options, for whoever picks this up
Make the observable available in release for the test — i.e. gate the cross-check on cfg(any(test, debug_assertions)) rather than debug_assertions alone, the shape assert_relocation_copied_the_header already uses in gc/layout/transfer.rs, which does run under cargo test --release.
Or mark the test #[cfg(debug_assertions)] so it is honestly scoped, and add a release-capable witness for the same arm — otherwise the arm has no release coverage at all.
(1) looks right by precedent, but whoever owns that cross-check should decide whether making it test-visible in release costs anything.
Suggestion beyond this one test
A sweep for #[test]s whose observable is debug_assertions-only would be worth someone's afternoon. Two have now been found by accident in this suite alone, both while chasing something else.
Flagging this as NOT fixed, against an initial read that said it was.
An issue audit first reported this closed by 420d9658d5. Checking that commit: it adds only #[cfg_attr(not(debug_assertions), ignore)].
This issue offers two remedies — (1) gate the cross-check on cfg(any(test, debug_assertions)), or (2) mark it debug-only and add a release-capable witness. Neither is in the tree: restore_surviving_dirty_coverage is still debug_assertions-only, and no new witness exists.
So the red is cleared and the arm still has zero release coverage, which is the entire point of the issue. Textbook "symptom gone, defect untouched" — and precisely the shape CLAUDE.md's ★ section describes, where a gate stops failing without its subject ever being checked.
Leaving open. Whoever picks this up wants remedy (2): the ignore can stay, but something has to exercise that arm in a release build, or [profile.gcaudit] (release codegen with debug assertions on) has to run it somewhere that gates.
Activity
proggeramlug commentedon Sep 20, 2026
Flagging this as NOT fixed, against an initial read that said it was.
An issue audit first reported this closed by
420d9658d5. Checking that commit: it adds only#[cfg_attr(not(debug_assertions), ignore)].This issue offers two remedies — (1) gate the cross-check on
cfg(any(test, debug_assertions)), or (2) mark it debug-only and add a release-capable witness. Neither is in the tree:restore_surviving_dirty_coverageis stilldebug_assertions-only, and no new witness exists.So the red is cleared and the arm still has zero release coverage, which is the entire point of the issue. Textbook "symptom gone, defect untouched" — and precisely the shape CLAUDE.md's ★ section describes, where a gate stops failing without its subject ever being checked.
Leaving open. Whoever picks this up wants remedy (2): the
ignorecan stay, but something has to exercise that arm in a release build, or[profile.gcaudit](release codegen with debug assertions on) has to run it somewhere that gates.