Skip to content

Add provisional %raw syntax for fixed external arguments - #8876

Draft
cknitt wants to merge 7 commits into
masterfrom
raw-external-args-syntax
Draft

cknitt wants to merge 7 commits into
masterfrom
raw-external-args-syntax

Conversation

@cknitt

@cknitt cknitt commented Oct 16, 2026 •

Copy link
Copy Markdown
Member

Second part of splitting #8609, stacked on #8879. The %raw syntax here is provisional and up for discussion with the community.

Summary

Fixed external arguments can be written with the %raw extension point:

@val
external unsafeAddStyle: (%raw("{}"), t, {..}) => t = "Object.assign"

external createElement: (%raw(`"img"`), document) => element = "createElement"

The payload is a string with JavaScript source, which must be exactly one JavaScript literal. Trailing code and comments are rejected because the source is copied into the output.

  • The @as(json...) _, @as("...") _ and @as(1) _ forms still compile but emit a deprecation warning, and the formatter rewrites them to %raw(...). Integers are rewritten as plain JavaScript integers (@as(007) becomes %raw("7")).
  • The fixed value is stored as a raw_source from Represent %raw, %ffi and %%raw with parsetree nodes #8879 (Pfixed_raw of raw_source), so template payloads have their escapes decoded the same way as in %raw expressions, with or without a PPX.
  • Attributes on a fixed argument are checked as for @as(value) _: @ignore, @int etc. next to the value have no effect and are reported as unused. Since the formatter prints all of an argument's attributes before its label, this now includes an attribute written before the label (@ignore ~a: @as(1) _), which used to be ignored silently.
  • %raw is only allowed as a direct external argument, and not as an optional one.
  • The stdlib, Belt and the test suites use the new syntax. dev-playground builds with the released compiler, so its bindings avoid fixed arguments.

Tests

  • Parser errors for %raw in other positions, non-string payloads, and two adjacent %raw arguments.
  • The printer fixture from Remove Pconst_json and represent fixed external arguments in the parsetree #8875 now shows the migration to %raw, plus comments around and inside %raw(...).
  • Error fixtures for a non-literal payload, an optional %raw argument, and an unused attribute next to %raw.
  • ounit tests for the literal check and for how fixed values are spelled as JavaScript.

🤖 Generated with Claude Code

https://claude.ai/code/session_01NP47qMfjMbjUTKZDsLthDo

@cknitt
cknitt force-pushed the raw-external-args-syntax branch from 4110a6e to a3120b2 Compare October 16, 2026 08:03
@cknitt
cknitt added this pull request to stack #8877 October 16, 2026 08:03
@codecov

codecov Bot commented Oct 16, 2026 •

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 86.82635% with 22 lines in your changes missing coverage. Please review.
✅ Project coverage is 81.71%. Comparing base (25e3dfb) to head (077ec17).

Files with missing lines Patch % Lines
compiler/frontend/ast_external_process.ml 75.00% 5 Missing ⚠️
compiler/ml/ast_fixed_arg.ml 84.37% 5 Missing ⚠️
compiler/ml/printast.ml 0.00% 5 Missing ⚠️
tests/ounit_tests/ounit_ast_mapper0_tests.ml 84.21% 3 Missing ⚠️
compiler/ml/ast_mapper_to0.ml 75.00% 2 Missing ⚠️
compiler/ml/classify_function.ml 83.33% 2 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##           master    #8876      +/-   ##
==========================================
- Coverage   81.72%   81.71%   -0.01%     
==========================================
  Files         460      460              
  Lines       64817    64937     +120     
