Repository navigation
Conversation
Codecov Report❌ Patch coverage is Additional details and impacted files@@ Coverage Diff @@
## master #8728 +/- ##
==========================================
+ Coverage 79.79% 79.83% +0.04%
==========================================
Files 464 464
Lines 63134 63135 +1
==========================================
+ Hits 50377 50406 +29
+ Misses 12757 12729 -28
🚀 New features to boost your workflow:
|
The current parsetree carried the frontend's FFI resolution result in `pval_prim` (`Prim_ffi` with an `External_ffi_types.t` spec, and `Prim_inline_const`), so the PPX-facing AST depended on post-PPX state. `pval_prim` is now `string loc option`: the primitive string as written, with its location. The frontend still resolves each FFI external to report errors and warnings and to decide cross-module inlining, but leaves the declaration as written. The type checker resolves it through the `Primitive.resolve_external` hook, which `Ast_external` registers. - `@inline` constants become an `external` with the `#rescript-inline` primitive and an `@inline(<literal>)` attribute. - The unused-attribute and stray-json checks run on each external's resolved form, and skip the unresolved declaration. - `Outcometree` gets its own `out_primitive` for printing resolved externals. - Bump the current-AST and CMT magic numbers. Signed-off-by: Christoph Knittel <[email protected]> Co-Authored-By: Claude Opus 5.5 <[email protected]>
cknitt
force-pushed
the
codex/resolve-external-in-typedecl
branch
from
October 7, 2026 04:59
36bd95a to
b71e398
Compare
rescript
@rescript/belt
@rescript/darwin-arm64
@rescript/darwin-x64
@rescript/linux-arm64
@rescript/linux-x64
@rescript/runtime
@rescript/win32-x64
commit: |
|
Developer playground preview: https://rescript-lang.github.io/rescript/dev-playground/?version=pr-8728 |
- `Ast_external_process.resolve` returns its record directly instead of wrapping a tuple. - Rename `rs_externals` to `is_ffi_external`. - `typedecl.transl_value_decl` resolves once, in a single match. - Run the unused-attribute and leftover-json checks on FFI externals in the post-mapping pass again, on each external's resolved form. Running them while mapping reported warnings in reverse order, since the built-in PPX maps the rest of a structure before its head. - Add fixtures for an unused attribute on an external argument and a json literal on an argument that resolution does not consume. Signed-off-by: Christoph Knittel <[email protected]> Co-Authored-By: Claude Opus 5.5 <[email protected]>
7 of 38 tasks
This branch has not been deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Why
Parsetreeis the AST that PPXs see, and we want to freeze a version of it as "v1" at some point (#8624). Before that, it should only describe source code.Externals didn't. After the frontend processed the FFI attributes of an
external, it replaced the primitive string with the computed FFI spec (Prim_ffi,Prim_inline_const). As a result:parsetree.mldepended onExternal_ffi_types, the compiler's internal FFI representation. That type would become part of any frozen AST, and of a standalonesyntaxpackage we'd like to publish on opam.What changes
pval_primis now just the string from the source, with its location (string loc option). For@send external join: … = "join"it is"join"; the@sendstays an attribute.The FFI attributes are now interpreted during type checking.
TypedeclcallsPrimitive.resolve_external, which the frontend registers, since that code lives abovecompiler/ml. The type checker ends up with the same types and primitive descriptions as before, so the generated JS is unchanged.The frontend still processes each external once, for two reasons:
@modulepath, which stops other modules from inlining it.It now leaves the declaration as written, though. The type checker's second pass runs with warnings off, so nothing is reported twice.
Smaller changes that follow from this:
@inlineconstants used to be encoded asPrim_inline_const. They are nowexternal x: T = "#rescript-inline"with the@inline(<literal>)attribute kept.jsonchecks now look at the processed form of each external rather than the declaration as written.Outcometree.out_primitive.Typedtree.val_primis a string as well; gentype now reads the external's name from the type checker's primitive description.Tests
ast-mappingfixture with several kinds of externals, all printing back unchanged after the v0 round trip.super_errorsfixtures for an unused attribute on an external's argument and ajsonliteral that an external doesn't consume, both of which are now checked on the processed form.🤖 Generated with Claude Code