Skip to content

Declare exports left unbound by a toplevel throw - #8692

Merged
cknitt merged 3 commits into
masterfrom
cristianoc/fix-unbound-exports-after-toplevel-throw
Oct 3, 2026
Merged

cknitt merged 3 commits into
masterfrom
cristianoc/fix-unbound-exports-after-toplevel-throw

Conversation

@cristianoc

@cristianoc cristianoc commented Oct 2, 2026 •

Copy link
Copy Markdown
Collaborator

Part of #8712.

Summary

  • Declare exports left unbound by a toplevel throw. When a toplevel binding always throws, its let compiles to the throw statement alone, and Js_output.concat drops every later group. The export list still names those identifiers, so the module is invalid JavaScript: node --check rejected tests/tests/src/conditional/cond_a.mjs ("Export 'u' is not defined in module") and cond_a_none.mjs ("Export 'A' is not defined in module").

Note for review: The fix is a final pass in Lam_compile_main that declares exported names left unbound when the module body always throws; the alternative would be to change how Praise compiles a Declare continuation.

Test plan

  • dune build
  • dune build @fmt
  • dune build --profile browser @check
  • make
  • make lib
  • no change in the runtime and Belt lib/ outputs
  • make test
  • make test-analysis
  • make test-tools
  • make test-gentype
  • make test-syntax
  • make checkformat
  • npm run check

🤖 Generated with Claude Code

When a toplevel binding always throws, its `let` compiles to the `throw`
statement alone, and Js_output.concat drops every later group. The export
list still names those identifiers, so the module is invalid JavaScript:
`node --check` rejected tests/tests/src/conditional/cond_a.mjs ("Export 'u'
is not defined in module") and cond_a_none.mjs ("Export 'A' is not
defined in module").

Lam_compile_main now appends a `let x;` declaration, after the throw, for
each exported identifier the finished module body does not declare. Only
modules whose body always throws are affected; make test regenerates no
other output.

cond_a_load_test dynamically imports both modules and expects loading to
reject with Assert_failure. Before the fix both cases fail with the
SyntaxError; after it both pass.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: Cristiano Calcagno <cristianoc@users.noreply.github.com>
@cristianoc
cristianoc requested a review from cknitt October 2, 2026 06:29
@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Oct 2, 2026 •

Copy link
Copy Markdown

Codex Review Summary

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review ✅ Completed 2026-10-02T06:32:30.803317Z 4584ee8 PR opened
ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: Cristiano Calcagno <cristianoc@users.noreply.github.com>

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 4584ee8b9f

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment on lines +405 to +406
if output.output_finished = True then
declare_undeclared_exports meta.exports block

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Add the required changelog entry

This changes compiler output for affected user programs from invalid to valid JavaScript, making it a user-facing bug fix, but the commit does not add the required entry under the current Unreleased bug-fix section of CHANGELOG.md; without it, the fix will be omitted from the release notes.

AGENTS.md reference: AGENTS.md:L93-L95

Useful? React with 👍 / 👎.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added in 59571ed, under the Unreleased section with the PR link.

alone. The identifiers those groups bind are then undeclared, and an export
list naming them is a JavaScript syntax error. This appends a declaration
for each such exported identifier after the [throw]. *)
let declare_undeclared_exports (exports : Ident.t list) (block : J.block) :

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Add the required DCO sign-off

The message for commit c00d4f6c38e4239dcb5d2ed117c2b7b0b7e598cd has no Signed-Off-By trailer, so the contribution does not meet the repository's required DCO commit standard and cannot be accepted as submitted.

AGENTS.md reference: AGENTS.md:L68-L70

Useful? React with 👍 / 👎.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Every commit on this branch carries a Signed-off-by trailer (git log --format='%(trailers:key=Signed-off-by)' origin/master..HEAD lists one per commit), so there is nothing to add.

@codecov

codecov Bot commented Oct 2, 2026 •

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 79.19%. Comparing base (e004c80) to head (895a5d8).

Additional details and impacted files
@@           Coverage Diff           @@
##           master    #8692   +/-   ##
=======================================
  Coverage   79.19%   79.19%           
=======================================
  Files         473      473           
  Lines       64020    64031   +11     
=======================================
+ Hits        50699    50712   +13     
+ Misses      13321    13319    -2     
Files with missing lines Coverage Δ
compiler/core/lam_compile_main.ml 89.79% <100.00%> (+0.47%) ⬆️

... and 1 file with indirect coverage changes

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@pkg-pr-new

pkg-pr-new Bot commented Oct 2, 2026 •

Copy link
Copy Markdown

Open in StackBlitz

rescript

npm i https://pkg.pr.new/rescript@8692

@rescript/belt

npm i https://pkg.pr.new/@rescript/belt@8692

@rescript/darwin-arm64

npm i https://pkg.pr.new/@rescript/darwin-arm64@8692

@rescript/darwin-x64

npm i https://pkg.pr.new/@rescript/darwin-x64@8692

@rescript/linux-arm64

npm i https://pkg.pr.new/@rescript/linux-arm64@8692

@rescript/linux-x64

npm i https://pkg.pr.new/@rescript/linux-x64@8692

@rescript/runtime

npm i https://pkg.pr.new/@rescript/runtime@8692

@rescript/win32-x64

npm i https://pkg.pr.new/@rescript/win32-x64@8692

commit: 895a5d8

@github-actions

github-actions Bot commented Oct 2, 2026

Copy link
Copy Markdown

@cknitt
cknitt enabled auto-merge (squash) October 3, 2026 05:45
@cknitt
cknitt merged commit 7c1c3e9 into master Oct 3, 2026
24 checks passed
@cknitt
cknitt deleted the cristianoc/fix-unbound-exports-after-toplevel-throw branch October 3, 2026 05:59
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.

2 participants