Skip to content

Conversation

@cknitt
Copy link
Member

@cknitt cknitt commented Oct 22, 2025

Fixes #7974.

@cristianoc Fix by Codex - please have a look if it makes sense, or if there is a better way to handle this.

@cknitt cknitt requested a review from cristianoc October 22, 2025 15:02
@pkg-pr-new
Copy link

pkg-pr-new bot commented Oct 22, 2025

Open in StackBlitz

rescript

npm i https://pkg.pr.new/rescript-lang/rescript@7977

@rescript/darwin-arm64

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

@rescript/darwin-x64

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

@rescript/linux-arm64

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

@rescript/linux-x64

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

@rescript/runtime

npm i https://pkg.pr.new/rescript-lang/rescript/@rescript/runtime@7977

@rescript/win32-x64

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

commit: 7c026d6

(* The default mapper would descend into nested [Pexp_fun] nodes (used for
additional parameters) before visiting the function body. Those
nested calls see [async = false] and would reset [async_context] to
false, so by the time we translate the body we incorrectly think we are
Copy link
Collaborator

Choose a reason for hiding this comment

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

Do we need all this? why not just save !in_function_def and restore it later? Does it already fix the issue.
If not, go with this.

Copy link
Member Author

Choose a reason for hiding this comment

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

Unfortunately it seems it is needed.

• I tried the “just save and restore in_function_def” tweak you suggested in compiler/frontend/bs_builtin_ppx.ml:102. Even with that in place, the
nested Pexp_fun that represents the second parameter still executes this branch with async = false, so we compute async_context := (true && !
true) || false, i.e. it flips back to false before we ever reach the real body. The result is the same error as before—node cli/bsc.js -dparsetree
tests/tests/src/function_directives_async.res still reports “Await on expression not in an async context”.

The manual rebuild keeps the outer async flag alive while we thread through the extra parameter wrappers: we map the attributes and parameters
ourselves, recurse into the body, then reassemble the function with the original ~async and pass that to Ast_async.make_function_async. With that
code back in place, the same CLI run succeeds and the generated JS contains the 'use cache'; directive. So we do already restore in_function_def,
but the heavier change is what stops the nested parameter visit from clearing async_context, which is the root of the regression.

@cknitt cknitt merged commit c3dc0dc into rescript-lang:master Oct 23, 2025
25 checks passed
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.

@directive on a function level fails to compile with async and multiple parameters

2 participants