lint: recurse W002 into unobserved blocks and match arms - #793
Merged
InauguralPhysicist merged 1 commit intoAug 2, 2026
Merged
Conversation
…ch arms check_unused_params recursed only through IF/FUNC/FOR/PROGRAM, breaking on AST_UNOBSERVED and AST_MATCH, so a define inside an unobserved block or a match arm never had its parameters checked and W002 lint'd clean while the same unused parameter at top level warned. Recurse into both, matching the shape check_builtin_shadow (InauguralSystems#787) and collect_assigns (InauguralSystems#790) already use for these node types. Diagnostics themselves are unchanged. Closes InauguralSystems#781 Co-Authored-By: Kimi K3 <noreply@kimi.com>
5 tasks
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What does this PR do?
Fixes #781.
check_unused_paramsrecursed only throughAST_IF/FUNC/FOR/PROGRAMand kept bothAST_MATCHandAST_UNOBSERVEDin its break-only group, so adefinenested in anunobserved:block or amatcharm was never visited and the W002 emission was never reached.Both arms were missing here, so this adds both — unlike #790, where the walker already recursed
AST_UNOBSERVEDand onlyAST_MATCHwas needed. The recursion idiom is #787's for the same node types, verbatim.Changes
src/lint.c— two recursion arms added tocheck_unused_params's switch; both labels removed from the break-only group. No new traversal helper, no change to the emission site, no other walker touched.tests/test_lint.sh— three tests, placed mid-file next to the existing W002 coverage rather than appended at the tail, since lint: W003 (unreachable code) never fires for a function defined inside unobserved: or a match arm #782 and lint: W010 (duplicate dict key) never fires inside unobserved: or a match arm #783 are adding tests to this same file. Two cover the fixed behaviour; the third pins the top-level path that already worked, so a future change to this switch can't silently break it.Testing
bash tests/test_lint.shrun directly for its exit code:123 passed, 0 failed, 123 total, exit 0.tests/run_all_tests.sh:RESULTS: 3315/3315 passed, 0 failed.src/lint.creverted to upstream and the new tests kept, both behaviour tests fail (121 passed, 2 failed). The third test passes against unfixed code, which is what a regression pin should do.AST_MATCHalone silences the match reproducer whileunobserved:still warns; deletingAST_UNOBSERVEDalone is the exact mirror.main(1750b48, which now includes lint: recurse W001 collect_assigns into match arms #790), builds clean,tests/test_lint.shexit 0.One caveat stated plainly, because it is easy to over-read. Linting all 397
.eigsfiles underlib/+examples/+tests/with the unfixed and fixed binaries produces byte-identical output (112,051 bytes, 973 warnings, per-file exit codes included). That is a no-regression result and nothing more: an indentation-aware scan finds zerodefines nested insideunobserved:ormatchanywhere in that corpus, so even a no-op arm would have produced the same bytes. The two new tests are the only evidence the fix actually fires.fuzz/corpus/was deliberately outside that scope.Checklist
make testpasses locally — full suite viatests/run_all_tests.sh:3315/3315 passed, 0 failed; lint tests run directly for their exit code,123 passed, 0 failed, exit 0docs/BUILTINS.md— n/a, no new builtinsdocs/STDLIB.md— n/a, no new library functionssrc/lint.candtests/test_lint.sh. Happy to add an entry if you'd rather these carried one.Generated by Claude Opus 5 (brief, review), Kimi K3 (implementation, verification)