Skip to content

TS backend phase 0 - Typed lambda#8471

Open
cometkim wants to merge 5 commits into
rescript-lang:masterfrom
cometkim:ts-backend-p0
Open

TS backend phase 0 - Typed lambda#8471
cometkim wants to merge 5 commits into
rescript-lang:masterfrom
cometkim:ts-backend-p0

Conversation

@cometkim

@cometkim cometkim commented Jun 13, 2026

Copy link
Copy Markdown
Member

This is a split from #8118 and explains the most basic part of the entire work.

Therefore, this should provide sufficient explanation to the LLM agents and should not conflict with other backend modifications (e.g., sourcemap) yet.

  • Before: Gentype; a separated pipeline that parses and reanalyzes serialized type information.
  • After: Attach the full type information to the Lambda IR and pass it directly to the codegen backend.

Although the compiler's intermediate layer still does not use type information, passing through it simplifying the type-related code generation as it can directly access already computed type information without any extra parsing.

Next phases:

  1. Implementing dts file emission: Provide it as an additional option. Stabilizes the dts format independently of the existing JS IR and deprecates Gentype.
  2. Rewriting codegen backend entirely: New, fully-typed, well-structured codegen IR that unifies all the fragmented codegen logic. It should covers JS/TS/d.ts in a single path (Need research. It may not be possible or complicated)
    • Implementation only: JavaScript output
    • Type only: d.ts output
    • Implementation + Type: TypeScript output

@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: 11042863f6

ℹ️ 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/core/lam_ts_emit.ml Outdated
Comment thread compiler/core/lam_coercion.ml Outdated
Comment on lines +400 to +405
( "-dlamtypes",
set Clflags.dump_lamtypes,
"*internal* dump Lam IR type annotations" );
( "-emit-typedefs",
set Clflags.emit_typedefs,
"*internal* emit .d.ts declarations" );

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

This is for debugging purposes, not a complete feature.

Phase 1 should cover the compiler flags and build system integration.

@codecov

codecov Bot commented Jun 13, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 39.39394% with 240 lines in your changes missing coverage. Please review.
✅ Project coverage is 74.20%. Comparing base (516e650) to head (fc3bd1e).

Files with missing lines Patch % Lines
compiler/core/lam_ts_emit.ml 0.00% 124 Missing ⚠️
compiler/core/lam_type_dump.ml 0.00% 62 Missing ⚠️
compiler/core/lam_eta_conversion.ml 11.76% 15 Missing ⚠️
compiler/core/lam.ml 53.84% 6 Missing ⚠️
compiler/ml/printlambda.ml 0.00% 6 Missing ⚠️
compiler/core/lam_pass_lets_dce.ml 68.75% 5 Missing ⚠️
compiler/ml/translcore.ml 73.33% 4 Missing ⚠️
compiler/core/lam_convert.ml 81.25% 3 Missing ⚠️
compiler/core/lam_pass_alpha_conversion.ml 72.72% 3 Missing ⚠️
compiler/core/lam_group.ml 33.33% 2 Missing ⚠️
... and 7 more
Additional details and impacted files
@@            Coverage Diff             @@
##           master    #8471      +/-   ##
==========================================
- Coverage   74.42%   74.20%   -0.23%     
==========================================
  Files         451      453       +2     
  Lines       61459    61659     +200     
==========================================
+ Hits        45743    45755      +12     
- Misses      15716    15904     +188     
Files with missing lines Coverage Δ
compiler/bsc/rescript_compiler_main.ml 71.79% <100.00%> (+0.29%) ⬆️
compiler/core/js_implementation.ml 84.40% <100.00%> (ø)
compiler/core/lam_analysis.ml 62.68% <100.00%> (ø)
compiler/core/lam_arity_analysis.ml 85.71% <100.00%> (ø)
compiler/core/lam_beta_reduce.ml 86.95% <100.00%> (ø)
compiler/core/lam_beta_reduce_util.ml 97.29% <100.00%> (ø)
compiler/core/lam_bounded_vars.ml 64.78% <100.00%> (ø)
compiler/core/lam_check.ml 95.00% <100.00%> (ø)
compiler/core/lam_closure.ml 53.24% <100.00%> (ø)
compiler/core/lam_coercion.ml 97.61% <100.00%> (+0.11%) ⬆️
... and 32 more
🚀 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.

This is a split from rescript-lang#8118 and explains the most basic part of the entire work.

Therefore, this should provide sufficient explanation to the LLM agents
and should not conflict with other backend modifications (e.g., sourcemap) yet.

- Before: Gentype; a separated pipeline that parses and reanalyzes serialized type information.
- After: Attach the full type information to the Lambda IR and pass it directly to the codegen backend.

Although the compiler's intermediate layer still does not use type information,
passing through it simplifying the type-related code generation as
it can directly access already computed type information without any extra parsing.

Next phases:

- 1. Implementing dts file emission:
  Provide it as an additional option. Stabilizes the dts format independently of the existing JS IR and deprecates Gentype.
- 2. Rewriting codegen backend entirely:
  New, fully-typed, well-structured codegen IR that unifies all the fragmented codegen logic.
  It should covers JS/TS/d.ts in a single path (Need research. It may not be possible or complicated)
  - Implementation only: JavaScript output
  - Type only: d.ts output
  - Implementation + Type: TypeScript output
@pkg-pr-new

pkg-pr-new Bot commented Jun 13, 2026

Copy link
Copy Markdown

Open in StackBlitz

rescript

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

@rescript/darwin-arm64

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

@rescript/darwin-x64

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

@rescript/linux-arm64

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

@rescript/linux-x64

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

@rescript/runtime

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

@rescript/win32-x64

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

commit: fc3bd1e

cometkim added 3 commits June 14, 2026 06:17
Type annotations on value bindings (`let n: int = 42`) were lost before
reaching the export grouping phase, causing `-emit-typedefs` to emit
`unknown` for all non-function exports.

Root cause: `let n: int = 42` produces `Tpat_alias(Tpat_any, n, ...)`
in the typedtree, not `Tpat_var`. The `for_let` fast path only matched
`Tpat_var`, so annotated bindings fell through to `simple_for_let`,
which does not carry the type through to `Lambda.Llet`.

Fix chain:
- Add `Tpat_alias({pat_desc = Tpat_any}, id, _)` to `for_let` fast path
  so `Some pat.pat_type` reaches `Lambda.Llet`
- Add `Types.type_expr option` field to `Lam_group.Single` to carry the
  type through `flatten` and `coerce_and_group_big_lambda`
- Thread `~ty` through `Lam_util.refine_let` so reconstructed `Llet`
  nodes preserve the annotation after `deep_flatten`
- Capture types in `Lam_stats.export_type_tbl` during `collect_info`
  before DCE inlines simple exported constants
- Use `export_type_tbl` in `handle_exports` to pass types to `Single`
  when the original `Llet` has been eliminated
- `Lam_ts_emit.emit_decls` reads `ty` from `Single` instead of trying
  to recover it from the bound expression

Also fixes the `make_key` regression that caused identical switch arms
to lose action sharing: type metadata in `Lapply.ap_result_type` and
`Llet` fields is now zeroed in sharing keys to prevent false inequality.

Assisted-by: OpenCode:glm-5.2
@cometkim

Copy link
Copy Markdown
Member Author

I have verified that all type information, including the module structure, is accessible from the emitter. I will continue emitter changes as phase 1 in another PR. It will be based on the format already investigated in #8118

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.

1 participant