lint: redundant-closure, a closure that only passes its parameters on #9
Loading…
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Context
torb lintnames two rules that are not built (torb-lint.md, "What is not decided", ROADMAPtorb lint). This issue builds the first: a closure that only passes its parameters on. The second (a case written with its type where the expected type names it) was split into its own issue, because an accepted design record (CLOSED-TRAITS, section 6) removes the leading-dot spelling that rule would rewrite to.Goal
A new rule
redundant-closurefinds a closure that does nothing but call a declared function with its own parameters, and its fix writes the function itself:items.map { stripMargin(_) }becomesitems.map(stripMargin). Like every rule it always runs (#157: no configuration, no off-by-default); the standard library and the compiler are swept clean instead.Design record points (pinned)
fndeclared by name can be passed exactly where a closure is expected - the rewrite is always expressible.docs/tooling/torb-lint.md: a rule that knows the fix for certain carries it; a rule that needs the expected type or resolution runs the checker (aslabeled-literalandredundant-wrapdo, with a checker table such asredundantWrapsAt). The ROADMAP text already says the fix is "only certain where the callee takes exactly that one parameter".redundant-closure(kebab-case, names what is wrong, likeredundant-wrap); the finding is awarninglike every other rule, there is no severity choice.What the rule finds
A closure (trailing, parenthesized or command form; implicit
_,_2parameters or explicit ones) whose whole body is one call of a declared function (top-level or localfn, or astatic fnby its path) with exactly the closure's parameters, each once, in order, positionally. The finding carries a fix only where the checker is certain the function reference means the same:var,lazy) the closure's own parameter does not share;Force), no generic callee (type arguments inferred at the call) in this first version;constor field that holds a closure (that value could differ between the closure's calls).Anything else gets no finding, or a finding without a fix where it is clearly the same pattern but one condition above fails (the message says which). A method call (
{ _.trim() }) is out of scope.Acceptance criteria
redundant-closureexists incompiler/src/lint/, is listed inLintRuleand in the synopsis oftorb lint, runs in every plaintorb lintrun, and has--fix{ f(_) },{ f(_, _2) }and{ x => f(x) }in every closure position (trailing, parenthesized, command form, as the only or the last argument) are found, and the fix writesfat the same argument position, labelled where the parameter's label requires ittorb checkaccepts every fixed file in the tests (the test runs the fix and checks the result)torb lintoverstdandcompiler/srcreports noredundant-closurefinding (CI shows it; a grep finds no obvious hit today, so the sweep is likely empty or tiny); no rule is documented as "off by default"docs/tooling/torb-lint.mddocuments the rule (synopsis, rules section with atrb checkexample, the "rules named and not built" entry reduced to the case rule) andcompiler/CONTRIBUTING.mdmentions it where it lists the lint rules; ROADMAPtorb linttext names it; generatedskills/regeneratedSeed
No. The rule is written in TorbScript with the existing syntax, the checker table is ordinary compiler code, no native, no driver flag, and
fas a function value is already accepted by the seed.Size and commits
One PR, one or two Conventional Commits:
feat(lint): find a closure that only passes its parameters on, and, only if the sweep finds something,refactor: pass the function itself instead of a closure that forwards to it.Implementer
opus / high (the rule needs a checker table in
compiler/src/semantics/checker/, so it is compiler work).Collisions
Touches
compiler/src/lint/command.trb,finding.trbanddocs/tooling/torb-lint.md, as #157 does (removal of--skip); whichever lands second rebases. No overlap with the running work on #6, #7 and #8.[loop:torbscript] intake: in scope (author orion, label loop). Two lint rules named in ROADMAP
torb lint; tooling only, no seed impact expected. The rule ids and the on/off-by-default choice may need an owner decision, to settle in refine. Release freeze for 0.1.0 (2026-10-06) holds new PRs, next: refine (queued, buffer >= 2 ready)[loop:torbscript] claim refine by session:loop-torbscript-20261008 until 2026-10-08T02:55:28Z
lint: the two named rules that are not builtto lint: redundant-closure, a closure that only passes its parameters on[loop:torbscript] refine: rewrote this issue to the closure rule
redundant-closure(goal, conditions for a certain fix, testable criteria, pinned records, seed impact: no, one PR with one or two Conventional Commits) and setready; the second rule (case written with its type) is split into #168 because the accepted CLOSED-TRAITS record removes the.Casespelling it would rewrite to, so it carries an owner decision there. #157 settles on/off: every rule always runs, so "off by default" is dropped and the sweep must be clean. Implementer: opus/high (checker table in compiler/src). Collides oncommand.trb,finding.trbandtorb-lint.mdwith #157 only (second to land rebases); no overlap with #6, #7, #8. Worker usage ~60000 tokens, next: implement[loop:torbscript] claim implement by session:loop-torbscript-20261008 until 2026-10-08T06:59:32Z