==========================================
+ Hits        52969    53066      +97     
- Misses      11848    11871      +23     
Files with missing lines Coverage Δ
compiler/frontend/ast_attributes.ml 89.04% <100.00%> (-2.74%) ⬇️
compiler/ml/ast_iterator.ml 95.19% <100.00%> (+0.61%) ⬆️
compiler/ml/ast_mapper.ml 98.48% <100.00%> (+<0.01%) ⬆️
compiler/ml/pprintast.ml 92.07% <100.00%> (+0.36%) ⬆️
compiler/syntax/src/res_comments_table.ml 91.22% <100.00%> (-0.01%) ⬇️
compiler/syntax/src/res_core.ml 92.06% <100.00%> (+0.04%) ⬆️
compiler/syntax/src/res_printer.ml 94.61% <100.00%> (-0.01%) ⬇️
tests/ounit_tests/ounit_flow_parser_tests.ml 95.00% <100.00%> (+1.06%) ⬆️
tests/ounit_tests/ounit_string_literal_tests.ml 90.86% <100.00%> (+0.35%) ⬆️
compiler/ml/ast_mapper_to0.ml 79.78% <75.00%> (-0.19%) ⬇️
... and 5 more

... and 3 files 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 16, 2026 •

Copy link
Copy Markdown

Open in StackBlitz

rescript

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

@rescript/belt

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

@rescript/darwin-arm64

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

@rescript/linux-arm64

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

@rescript/linux-x64

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

@rescript/runtime

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

@rescript/win32-x64

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

commit: 077ec17

@cknitt

cknitt commented Oct 16, 2026

Copy link
Copy Markdown
Member Author

@codex review

@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Oct 16, 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-17T05:31:07.023912Z ad2b5b3 Manual request
ℹ️ 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.

@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: b31d9f912f

ℹ️ 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 thread compiler/ml/ast_mapper_to0.ml Resolved
Comment thread compiler/ml/classify_function.ml Resolved
@cknitt

cknitt commented Oct 16, 2026

Copy link
Copy Markdown
Member Author

@codex review

@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: 370b817610

ℹ️ 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 thread compiler/ml/classify_function.ml Resolved
@cknitt
cknitt force-pushed the raw-external-args-syntax branch from 370b817 to 0c75297 Compare October 16, 2026 13:21
@cknitt

cknitt commented Oct 16, 2026

Copy link
Copy Markdown
Member Author

@codex review

@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: 0c752972e3

ℹ️ 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 thread compiler/syntax/src/res_core.ml Resolved
Base automatically changed from fixed-external-args-parsetree to master October 16, 2026 14:49
@cknitt
cknitt force-pushed the raw-external-args-syntax branch 2 times, most recently from 4d07bc5 to 876498c Compare October 16, 2026 15:02
@cknitt
cknitt removed this pull request from stack #8877 October 16, 2026 15:02
@cknitt
cknitt changed the base branch from master to raw-extension-nodes October 16, 2026 15:02
@cknitt
cknitt added this pull request to stack #8880 October 16, 2026 15:02
@cknitt

cknitt commented Oct 16, 2026

Copy link
Copy Markdown
Member Author

@codex review

@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: 876498c5a7

ℹ️ 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 thread compiler/ml/ast_fixed_arg.ml Resolved
@cknitt
cknitt force-pushed the raw-external-args-syntax branch from 876498c to 134919c Compare October 16, 2026 15:45
@cknitt

cknitt commented Oct 16, 2026

Copy link
Copy Markdown
Member Author

@codex review

@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: 134919c46c

ℹ️ 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 thread compiler/syntax/src/res_printer.ml Resolved
@cknitt
cknitt force-pushed the raw-external-args-syntax branch from 134919c to 415e2ec Compare October 16, 2026 19:13
@cknitt

cknitt commented Oct 16, 2026

Copy link
Copy Markdown
Member Author

@codex review

@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: 415e2ecf71

ℹ️ 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 thread compiler/ml/classify_function.ml Resolved
@cknitt

cknitt commented Oct 17, 2026

Copy link
Copy Markdown
Member Author

@codex review

@chatgpt-codex-connector

Copy link
Copy Markdown

Codex Review: Didn't find any major issues. Can't wait for the next one!

Reviewed commit: ad2b5b3270

ℹ️ 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".

Base automatically changed from raw-extension-nodes to master October 17, 2026 07:18
@cknitt
cknitt force-pushed the raw-external-args-syntax branch from ad2b5b3 to 133fd8e Compare October 17, 2026 07:18
@github-actions

