Skip to content

Note [Sequential scoping of Let bindings] omits freshenBinders and alphaKey from its list of implementors #354

Description

@Unisay

Problem

pslua records how local bindings inside a Let resolve — sequentially, like Scheme's let* — as a GHC-style Note [Sequential scoping of Let bindings] in lib/Language/PureScript/Backend/IR/Types.hs. A Note is a named block comment that other sites reference by name instead of restating the rationale.

This Note is load-bearing rather than descriptive. It states that every traversal walking under Let binders while duplicate names can still occur must implement the convention, and that they must all agree — then enumerates the implementors:

  * 'countFreeRefs' threads the scope through the groupings left to right;

  * 'alphaEq' resolves names to binder positions the same way, so it
    stays correct on shadowed input;

  * the well-scopedness lint
    ('Language.PureScript.Backend.IR.Linter.unboundLocals' — ...)
    tracks bound names the same way;

  * 'qualifyTopRefs' (Linker, ahead of the optimizer pipeline) decides
    whether a local reference escapes to a top-level binding by
    threading bound names the same way;

  * 'Language.PureScript.Backend.IR.Uniquify.uniquifyNamesInExpr'
    resolves names to fresh, site-wide unique names the same way, ...

Two further traversals now implement the same rule and appear nowhere in that list:

Both reference the Note from their own Haddock, so the link runs one way only: a reader standing at the Note cannot see them. Since the list reads as exhaustive ("they must all agree"), the omission actively misleads — the next change to a scoping-sensitive traversal consults the Note, finds five implementors, and misses two.

This family has now produced three defects: #37, where an optimizer traversal resolved a sibling-bound reference against the wrong binder, DCE deleted the "unused" binder, and codegen emitted a dangling Lua variable (the Note cites it); then #345; then #349. The Note is the artifact meant to prevent the fourth.

Approach

Add the two missing implementors to the Note's bullet list, each with a one-clause statement of what it threads, in the style of the existing entries.

Also attach the obligation explicitly: a traversal that implements this convention must be listed here. Today the list is only implicitly exhaustive, which is why two additions slipped past it — stating the rule makes the omission a reviewable defect rather than an oversight.

The change edits a single comment block, so it is small enough to ride along in the next PR that touches a scoping-sensitive traversal instead of taking a cycle of its own.

Prerequisites / Relations

None. Follows #345 and #349, whose fixes created the omission.

Verification / Measurement

Every site whose Haddock claims to implement the convention appears in the Note's list. Documentation only — behaviour is already pinned by the golden test test/ps/src/Golden/Issue37/Test.purs and the "Let sequential (let*) scoping" tests, so this adds no test of its own.

Metadata

Metadata

Assignees

No one assigned

    Labels

    area: irIR / optimizer / DCE / inlinerchoreMaintenance / infrastructure

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions