Skip to content

Commit 6207c9e

Browse files
claude[bot]claude
andauthored
fix(lint): resolve the durability gate's wrapper hop through the call site's lexical scope (#13784)
* fix(lint): resolve the durability gate's wrapper hop through the call site's lexical scope `indexFunctionBodies` built one flat `Map<name, body>` in source order, so a file that declared the same name more than once resolved EVERY call to that name to the LAST declaration, wherever the call was written. That is not an approximation with a direction: a collision where only some of the same-named bodies read either invents a read seam or drops a real one, and nothing in the output distinguishes either case from a correct resolution. The index now records every declaration with the scope it is visible from, and `get(name, from)` walks outward from the call site, innermost scope first. Two deliberate departures from a strict lexical resolver, both measured: - a name with exactly ONE body in the file resolves from anywhere. There is nothing to choose, and this keeps every hop the census depends on -- notably a wrapper reached on an identifier receiver, whose owning class is not on the caller's ancestor chain. - a name with SEVERAL bodies and no enclosing one is refused rather than guessed. File order is not evidence, and declining is the under-counting direction this family declares. `contradictsWrapperResolution` is unchanged: it answers a different question (collisions across receivers), both of its clauses pass correctly on the live instance, and it stays load-bearing for a unique name reached on a compound receiver. The sibling `indexLogAliases` stays flat and last-wins, and its docblock now says so with the measurement behind it: zero same-file collisions among the names that index holds, across the whole scan surface. Regression control: four fixtures in `selfTestReadSeams` pinning both error directions (dropped seam, invented seam), the live three-body `lookup` shape, and the non-narrowing rule that catches an over-fix. Measured on this tree: `--list` and `--depth-cost` are byte-identical before and after, at the shipped bound and at every probed depth up to 8. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Pk26oZ12t5N1hwGW1m1MgC * docs(lint): retire the resolution-hazard note the lexical resolver closed The header recorded the flat-index collision as an OPEN hazard, in the present tense, pinned to line numbers that had already drifted by ~131 lines. It also supplied the third of three reasons for leaving MAX_READ_WRAPPER_DEPTH alone ("the hazard grows with depth"), so closing the hazard silently would have left a maintainer-reserved decision resting on an argument that no longer holds. The note now says what was true, what closed it, and what survives of the depth argument in its narrower form: a longer chain no longer needs every name in it to be unique, only resolvable at its own call site -- but a name declared exactly once is still answered by name alone from anywhere, so a longer chain still crosses more of those. The other two reasons are untouched and the bound is not moved. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Pk26oZ12t5N1hwGW1m1MgC --------- Co-authored-by: Claude <noreply@anthropic.com>
1 parent eb717a1 commit 6207c9e

1 file changed

Lines changed: 309 additions & 26 deletions

File tree

0 commit comments

Comments
 (0)