feat(lint): find a closure that only passes its parameters on #173

Merged
argus merged 2 commits from loop/9-lint-redundant-closure into main 2026-10-08 03:39:57 +00:00
Collaborator

Closes #9

What

The lint rule redundant-closure: a closure whose body is one call of a declared function with the closure's own parameters, each once and in order ({ f(_) }, { f(_, _2) }, { x => f(x) }, { f _ }), is reported and its fix passes the function by its name: items.map { stripMargin(_) } becomes items.map(stripMargin). A closure that trails the call moves into the argument list, with its parameter's label where a labeled argument comes before it or its position would fill another parameter.

Why it is certain

The rule reads the checker's tables, as labeled-literal does: the resolution of the inner call (a Direct call of a SymbolKind.Function with a ready, non-generic signature that has a body and does not take self), the adaptations at the inner call, at its arguments and at the closure (only ImplicitParameter(i) in order, and TrailingClosure), its type arguments, and the function type the closure was given (sameType for every parameter and the result, modes only by value or var on both sides, no default). No new checker table was needed; the existing resolutions, adaptations, typeArguments, argumentTargets and expressionTypes answer every question. No seed impact.

A closure that adapts the function (default left out, lazy, variadic, conversion or wrap of an argument or the result, generic or native callee, a method, a binding or field that holds a closure) gets no finding at all: the rule has no setting and no suppression, so it reports only what it can fix.

The case-shorthand rule split out to #168 is untouched; torb-lint.md still names it under "What is not decided".

Changes

  • compiler/src/lint/redundant-closure.trb: the rule; wired into finding.trb, command.trb and the language server (view.trb). Target and parametersOf of labeled-literal.trb became public for the label of a moved trailing closure.
  • compiler/tests/lint.test.trb: group redundant-closure - every position (trailing, parenthesized, labeled, command, no parentheses), a local and a static function, a generic outer function, labels for a moved trailing closure, and the cases that are kept (a default, lazy, an adaptation, a generic callee, a stored closure, arguments out of order, used twice, labeled or not the parameters); every fixed text type checks.
  • Second commit: the sweep, torb lint --fix --rule redundant-closure std compiler/src then torb format (22 closures in 11 files). Afterwards the rule finds nothing in std and compiler/src.
  • Docs: docs/tooling/torb-lint.md (synopsis, rule section with a trb check example, the not-built list), the-torb-command.md, verifying-your-work.md, ROADMAP.md, compiler/CONTRIBUTING.md; skills regenerated.

Test

Locally (quick checks only): torb check compiler std clean, torb format --check on every touched file, torb docs skill docs skills --check, and torb test compiler/tests/lint.test.trb --filter redundant-closure (5 passed). Gates run in CI.