github-actions Bot commented Oct 17, 2026 •

Copy link
Copy Markdown

Changelog

🚀 New Feature

  • Add %raw(...) arguments for externals, for example external assign: (%raw("{}"), t) => t = "Object.assign". The string contains the raw JavaScript value supplied by the binding, and the argument is omitted at call sites. The legacy @as(json`...`) _, @as("...") _, and @as(1) _ forms now emit a deprecation warning and are formatted as %raw(...). Add provisional %raw syntax for fixed external arguments #8876

Semantic Diff

7 commits · Full page

Add provisional %raw syntax for fixed external arguments

6a51685 · cknitt + Claude · Oct 16, 2026, 08:01 UTC

%raw("{}") writes a fixed external argument as a JavaScript literal. The @as(value) _ form is deprecated and formats as %raw(...).

✏️ Allow slow CI builds in watch recompilation test

f308aec · cknitt · Sep 04, 2026, 05:42 UTC · edited

A cold build of the test repository can take over 20 seconds on Intel macOS CI, so the test now waits up to 60 seconds for the output.

Reject computed keys in fixed literals

c631d8a · cknitt + Claude · Oct 16, 2026, 12:57 UTC

A computed object key such as [f()] runs code, so it is not a literal. Also test that a %raw fixed argument survives the v0 bridge.

Validate fixed literals as strict mode JavaScript

2d6a79e · cknitt + Claude · Oct 16, 2026, 13:21 UTC

The output is strict, so legacy octal literals such as 007 and octal escapes are rejected.

Report unused attributes on fixed arguments

f5219e3 · cknitt + Claude · Oct 16, 2026, 15:45 UTC

As for @as(value) _, an attribute such as @ignore next to %raw has no effect.

✏️ Test migrating fixed values with template syntax

8b91067 · cknitt + Claude · Oct 16, 2026, 19:13 UTC · edited

Fixed values written with characters that are special in a template, such as ${, a backtick or a backslash, keep their value when the formatter migrates them to %raw(...).

Allow unary minus only on numbers in fixed literals

077ec17 · cknitt + Claude · Oct 17, 2026, 05:28 UTC

Negating an array, object or regexp can run a valueOf method.

@github-actions

Copy link
Copy Markdown

`%raw("{}")` writes a fixed external argument as a JavaScript literal. The
`@as(value) _` form is deprecated and formats as `%raw(...)`.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01NP47qMfjMbjUTKZDsLthDo
Signed-off-by: Christoph Knittel <ck@cca.io>
A cold build of the test repository can take over 20 seconds on Intel macOS CI,
so the test now waits up to 60 seconds for the output.

Signed-off-by: Christoph Knittel <ck@cca.io>
A computed object key such as `[f()]` runs code, so it is not a literal.
Also test that a `%raw` fixed argument survives the v0 bridge.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01NP47qMfjMbjUTKZDsLthDo
Signed-off-by: Christoph Knittel <ck@cca.io>
The output is strict, so legacy octal literals such as `007` and octal escapes
are rejected.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01NP47qMfjMbjUTKZDsLthDo
Signed-off-by: Christoph Knittel <ck@cca.io>
As for @as(value) _, an attribute such as @ignore next to %raw has no effect.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01NP47qMfjMbjUTKZDsLthDo
Signed-off-by: Christoph Knittel <ck@cca.io>
Fixed values written with characters that are special in a template, such as
`${`, a backtick or a backslash, keep their value when the formatter migrates
them to `%raw(...)`.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01NP47qMfjMbjUTKZDsLthDo
Signed-off-by: Christoph Knittel <ck@cca.io>
Negating an array, object or regexp can run a valueOf method.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01NP47qMfjMbjUTKZDsLthDo
Signed-off-by: Christoph Knittel <ck@cca.io>
@cknitt
cknitt force-pushed the raw-external-args-syntax branch 2 times, most recently from c15c5b4 to 077ec17 Compare October 30, 2026 09:24

This branch has not been deployed

No deployments
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