Repository navigation
Conversation
Changelog🐛 Bug fix
Semantic Diff3 commits · Full page Print types from applied functors in created interfacesa064592 · cknitt + Claude · Oct 27, 2026, 12:40 UTC
Diagnostic modified (create interface) module StrSet = CreateInterfaceFunctor.MakeSet({
type t = string
let compare = (a: string, b) => a < b ? -1 : a > b ? 1 : 0
})
module StrSet: {
-
+ type t = array<string>
let add: (t, string) => array<string>
}Review
Copy same-file types outside functors verbatim in created interfacesde88a9c · cknitt + Claude · Oct 27, 2026, 17:33 UTC Codex review on #9077: a type of the same file reached through Print the runtime names of record fields from signatures8a9ddb5 · cknitt + Claude · Oct 28, 2026, 07:39 UTC Review on #9077: a type of an applied functor is printed from its signature, and the printed record dropped Diagnostic modified (created interface of an applied functor) module WithWire = (X: {}) => {
type t = {@as("wire") field: int}
}
module Applied = WithWire({})
module Applied: {
- type t = {field: int}
+ type t = {@as("wire") field: int}
} |
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## master #9077 +/- ##
=======================================
Coverage 81.45% 81.46%
=======================================
Files 460 460
Lines 64645 64664 +19
=======================================
+ Hits 52657 52676 +19
Misses 11988 11988
🚀 New features to boost your workflow:
|
rescript
@rescript/belt
@rescript/darwin-arm64
@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-9077 |
|
@codex review |
Codex Review SummaryThis comment shows the latest Codex review activity on this pull request.
ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings. |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 427fc4ecd5
ℹ️ 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".
Codex review on #9077: a type of the same file reached through `module type of` or `include` was printed from the signature, which drops field attributes such as `@as`, so the interface no longer matched. Only types inside a functor body other than the module being printed, and types of other files, are printed from the signature now. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Kbf3gLMawVgtmiKy3TMBc3 Signed-off-by: Christoph Knittel <ck@cca.io>
|
@codex review |
cristianoc
left a comment
There was a problem hiding this comment.
Approved, with one remaining interface-generation case worth addressing:
module F = (X: {}) => {
type t = {@as("wire") field: int}
}
module M = F({})For the applied module M, the synthetic printer drops @as("wire"), producing {field: int} and a signature mismatch. The path is analysis/src/create_interface.ml:288–290 → Printtyp.tree_of_label, which omits ld_runtime_name; Includecore.compare_records checks that runtime name. The latest fix preserves annotations for same-file types outside functors, but this applied-functor case remains.
This is based on source inspection; I have not run the repro locally.
Review on #9077: a type of an applied functor is printed from its signature, and the printed record dropped `@as` on its fields, so the created interface for `module M = F({})` with `type t = {@as("wire") field: int}` in F's body didn't match. Record fields in the outcome tree now carry their runtime name, and the printer writes it as `@as`, which also shows it in hover and error messages. Diagnostic modified (created interface of an applied functor): Example: module WithWire = (X: {}) => { type t = {@as("wire") field: int} } module Applied = WithWire({}) Before (rescript): module Applied: { type t = {field: int} } After (rescript): module Applied: { type t = {@as("wire") field: int} } Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Kbf3gLMawVgtmiKy3TMBc3 Signed-off-by: Christoph Knittel <ck@cca.io>
|
Thanks, confirmed and fixed in c6e8221. Record fields in the outcome tree now carry their runtime name, and the outcome printer writes it as |
|
@codex review |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: c6e822102e
ℹ️ 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".
Why:
Create interface copied each type declaration from the source file
at the declaration's location. A type of an applied functor or of an
included module is located in the functor's body, possibly in
another file, so the interface got the unsubstituted body type or
whatever lines of the current file happened to be there. Types
declared elsewhere are now printed from the signature.
Diagnostic modified (create interface):
Example:
module StrSet = CreateInterfaceFunctor.MakeSet({
type t = string
let compare = (a: string, b) => a < b ? -1 : a > b ? 1 : 0
})
Before (rescript): tests/analysis_tests/tests/src/CreateInterfaceFunctorUse.res
module StrSet: {
let add: (t, string) => array<string>
}
After (rescript): tests/analysis_tests/tests/src/CreateInterfaceFunctorUse.res
module StrSet: {
type t = array<string>
let add: (t, string) => array<string>
}
Review: Are types declared in the module itself still copied verbatim?
Yes. A type is copied when its location is in the source file and,
inside a nested module, within that module's declaration, so
attributes on local declarations are kept as before.
Fixes: #9065
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Kbf3gLMawVgtmiKy3TMBc3
Signed-off-by: Christoph Knittel <ck@cca.io>
Codex review on #9077: a type of the same file reached through `module type of` or `include` was printed from the signature, which drops field attributes such as `@as`, so the interface no longer matched. Only types inside a functor body other than the module being printed, and types of other files, are printed from the signature now. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Kbf3gLMawVgtmiKy3TMBc3 Signed-off-by: Christoph Knittel <ck@cca.io>
Review on #9077: a type of an applied functor is printed from its signature, and the printed record dropped `@as` on its fields, so the created interface for `module M = F({})` with `type t = {@as("wire") field: int}` in F's body didn't match. Record fields in the outcome tree now carry their runtime name, and the printer writes it as `@as`, which also shows it in hover and error messages. Diagnostic modified (created interface of an applied functor): Example: module WithWire = (X: {}) => { type t = {@as("wire") field: int} } module Applied = WithWire({}) Before (rescript): module Applied: { type t = {field: int} } After (rescript): module Applied: { type t = {@as("wire") field: int} } Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Kbf3gLMawVgtmiKy3TMBc3 Signed-off-by: Christoph Knittel <ck@cca.io>
c6e8221 to
8a9ddb5
Compare
Fixes #9065.
Create interface copied each type declaration verbatim from the source file at the declaration's location. For a module created by applying a functor, or included from one, that location is inside the functor's body, possibly in another file. So the
.resigot the unsubstituted body type or unrelated lines. Types declared outside the module being printed are now printed from the signature; local ones are still copied, keeping their attributes.New analysis tests:
CreateInterfaceFunctor(same file) andCreateInterfaceFunctorUse(functor from another file,module M = F(...)andinclude F(...)).🤖 Generated with Claude Code
https://claude.ai/code/session_01Kbf3gLMawVgtmiKy3TMBc3