Skip to content
Permalink

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also or learn more about diff comparisons.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also . Learn more about diff comparisons here.
base repository: purescript-lua/purescript-lua
Failed to load repositories. Confirm that selected base ref is valid, then try again.
Loading
base: chore/disable-push-declarations
Choose a base ref
...
head repository: purescript-lua/purescript-lua
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: main
Choose a head ref
Checking mergeability… Don’t worry, you can still create the pull request.
  • 12 commits
  • 32 files changed
  • 2 contributors

Commits on Jul 2, 2026

  1. chore: park the unused Lua-level DCE on the lua-dce-wip branch

    The pass has been unplugged from the pipeline since 189173d (Jul 2023),
    when the IR-level DCE over the UberModule took over, and the 2026-07-02
    backend audit showed it would miscompile if re-enabled (PreserveReturned
    drops all top-level field assignments). Moved to the lua-dce-wip branch
    with its defect list documented; a pointer comment in compileModules
    marks where it would be wired back.
    Unisay committed Jul 2, 2026
    Configuration menu
    Copy the full SHA
    1feaf14 View commit details
    Browse the repository at this point in the history
  2. Merge pull request #135 from purescript-lua/chore/park-lua-dce

    chore: park the unused Lua-level DCE on the lua-dce-wip branch
    Unisay authored Jul 2, 2026
    Configuration menu
    Copy the full SHA
    3f2a5ca View commit details
    Browse the repository at this point in the history
  3. Merge pull request #137 from purescript-lua/chore/disable-push-declar…

    …ations
    
    perf: disable pushDeclarationsDownTheInnerScope (#136)
    Unisay authored Jul 2, 2026
    Configuration menu
    Copy the full SHA
    f68c23f View commit details
    Browse the repository at this point in the history
  4. fix: preserve order and scope of recursive groups in renameShadowedNa…

    …mes (#133)
    
    The RecursiveGroup branch of renameShadowedNamesInExpr had two defects:
    
    1. The fold consed processed members onto an accumulator and never
       reversed the result, so every local recursive group came out with
       its members in reverse order. Member order is the initialization
       order computed by the laziness transform, so eager members (e.g. the
       `name = Lazy_name(0)` forcing bindings) could run before the members
       they read were assigned, producing nil at runtime.
    
    2. Each member's RHS was renamed in the scope accumulated over the
       previous members only, while recursive-group scoping makes every
       member visible in every member's RHS, itself included (see
       Note [Sequential scoping of Let bindings]). When a group member
       shadowed an outer binder, self- and forward references kept the old
       name and silently rebound to the outer binder.
    
    The branch now brings all the members into scope first (avoiding the
    names bound anywhere in the group), then renames every RHS in the
    complete group scope, preserving member order.
    
    The Golden.RecGroupOrder test pins the runtime consequence: its lazy
    self-reference compiles to a Lazy_record/record pair whose order is
    load-bearing; with the old code the generated Lua crashed with
    "attempt to call local 'Lazy_record' (a nil value)".
    
    The Golden.RecursiveBindings churn is the reversal disappearing: member
    order now matches what the laziness transform emits.
    Unisay committed Jul 2, 2026
    Configuration menu
    Copy the full SHA
    32899b0 View commit details
    Browse the repository at this point in the history
  5. Configuration menu
    Copy the full SHA
    41eccea View commit details
    Browse the repository at this point in the history
  6. Merge pull request #147 from purescript-lua/issue-133/rename-rec-groups

    fix: preserve order and scope of recursive groups in renameShadowedNames
    Unisay authored Jul 2, 2026
    Configuration menu
    Copy the full SHA
    44bdbd3 View commit details
    Browse the repository at this point in the history
  7. fix: unshift dropped Let binders and resolve body scope per let* in I…

    …R DCE (#134)
    
    Two defects in the Let handling of IR dead code elimination, both of
    the De Bruijn bookkeeping class of #37/#56:
    
    1. Dropping a dead binding from a Let removed a slot from that name's
       De Bruijn namespace without lowering the references that skipped
       over it, unlike the Abs case (fixed in #56). A dangling reference
       either crashed the Lua codegen with UnexpectedRefBound or silently
       resolved to the wrong binder. The Let case of dceAnnotatedExp now
       walks the groupings left to right and, for every dropped binder,
       unshifts the rest of the Let (later grouping RHSs and the body).
       The unshift traversal is reused by wrapping the remainder back into
       a Let, so the scope threading follows
       Note [Sequential scoping of Let bindings] instead of being
       re-implemented.
    
    2. The scope the Let body was resolved against in adjacencyListForExpr
       was built with a foldr, putting the *first* binding of a name at
       index 0 where the let* convention requires the *last*. Reachability
       thus marked the wrong binding live among same-name siblings. The
       body now uses the same scope that adjacencyListForGrouping threads
       through the groupings.
    
    Both defects are latent on the current corpus (no golden churn):
    same-name Let siblings cannot be produced from source today, and the
    dangling-reference path needs an inliner-created shadowing binder
    whose uses later die. Regression tests pin the semantics at the DCE
    level; an end-to-end golden can follow once a source-level
    reproduction for the second path is pinned down.
    Unisay committed Jul 2, 2026
    Configuration menu
    Copy the full SHA
    dde6ac7 View commit details
    Browse the repository at this point in the history
  8. Merge pull request #148 from purescript-lua/issue-134/dce-let-scope

    fix: unshift dropped Let binders and resolve body scope per let* in IR DCE
    Unisay authored Jul 2, 2026
    Configuration menu
    Copy the full SHA
    91e2f0d View commit details
    Browse the repository at this point in the history

Commits on Jul 3, 2026

  1. fix: eliminate dead bindings of a Let a collapsing Let exposes

    'Rewritten Recurse' descends into the rewritten node's children without
    re-applying the rule to the node itself. When every binding of a Let is
    dead and the node collapses to its body, a body that is itself a Let
    escaped the DCE rule: its dead bindings were kept, while the parameters
    of lambdas inside them were blanked (their ids are unreachable), leaving
    unbound local references in the intermediate IR. A later optimizer
    iteration always dropped the residue, so generated code was unaffected;
    the per-pass invariant checks built for #138 surfaced the bug on the
    golden corpus (Golden.LongWriterBind, Control.Monad.Writer.Trans).
    
    Process a collapsed-into Let directly in the rule (the collapse can
    cascade), so its dead bindings are eliminated in the same pass.
    Unisay committed Jul 3, 2026
    Configuration menu
    Copy the full SHA
    fe02dec View commit details
    Browse the repository at this point in the history
  2. feat: first-class Pass pipeline with linter and deterministic supply (#…

    …138)
    
    The IR pipeline becomes a list of Step values interpreted by runners: a
    Pass carries its invariant contract (passRequires/passEnsures), and the
    Step layer (RunPass | RunFixpoint) lets the checked runner lint every
    pass boundary including every fixpoint iteration — an intermediate
    violation masked by a later iteration is exactly what it exists to
    catch. Components:
    
    - IR.Supply: deterministic counter-based name supply threaded through
      passRun; flattenDeepBinds ports its internal counter to it (names are
      bit-identical: nothing draws before it, the counter starts at 0).
    - IR.Linter: well-scopedness check generalized from the Optimizer
      spec's unboundLocals reference implementation; walks bindings,
      foreigns, and exports, and treats the runtime lazy factory as bound
      by the runtime (a fifth site of the PSLUA_runtime_lazy coupling).
    - IR.Pass: Invariant, Pass, Step, PassCheckFailure, and the three
      runners (plain, checked, traced); idempotently moves here.
    - The golden harness compiles through the checked runner, so every
      golden module doubles as a scope-invariant test of the pipeline.
    - The CLI gains a --lint-ir debug flag plumbed through compileModules.
    
    Behavior-identical: zero golden churn (guarded by the kont0/tmp0 names
    baked into the Long*Bind goldens).
    Unisay committed Jul 3, 2026
    Configuration menu
    Copy the full SHA
    36da35c View commit details
    Browse the repository at this point in the history
  3. Configuration menu
    Copy the full SHA
    610e54c View commit details
    Browse the repository at this point in the history
  4. Merge pull request #149 from purescript-lua/issue-138/pass-pipeline

    First-class passes for the IR pipeline: Pass values, invariant checks, deterministic name supply
    Unisay authored Jul 3, 2026
    Configuration menu
    Copy the full SHA
    180670d View commit details
    Browse the repository at this point in the history
Loading