Summary
check-test-lang-gates.py exempts a sweep from the per-feature check on
the strength of a bare is_enabled / into_enum_iter token
(SWEEP_RE). The exemption is sound for the languages a sweep
iterates — the runtime filter skips the disabled ones — but it also
covers a language the sweep names outside the loop, which no filter can
skip.
The pin that exists for exactly this (hardcoded) is populated only
from *Parser / *Code type names, not from a LANG value:
// Passes the gate today. Panics under `--features python`.
#[cfg(any(feature = "python", feature = "rust"))]
#[test]
fn sweep_that_also_parses_rust() {
if !LANG::Python.is_enabled() {
return;
}
let _ = analyze(Source::new(LANG::Rust, src), Default::default());
}
--fix would write that same any(...) gate.
Why it is latent
All 16 sweep-only tests in the tree filter per language and parse only
the loop variable. Verified by reading each:
c_family_space_names_tests.rs:210,302,347, abc.rs, cognitive.rs,
nargs.rs, langs.rs, and the four parity sweeps. Nothing is wrong
today.
Why the obvious fix does not work
Pinning every surviving LANG::X literal in a sweep body was tried and
reverted: it breaks 22 items and 8 self-tests, because a sweep's row
table is frequently written as LANG::X literals —
for (lang, src) in [(LANG::C, C_SRC), (LANG::Cpp, CPP_SRC)] {
if !lang.is_enabled() { continue; }
— and those literals are skipped by the filter. The gate cannot
currently tell a literal inside the iterated collection from one outside
the loop, and that distinction is the whole fix.
What would fix it
Track the extent of the iterated collection (the for header's
expression, or the array literal it destructures) and pin only the
LANG::X mentions outside it. Alternatively, require is_enabled to
appear in filter position (.filter(, if !lang.is_enabled()) over an
iterated binding, rather than accepting the bare token anywhere in the
body.
Either is a real change to the scan with real regression risk, which is
why it was not folded into #1478.
Meanwhile
The boundary is documented in .claude/rules/testing.md under "A sweep
still needs the parsers it hardcodes": the pin covers a parser named as
a type and nothing else, and a fixed-parser call written
check_metrics::<RustParser> is pinned correctly.
Found by a review of PR #1479.
Summary
check-test-lang-gates.pyexempts a sweep from the per-feature check onthe strength of a bare
is_enabled/into_enum_itertoken(
SWEEP_RE). The exemption is sound for the languages a sweepiterates — the runtime filter skips the disabled ones — but it also
covers a language the sweep names outside the loop, which no filter can
skip.
The pin that exists for exactly this (
hardcoded) is populated onlyfrom
*Parser/*Codetype names, not from aLANGvalue:--fixwould write that sameany(...)gate.Why it is latent
All 16 sweep-only tests in the tree filter per language and parse only
the loop variable. Verified by reading each:
c_family_space_names_tests.rs:210,302,347,abc.rs,cognitive.rs,nargs.rs,langs.rs, and the four parity sweeps. Nothing is wrongtoday.
Why the obvious fix does not work
Pinning every surviving
LANG::Xliteral in a sweep body was tried andreverted: it breaks 22 items and 8 self-tests, because a sweep's row
table is frequently written as
LANG::Xliterals —— and those literals are skipped by the filter. The gate cannot
currently tell a literal inside the iterated collection from one outside
the loop, and that distinction is the whole fix.
What would fix it
Track the extent of the iterated collection (the
forheader'sexpression, or the array literal it destructures) and pin only the
LANG::Xmentions outside it. Alternatively, requireis_enabledtoappear in filter position (
.filter(,if !lang.is_enabled()) over aniterated binding, rather than accepting the bare token anywhere in the
body.
Either is a real change to the scan with real regression risk, which is
why it was not folded into #1478.
Meanwhile
The boundary is documented in
.claude/rules/testing.mdunder "A sweepstill needs the parsers it hardcodes": the pin covers a parser named as
a type and nothing else, and a fixed-parser call written
check_metrics::<RustParser>is pinned correctly.Found by a review of PR #1479.