Skip to content

Fold a field projection through a foreign-header scope IIFE - #161

Merged
Unisay merged 8 commits into
mainfrom
copilot/fold-field-projection-foreign-header-iife
Jul 6, 2026
Merged

Fold a field projection through a foreign-header scope IIFE#161
Unisay merged 8 commits into
mainfrom
copilot/fold-field-projection-foreign-header-iife

Conversation

Copilot AI commented Jul 4, 2026

Copy link
Copy Markdown
Contributor

A ForeignImport with a header lowers to a chunk [ForeignSourceStat fh, return exportsTable]. Projecting a field off it lowers to (function() ...; return exports end)().field — a shape neither the IR-level reduceObjectProp nor the Lua-level reduceTableDefinitionAccessor sees through, since the projected value is a function call, not a table constructor, at either level.

Summary

  • Added foldFieldProjectionThroughScopeCall, a Lua-AST rewrite rule that projects the field inside a no-arg immediately-invoked function whose last statement is a return, rather than after the call: (function() …; return e end)().foo(function() …; return e.foo end)(). Sound because the projection happens within the same activation regardless of whether it's before or after the call returns, so no side effect crosses the boundary.

  • The rewritten projection is immediately re-optimized, so it composes with reduceTableDefinitionAccessor in the same pass. For the Data.Eq.eqChar case from the issue, this fully collapses:

    ((function()
      local refEq = function(r1) return function(r2) return r1 == r2 end end
      return { eqCharImpl = refEq }
    end)()).eqCharImpl

    down to:

    (function()
      local refEq = function(r1) return function(r2) return r1 == r2 end end
      return refEq
    end)()
  • Wired into rewriteRulesInOrder alongside the existing rules.

  • Added unit tests covering full reduction, partial fold (when the returned value isn't an unambiguous table constructor), and decline (callee not a no-arg IIFE).

Checklist

  • Added a changelog.d/ fragment for any user-facing change (scriv create
    in the dev shell), or this change ships nothing releasable (CI, docs, or an
    internal refactor).
  • In the dev shell (nix develop), fourmolu -i lib/ exe/ test/ and
    hlint lib/ exe/ test/ are clean.
  • In the dev shell, cabal test all passes; structural goldens were
    re-accepted on purpose if codegen moved (PSLUA_GOLDEN_ACCEPT=1), and
    eval/golden.txt still holds.

Copilot AI changed the title [WIP] Fix field projection through foreign-header scope IIFE Fold a field projection through a foreign-header scope IIFE Jul 4, 2026
Copilot finished work on behalf of Unisay July 4, 2026 20:54
Copilot AI requested a review from Unisay July 4, 2026 20:54
@Unisay
Unisay marked this pull request as ready for review July 5, 2026 20:47
@Unisay
Unisay merged commit 44f6345 into main Jul 6, 2026
2 checks passed
@Unisay
Unisay deleted the copilot/fold-field-projection-foreign-header-iife branch July 6, 2026 06:27
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Fold a field projection through a foreign-header scope IIFE

2 participants