Closes #9 ## What The lint rule `redundant-closure`: a closure whose body is one call of a declared function with the closure's own parameters, each once and in order (`{ f(_) }`, `{ f(_, _2) }`, `{ x => f(x) }`, `{ f _ }`), is reported and its fix passes the function by its name: `items.map { stripMargin(_) }` becomes `items.map(stripMargin)`. A closure that trails the call moves into the argument list, with its parameter's label where a labeled argument comes before it or its position would fill another parameter. ## Why it is certain The rule reads the checker's tables, as `labeled-literal` does: the resolution of the inner call (a `Direct` call of a `SymbolKind.Function` with a ready, non-generic signature that has a body and does not take `self`), the adaptations at the inner call, at its arguments and at the closure (only `ImplicitParameter(i)` in order, and `TrailingClosure`), its type arguments, and the function type the closure was given (`sameType` for every parameter and the result, modes only by value or `var` on both sides, no default). No new checker table was needed; the existing `resolutions`, `adaptations`, `typeArguments`, `argumentTargets` and `expressionTypes` answer every question. No seed impact. A closure that adapts the function (default left out, `lazy`, variadic, conversion or wrap of an argument or the result, generic or `native` callee, a method, a binding or field that holds a closure) gets no finding at all: the rule has no setting and no suppression, so it reports only what it can fix. The case-shorthand rule split out to #168 is untouched; torb-lint.md still names it under "What is not decided". ## Changes - `compiler/src/lint/redundant-closure.trb`: the rule; wired into `finding.trb`, `command.trb` and the language server (`view.trb`). `Target` and `parametersOf` of `labeled-literal.trb` became public for the label of a moved trailing closure. - `compiler/tests/lint.test.trb`: group `redundant-closure` - every position (trailing, parenthesized, labeled, command, no parentheses), a local and a static function, a generic outer function, labels for a moved trailing closure, and the cases that are kept (a default, `lazy`, an adaptation, a generic callee, a stored closure, arguments out of order, used twice, labeled or not the parameters); every fixed text type checks. - Second commit: the sweep, `torb lint --fix --rule redundant-closure std compiler/src` then `torb format` (22 closures in 11 files). Afterwards the rule finds nothing in std and compiler/src. - Docs: `docs/tooling/torb-lint.md` (synopsis, rule section with a `trb check` example, the not-built list), `the-torb-command.md`, `verifying-your-work.md`, `ROADMAP.md`, `compiler/CONTRIBUTING.md`; skills regenerated. ## Test Locally (quick checks only): `torb check compiler std` clean, `torb format --check` on every touched file, `torb docs skill docs skills --check`, and `torb test compiler/tests/lint.test.trb --filter redundant-closure` (5 passed). Gates run in CI.
The rule redundant-closure reports a closure whose body is one call of a declared function with the closure's
parameters, each once and in order, and its fix passes the function by its name. It reads the checker's existing
tables (resolutions, adaptations, type arguments and the closure's type), finds only what it can fix and runs in
the language server like the other typed rules.
refactor: pass a function by its name where a closure only called it
Some checks failed
ci / commit messages (pull_request) Has been cancelled
ci / what the change touches (pull_request) Has been cancelled
ci / gates (pull_request) Has been cancelled
pdisc / pdisc (pull_request) Has been cancelled
43f19e2af9
torb lint --fix --rule redundant-closure over std and compiler/src, then torb format.
orion force-pushed loop/9-lint-redundant-closure from 43f19e2af9
Some checks failed
ci / commit messages (pull_request) Has been cancelled
ci / what the change touches (pull_request) Has been cancelled
ci / gates (pull_request) Has been cancelled
pdisc / pdisc (pull_request) Has been cancelled
to 4f2d56480f
Some checks failed
ci / commit messages (pull_request) Successful in 5s
ci / what the change touches (pull_request) Successful in 5s
pdisc / pdisc (pull_request) Failing after 2m15s
ci / which runners exist (pull_request) Successful in 1s
ci / bootstrap and conformance (windows-x64) (pull_request) Has been skipped
ci / bootstrap and conformance (linux-arm64) (pull_request) Has been skipped
ci / bootstrap and conformance (macos-arm64) (pull_request) Has been skipped
ci / gates (pull_request) Has been cancelled
ci / tier A (linux-x64) (pull_request) Has been cancelled
ci / tier B (linux-x64) (pull_request) Has been cancelled
ci / tools/release-sync and tools/registry (linux-x64) (pull_request) Has been cancelled
ci / cross-compiled on linux-x64 (windows-x64) (pull_request) Has been cancelled
ci / cross-compiled on linux-x64 (linux-arm64) (pull_request) Has been cancelled
ci / cross-compiled on linux-x64 (macos-arm64) (pull_request) Has been cancelled
ci / every host emits the same C (pull_request) Has been cancelled
ci / the VS Code extension (editors/vscode) (pull_request) Has been cancelled
ci / the playground (torb as WebAssembly) (pull_request) Has been cancelled
ci / pack the seed (pull_request) Has been cancelled
ci / archives (pull_request) Has been cancelled
ci / bootstrap (linux-x64) (pull_request) Has been cancelled
2026-10-08 01:43:49 +00:00
Compare
orion force-pushed loop/9-lint-redundant-closure from 4f2d56480f
Some checks failed
ci / commit messages (pull_request) Successful in 5s
ci / what the change touches (pull_request) Successful in 5s
pdisc / pdisc (pull_request) Failing after 2m15s
ci / which runners exist (pull_request) Successful in 1s
ci / bootstrap and conformance (windows-x64) (pull_request) Has been skipped
ci / bootstrap and conformance (linux-arm64) (pull_request) Has been skipped
ci / bootstrap and conformance (macos-arm64) (pull_request) Has been skipped
ci / gates (pull_request) Has been cancelled
ci / tier A (linux-x64) (pull_request) Has been cancelled
ci / tier B (linux-x64) (pull_request) Has been cancelled
ci / tools/release-sync and tools/registry (linux-x64) (pull_request) Has been cancelled
ci / cross-compiled on linux-x64 (windows-x64) (pull_request) Has been cancelled
ci / cross-compiled on linux-x64 (linux-arm64) (pull_request) Has been cancelled
ci / cross-compiled on linux-x64 (macos-arm64) (pull_request) Has been cancelled
ci / every host emits the same C (pull_request) Has been cancelled
ci / the VS Code extension (editors/vscode) (pull_request) Has been cancelled
ci / the playground (torb as WebAssembly) (pull_request) Has been cancelled
ci / pack the seed (pull_request) Has been cancelled
ci / archives (pull_request) Has been cancelled
ci / bootstrap (linux-x64) (pull_request) Has been cancelled
to 59512e08c1
Some checks failed
ci / commit messages (pull_request) Successful in 3s
ci / what the change touches (pull_request) Successful in 4s
pdisc / pdisc (pull_request) Successful in 2m15s
ci / which runners exist (pull_request) Successful in 0s
ci / bootstrap and conformance (windows-x64) (pull_request) Has been skipped
ci / bootstrap and conformance (linux-arm64) (pull_request) Has been skipped
ci / bootstrap and conformance (macos-arm64) (pull_request) Has been skipped
ci / the VS Code extension (editors/vscode) (pull_request) Successful in 22s
ci / bootstrap (linux-x64) (pull_request) Successful in 4m0s
ci / cross-compiled on linux-x64 (windows-x64) (pull_request) Has been skipped
ci / cross-compiled on linux-x64 (linux-arm64) (pull_request) Has been skipped
ci / cross-compiled on linux-x64 (macos-arm64) (pull_request) Has been skipped
ci / tier A (linux-x64) (pull_request) Failing after 3m22s
ci / tools/release-sync and tools/registry (linux-x64) (pull_request) Successful in 2m55s
ci / gates (pull_request) Has been cancelled
ci / the playground (torb as WebAssembly) (pull_request) Has been cancelled
ci / pack the seed (pull_request) Has been cancelled
ci / archives (pull_request) Has been cancelled
ci / every host emits the same C (pull_request) Has been cancelled
ci / tier B (linux-x64) (pull_request) Has been cancelled
2026-10-08 01:58:49 +00:00
Compare
orion force-pushed loop/9-lint-redundant-closure from 59512e08c1
Some checks failed
ci / commit messages (pull_request) Successful in 3s
ci / what the change touches (pull_request) Successful in 4s
pdisc / pdisc (pull_request) Successful in 2m15s
ci / which runners exist (pull_request) Successful in 0s
ci / bootstrap and conformance (windows-x64) (pull_request) Has been skipped
ci / bootstrap and conformance (linux-arm64) (pull_request) Has been skipped
ci / bootstrap and conformance (macos-arm64) (pull_request) Has been skipped
ci / the VS Code extension (editors/vscode) (pull_request) Successful in 22s
ci / bootstrap (linux-x64) (pull_request) Successful in 4m0s
ci / cross-compiled on linux-x64 (windows-x64) (pull_request) Has been skipped
ci / cross-compiled on linux-x64 (linux-arm64) (pull_request) Has been skipped
ci / cross-compiled on linux-x64 (macos-arm64) (pull_request) Has been skipped
ci / tier A (linux-x64) (pull_request) Failing after 3m22s
ci / tools/release-sync and tools/registry (linux-x64) (pull_request) Successful in 2m55s
ci / gates (pull_request) Has been cancelled
ci / the playground (torb as WebAssembly) (pull_request) Has been cancelled
ci / pack the seed (pull_request) Has been cancelled
ci / archives (pull_request) Has been cancelled
ci / every host emits the same C (pull_request) Has been cancelled
ci / tier B (linux-x64) (pull_request) Has been cancelled
to 0b21250801
All checks were successful
ci / commit messages (pull_request) Successful in 4s
ci / what the change touches (pull_request) Successful in 4s
pdisc / pdisc (pull_request) Successful in 2m14s
ci / which runners exist (pull_request) Successful in 0s
ci / bootstrap and conformance (windows-x64) (pull_request) Has been skipped
ci / bootstrap and conformance (linux-arm64) (pull_request) Has been skipped
ci / bootstrap and conformance (macos-arm64) (pull_request) Has been skipped
ci / the VS Code extension (editors/vscode) (pull_request) Successful in 21s
ci / bootstrap (linux-x64) (pull_request) Successful in 3m56s
ci / cross-compiled on linux-x64 (windows-x64) (pull_request) Has been skipped
ci / cross-compiled on linux-x64 (linux-arm64) (pull_request) Has been skipped
ci / cross-compiled on linux-x64 (macos-arm64) (pull_request) Has been skipped
ci / tier A (linux-x64) (pull_request) Successful in 2m42s
ci / tools/release-sync and tools/registry (linux-x64) (pull_request) Successful in 2m45s
ci / every host emits the same C (pull_request) Successful in 4m12s
ci / the playground (torb as WebAssembly) (pull_request) Successful in 1m43s
ci / tier B (linux-x64) (pull_request) Successful in 11m39s
ci / pack the seed (pull_request) Has been skipped
ci / archives (pull_request) Has been skipped
ci / gates (pull_request) Successful in 0s
2026-10-08 02:35:29 +00:00
Compare
argus approved these changes 2026-10-08 03:39:56 +00:00
argus left a comment

Approved. Checklist for head 0b21250:

  • Tests: ok. Group redundant-closure covers every position, local/static functions, labels for a moved trailing closure, and the kept cases (default, lazy, generic, wrapped result, stored closure, order, reuse, labels); every fixed text is re-checked. CI green (combined status success).
  • Correctness: ok. Every condition of the rule (single call body, positional parameters each once in order, no adaptation, declared non-generic non-native function with body, same types and modes) is read from the checker tables. The trailing-closure fix handles the argument-list shapes and returns no fix for shapes it does not recognise.
  • Scope: ok. Closes #9 only. The case-shorthand rule stays split out (#168).
  • Security/data: ok. No secrets, dependencies or formats touched.
  • Docs: ok. torb-lint.md, the-torb-command.md, verifying-your-work.md, ROADMAP and CONTRIBUTING updated, skills regenerated, pdisc green.
  • Sweep commit: 22 closures in 11 files, mechanical; CI (bootstrap, tier A/B) passes on the result.

Non-blocking: none.

Approved. Checklist for head 0b21250: - Tests: ok. Group `redundant-closure` covers every position, local/static functions, labels for a moved trailing closure, and the kept cases (default, `lazy`, generic, wrapped result, stored closure, order, reuse, labels); every fixed text is re-checked. CI green (combined status success). - Correctness: ok. Every condition of the rule (single call body, positional parameters each once in order, no adaptation, declared non-generic non-native function with body, same types and modes) is read from the checker tables. The trailing-closure fix handles the argument-list shapes and returns no fix for shapes it does not recognise. - Scope: ok. Closes #9 only. The case-shorthand rule stays split out (#168). - Security/data: ok. No secrets, dependencies or formats touched. - Docs: ok. torb-lint.md, the-torb-command.md, verifying-your-work.md, ROADMAP and CONTRIBUTING updated, skills regenerated, pdisc green. - Sweep commit: 22 closures in 11 files, mechanical; CI (bootstrap, tier A/B) passes on the result. Non-blocking: none.
argus merged commit 129f1574e8 into main 2026-10-08 03:39:57 +00:00
argus deleted branch loop/9-lint-redundant-closure 2026-10-08 03:39:57 +00:00
Sign in to join this conversation.
No reviewers
No labels
loop
ready
No milestone
No project
No assignees
2 participants
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
torbscript/language!173
No description provided.