Skip to content

issue-2088 plan: introducesShadowedBinding's switch_body case may carry the identical using_declaration gap #2632 closed for statement_block #2637

Description

@carlos-alm

What

Found while implementing round 16's fix for #2632 (PR #2612, docs/plans/issue-2088.md).

introducesShadowedBinding's switch_body case (src/extractors/javascript.ts, the arm handling an unbraced case/default clause) checks each statement for lexical_declaration (via declarationDeclaresName) and, by name field, function_declaration/generator_function_declaration/class_declaration — the identical enumeration its statement_block case uses, and the identical enumeration that (pre-round-16) was missing using_declaration in both places. Round 16 closed the gap for condition 4's resolution question (findResolvingScopeNode) by adding a using_declaration disjunct scoped specifically to a statement_block ancestor — matching exactly what #2632 itself described (a block-scoped using shadow) and nothing more.

The switch_body case carries the identical enumeration gap: an unbraced case/default clause's own using run = mk(); is invisible to introducesShadowedBinding's switch_body arm for the identical reason statement_block's was, and — by the same reasoning #2632 itself gives for why this is a genuine (not merely conservative) gap for condition 4's resolution question specifically — a same-named module-level decoy shadowed only by such a case-level using declaration would resolve to the decoy with full confidence via findResolvingScopeNode, rather than failing safe.

This is not covered by round 16's own fix: that fix's new disjunct in findResolvingScopeNode is gated on current.type === 'statement_block' specifically, matching #2632's own repro shape exactly — it does not check a switch_body ancestor at all.

Direction

Per the exclusion ledger's now-explicit direction labels (see docs/plans/issue-2088.md's Success Criteria section, round 16): this is UNDER-escape if it manifests for condition 4's resolution question, the identical direction #2632 itself is — live code would be reported dead, not a recall trade-off. Per the standing rule the same round establishes, this may not be filed as an accepted limitation once confirmed; it must be fixed. This issue exists to track investigation and closure, not to document it as permanent scope.

Suggested next step

Confirm the switch_body case actually reaches this code path for an unbraced case/default clause containing a using declaration (verify against tree-sitter-javascript@0.25.0's grammar the same way #2632 did for statement_block), then close it the same way round 16 closed #2632: a matching disjunct in findResolvingScopeNode (not a widening of introducesShadowedBinding, for the same reason #2632's own round-16 fix avoided that), mirrored in the Rust engine, with its own escape-fallback fixture.

Where

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions