Skip to content

issue-2088 plan: param-flow branch of escape analysis has the same alias-transitivity gap round-4 fixed for aliases #2617

Description

@carlos-alm

What

docs/plans/issue-2088.md's escape-analysis design (condition 3 of computeObjectLiteralSiteEscapes, WU-2) has the same transitivity gap for its parameter-flow branch that PR #2612 round 4 (Greptile) just caught for its alias branch, and that fix does not cover this case.

Condition 3 treats a bare-identifier argument to a "LOCALLY-DEFINED, NON-EXPORTED function" as a tracked reference, on the grounds that paramBindings (Phase 8.3c, already shipped) propagates the site into the callee's scoped parameter key. Verified against the real, already-shipped primitive at src/domain/graph/resolver/points-to.ts:96 (buildParamFlowConstraints): it only adds the constraint row pts(f::paramName) ⊇ pts(x) — it has no escape-safety check of its own, and nothing in the plan's condition 3 examines what the callee's body subsequently does with that parameter.

So f(T) is accepted as tracked even when f's body does e.g. function f(t) { importedFn(t); } — the parameter t escapes through an unmodeled channel exactly the way u did in the alias case (const u = T; importedFn(u);), but nothing in the current design catches it, because the check never looks inside f's body.

Why this wasn't folded into #2612 directly

Scope discipline: PR #2612 round 4 is fixing the alias branch specifically (what Greptile flagged); this is a structurally analogous but independent branch of the same condition, not yet flagged by any reviewer, and fixing it requires deciding how to scope a recursive/transitive check into another function's body (parameter shadowing rules there are less obviously reused from the existing introducesShadowedBinding/findDeclaringScopeLine machinery than the alias case's same-scope walk was) — worth its own focused look rather than expanding round 4's diff.

Suggested fix shape (not binding — decide at execute/fix time)

Mirror round 4's fix: when condition 3 accepts a bare-identifier argument to a local, non-exported callee, additionally require that condition 3 (recursively) also holds for the callee's corresponding parameter name, scoped to occurrences inside that callee's own body. Add a regression case to WU-10's escape-fallback test list (tests/integration/issue-2088-escape-fallback.test.ts) demonstrating f(T) where f's body passes its parameter to an imported/exported function must still classify the site escaping.

Where

Metadata

Metadata

Assignees

No one assigned

    Labels

    follow-upDeferred work from PR reviews that needs tracking

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions