Skip to content

Use the applied signature for modules created by functor application - #9084

Open
cknitt wants to merge 12 commits into
masterfrom
fix-9072-applied-functor-types
Open

cknitt wants to merge 12 commits into
masterfrom
fix-9072-applied-functor-types

Conversation

@cknitt

@cknitt cknitt commented Oct 27, 2026 •

Copy link
Copy Markdown
Member

Fixes #9072.

Analysis modelled module M = F(X) by F's own body, so hover and completion on M's items showed the body's parameter types (array<O.t>). M is now modelled by the signature the compiler computed for the application.

That signature keeps the identifiers of F's body, whose stamps already name the body's items in the file's stamp table. So it is renamed with Subst first, from a stamp counter raised far above the stamps in a typed tree.

New analysis test: AppliedFunctor.

Members of the applied module are also connected to their declarations in the functor's body, so Find References and rename cover both within a file, including nested modules.

Known limitation: across files, references and rename don't connect a use such as StrSet.add to add in the functor's file. That needs external references for renamed members; go to definition and hover links do resolve to the functor's file.

🤖 Generated with Claude Code

https://claude.ai/code/session_01Kbf3gLMawVgtmiKy3TMBc3

@github-actions

github-actions Bot commented Oct 27, 2026 •

Copy link
Copy Markdown

Changelog

🐛 Bug fix

  • Hover and completion on a module created by applying a functor show the applied types, such as array<int>, instead of the functor body's array<O.t>.

Semantic Diff

12 commits · Full page

Use the applied signature for modules created by functor application

93deefc · cknitt + Claude · Oct 27, 2026, 12:59 UTC

Why

Editor analysis modelled module M = F(X) by F's own body, so hover and completion on M's items showed the types of the functor's body, with the parameter's types such as O.t, instead of the argument's. M is now modelled by the signature the compiler computed for the application. That signature keeps the identifiers of F's body, whose stamps already name the body's items, so it is renamed first.

Diagnostic modified (completion on an applied functor)

module type Ord = {
  type t
  let compare: (t, t) => int
}
module MakeSet = (O: Ord) => {
  type t = array<O.t>
  let add = (s: t, x: O.t) => s->Array.concat([x])
}
module IntSet = MakeSet({
  type t = int
  let compare = (a: int, b) => a - b
})
// IntSet.

text · tests/analysis_tests/tests/src/AppliedFunctor.res

-"detail": "(t, O.t) => array<O.t>"
+"detail": "(t, int) => array<int>"

Diagnostic modified (hover on a type of an applied functor)

text

-type IntSet.t = array<O.t>
+type IntSet.t = array<int>

Review

  • Why raise the stamp counter before renaming? The renamed identifiers get stamps from the analysis process's own counter, which starts low and would hand out stamps that the typed tree already uses; above 2^40 they cannot meet one.
Keep the functor's file for members of an applied functor

d45f713 · cknitt + Claude · Oct 27, 2026, 17:45 UTC

Codex review on #9084: the members of module M = Other.Make(X) were registered in the current file with the locations of Other's functor body, so Go to Definition and hover's type-definition link combined Other's location with the current file. Their module path now records the functor, as it does for included modules, so both resolve to the functor's file.

Link signature help type definitions to their declaring file

467cb2a · cknitt + Claude · Oct 27, 2026, 20:22 UTC

Codex review on #9084: signature help built its Type definition link from the caller's file, so for a type of an applied functor from another file it pointed into the caller. It now takes the file from the type's declaration, as hover does; the link function requires it, so no caller can fall back to the wrong file.

Connect renamed members of an applied functor to their declarations

4df3721 · cknitt + Claude · Oct 27, 2026, 20:22 UTC

Codex review on #9084: the members of an applied functor are registered under fresh stamps, so references to IntSet.add were no longer references to MakeSet.add; Find References missed them and renaming the declaration left them unchanged. Each renamed stamp now maps to the stamp it was renamed from: a use of the member is also recorded as a use of the original, and references starting from the member start from the original.

Connect nested modules of an applied functor to their declarations

9bf663d · cknitt + Claude · Oct 27, 2026, 21:23 UTC

Codex review on #9084: uses of a module path such as M.Nested were recorded only under the renamed stamp. They are now also recorded under the original, like value uses. The originals are taken from the functor's result signature: when the argument is a path, the application's signature was already renamed by the compiler and doesn't carry the body's stamps.

Resolve applied fields and constructors to the functor's declarations

29cad75 · cknitt + Claude · Oct 28, 2026, 07:45 UTC

Codex review on #9084: an applied functor's record fields and constructors are read from its signature, where they have no location. Go to Definition returned that missing location, and rename added it as a reference, producing edits at character -1. Their lookups now go through the type they were renamed from, which has the body's locations, and fields and constructors without a location are not registered as references.

Register module types of an applied functor's signature

9ae3cc8 · cknitt + Claude · Oct 29, 2026, 06:11 UTC

Codex review on #9084: the applied signature's module types were dropped, because the signature walk handled modules but not module types, so a member declared with one, such as Applied.Nested.value with module Nested: S, no longer resolved. Module types are registered like those of a structure now.

Map the members of an applied functor's module types to their declarations

420145e · cknitt + Claude · Oct 29, 2026, 09:53 UTC

Codex review on #9084: only a module type's own identifier was mapped to the functor body's, not those inside its signature, so a member reached through the applied module type, such as X.value with X: Applied.S, was missing from the references and renames of S.value. Module type signatures are now walked like those of modules.

Register an inline functor's parameters before applying it

7a3dd05 · cknitt + Claude · Oct 29, 2026, 10:03 UTC

Codex review on #9084: an immediately applied inline functor was no longer walked, so its parameters and declarations were missing and O.compare in its body had no definition. The functor is walked again before its application. The results of curried applications now take the body's identifiers from the functor applied first, as the compiler had already renamed those of the inner application.

Locate items of a functor applied from another file in that file

e886bad · cknitt + Claude · Oct 29, 2026, 10:32 UTC

Codex review on #9084: Go to Definition on a nested module and Go to Type Definition paired the functor file's locations with the caller's URI. Both now take the URI from the declaration's module path, like value definitions. Fields and constructors of such a functor are found in its file, and its items no longer register locations and references at the same positions of the caller's file.

Refer uses of a functor applied from another file to that file's members

d22c654 · cknitt + Claude · Oct 29, 2026, 10:39 UTC

A use of a member of a functor applied from another file referred to the caller's copy, so references and renames no longer crossed files as they did when the application resolved to the functor. Such a use refers to the functor's member again, for values, types, fields, constructors and modules, and a signature's nested modules now name their items' paths.

✨ Follow a functor's aliases to its file for the members it creates

ff8f5be · cknitt + Claude · Oct 29, 2026, 18:03 UTC · new

Review fix: a functor from another file applied through a local alias, such as module Make = AppliedFunctor.MakeSet then Make(IntOrd), kept the alias as the members' source, so Go to Definition and type-definition links pointed into the caller at the functor's line numbers, and uses didn't reach the functor's references and renames. The source is now the path the compiler resolved the alias chain to, through modules too.

Analysis modified (go to definition of an applied member)

module Make = AppliedFunctor.MakeSet
module Aliased = Make(AppliedFunctor.IntOrd)
let a = Aliased.add([], 1)

text · definition of add

-file:///AppliedFunctorUse.res 7:6-7:9
+file:///AppliedFunctor.res 7:6-7:9

@codecov

codecov Bot commented Oct 27, 2026 •

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 83.95062% with 26 lines in your changes missing coverage. Please review.
✅ Project coverage is 81.75%. Comparing base (799a82f) to head (ff8f5be).
⚠️ Report is 5 commits behind head on master.

Files with missing lines Patch % Lines
analysis/src/references.ml 68.18% 14 Missing ⚠️
analysis/src/process_cmt.ml 87.27% 7 Missing ⚠️
analysis/src/process_extra.ml 92.72% 4 Missing ⚠️
analysis/src/shared_types.ml 0.00% 1 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##           master    #9084      +/-   ##
==========================================
+ Coverage   81.48%   81.75%   +0.27%     
==========================================
  Files         460      460              
  Lines       64728    64858     +130     
==========================================
+ Hits        52744    53026     +282     
+ Misses      11984    11832     -152     
Files with missing lines Coverage Δ
analysis/src/hover.ml 77.27% <100.00%> (+0.14%) ⬆️
analysis/src/markdown.ml 100.00% <100.00%> (ø)
analysis/src/signature_help.ml 80.37% <100.00%> (ø)
analysis/src/shared_types.ml 80.41% <0.00%> (-0.28%) ⬇️
analysis/src/process_extra.ml 87.50% <92.72%> (+0.05%) ⬆️
analysis/src/process_cmt.ml 85.26% <87.27%> (+1.17%) ⬆️
analysis/src/references.ml 70.92% <68.18%> (+2.99%) ⬆️

... and 19 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 27, 2026 •

Copy link
Copy Markdown

Open in StackBlitz

rescript

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

@rescript/belt

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

@rescript/darwin-arm64

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

@rescript/linux-arm64

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

@rescript/linux-x64

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

@rescript/runtime

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

@rescript/win32-x64

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

commit: ff8f5be

@github-actions

Copy link
Copy Markdown

@cknitt
cknitt marked this pull request as ready for review October 27, 2026 14:20
@cknitt

cknitt commented Oct 27, 2026

Copy link
Copy Markdown
Member Author

@codex review

@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Oct 27, 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-29T18:07:36.339989Z ff8f5be 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: eeb4965510

ℹ️ 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 analysis/src/process_cmt.ml Outdated
cknitt added a commit that referenced this pull request Oct 27, 2026
Codex review on #9084: the members of `module M = Other.Make(X)` were
registered in the current file with the locations of Other's functor
body, so Go to Definition and hover's type-definition link combined
Other's location with the current file. Their module path now records
the functor, as it does for included modules, so both resolve to the
functor's file.

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>
@cknitt

cknitt commented Oct 27, 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: c4cc7a1a84

ℹ️ 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 analysis/src/process_cmt.ml Outdated
Comment thread analysis/src/signature_help.ml Outdated
@cknitt
cknitt added this pull request to stack #9093 October 27, 2026 19:58
cknitt added a commit that referenced this pull request Oct 27, 2026
Codex review on #9084: signature help built its Type definition link from
the caller's file, so for a type of an applied functor from another file
it pointed into the caller. It now takes the file from the type's
declaration, as hover does; the link function requires it, so no caller
can fall back to the wrong file.

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>
cknitt added a commit that referenced this pull request Oct 27, 2026
Codex review on #9084: the members of an applied functor are registered
under fresh stamps, so references to `IntSet.add` were no longer
references to `MakeSet.add`; Find References missed them and renaming the
declaration left them unchanged. Each renamed stamp now maps to the stamp
it was renamed from: a use of the member is also recorded as a use of
the original, and references starting from the member start from the
original.

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>
@cknitt

cknitt commented Oct 27, 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: 5ca5862e19

ℹ️ 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 analysis/src/process_extra.ml Outdated
Comment thread analysis/src/references.ml
cknitt added a commit that referenced this pull request Oct 27, 2026
Codex review on #9084: uses of a module path such as `M.Nested` were
recorded only under the renamed stamp. They are now also recorded under
the original, like value uses. The originals are taken from the functor's
result signature: when the argument is a path, the application's
signature was already renamed by the compiler and doesn't carry the
body's stamps.

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>
@cknitt

cknitt commented Oct 27, 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: ec52147ce9

ℹ️ 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 analysis/src/process_cmt.ml
@cknitt
cknitt force-pushed the fix-9072-applied-functor-types branch from ec52147 to c989f87 Compare October 28, 2026 07:58
cknitt added a commit that referenced this pull request Oct 28, 2026
Codex review on #9084: the members of `module M = Other.Make(X)` were
registered in the current file with the locations of Other's functor
body, so Go to Definition and hover's type-definition link combined
Other's location with the current file. Their module path now records
the functor, as it does for included modules, so both resolve to the
functor's file.

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>
cknitt added a commit that referenced this pull request Oct 28, 2026
Codex review on #9084: signature help built its Type definition link from
the caller's file, so for a type of an applied functor from another file
it pointed into the caller. It now takes the file from the type's
declaration, as hover does; the link function requires it, so no caller
can fall back to the wrong file.

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>
cknitt added a commit that referenced this pull request Oct 28, 2026
Codex review on #9084: the members of an applied functor are registered
under fresh stamps, so references to `IntSet.add` were no longer
references to `MakeSet.add`; Find References missed them and renaming the
declaration left them unchanged. Each renamed stamp now maps to the stamp
it was renamed from: a use of the member is also recorded as a use of
the original, and references starting from the member start from the
original.

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>
cknitt added a commit that referenced this pull request Oct 28, 2026
Codex review on #9084: uses of a module path such as `M.Nested` were
recorded only under the renamed stamp. They are now also recorded under
the original, like value uses. The originals are taken from the functor's
result signature: when the argument is a path, the application's
signature was already renamed by the compiler and doesn't carry the
body's stamps.

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>
cknitt added a commit that referenced this pull request Oct 28, 2026
Codex review on #9084: an applied functor's record fields and
constructors are read from its signature, where they have no location.
Go to Definition returned that missing location, and rename added it as a
reference, producing edits at character -1. Their lookups now go through
the type they were renamed from, which has the body's locations, and
fields and constructors without a location are not registered as
references.

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>
@cknitt

cknitt commented Oct 28, 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: c989f879df

ℹ️ 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 analysis/src/process_cmt.ml
@cknitt cknitt mentioned this pull request Oct 28, 2026
8 of 12 tasks
cknitt added a commit that referenced this pull request Oct 29, 2026
Codex review on #9084: the applied signature's module types were dropped,
because the signature walk handled modules but not module types, so a
member declared with one, such as `Applied.Nested.value` with
`module Nested: S`, no longer resolved. Module types are registered like
those of a structure 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>
@cknitt

cknitt commented Oct 29, 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: 7ef144ca10

ℹ️ 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 analysis/src/process_cmt.ml Outdated
cknitt added a commit that referenced this pull request Oct 29, 2026
…tions

Codex review on #9084: only a module type's own identifier was mapped to
the functor body's, not those inside its signature, so a member reached
through the applied module type, such as `X.value` with `X: Applied.S`,
was missing from the references and renames of `S.value`. Module type
signatures are now walked like those of modules.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Kbf3gGkPma9LAZimuQjnrP
Signed-off-by: Christoph Knittel <ck@cca.io>
@cknitt

cknitt commented Oct 29, 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: 3e7ca1f363

ℹ️ 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 analysis/src/process_cmt.ml Outdated
cknitt added a commit that referenced this pull request Oct 29, 2026
Codex review on #9084: an immediately applied inline functor was no longer
walked, so its parameters and declarations were missing and `O.compare` in
its body had no definition. The functor is walked again before its
application. The results of curried applications now take the body's
identifiers from the functor applied first, as the compiler had already
renamed those of the inner application.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Kbf3gGkPma9LAZimuQjnrP
Signed-off-by: Christoph Knittel <ck@cca.io>
@cknitt

cknitt commented Oct 29, 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: 47a17fa13b

ℹ️ 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 analysis/src/process_cmt.ml
Comment thread analysis/src/process_cmt.ml
cknitt added a commit that referenced this pull request Oct 29, 2026
Codex review on #9084: Go to Definition on a nested module and Go to Type
Definition paired the functor file's locations with the caller's URI. Both
now take the URI from the declaration's module path, like value
definitions. Fields and constructors of such a functor are found in its
file, and its items no longer register locations and references at the
same positions of the caller's file.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Kbf3gGkPma9LAZimuQjnrP
Signed-off-by: Christoph Knittel <ck@cca.io>
@cknitt

cknitt commented Oct 29, 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: 8c1673dd5d

ℹ️ 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 analysis/src/process_cmt.ml
@cknitt

cknitt commented Oct 29, 2026

Copy link
Copy Markdown
Member Author

@codex review

@chatgpt-codex-connector

Copy link
Copy Markdown

Codex Review: Didn't find any major issues. You're on a roll.

Reviewed commit: c4161881ae

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

cknitt and others added 11 commits October 29, 2026 13:11
Why:
    Editor analysis modelled `module M = F(X)` by F's own body, so hover
    and completion on M's items showed the types of the functor's body,
    with the parameter's types such as `O.t`, instead of the argument's.
    M is now modelled by the signature the compiler computed for the
    application. That signature keeps the identifiers of F's body, whose
    stamps already name the body's items, so it is renamed first.

Diagnostic modified (completion on an applied functor):
Example:
    module type Ord = {
      type t
      let compare: (t, t) => int
    }
    module MakeSet = (O: Ord) => {
      type t = array<O.t>
      let add = (s: t, x: O.t) => s->Array.concat([x])
    }
    module IntSet = MakeSet({
      type t = int
      let compare = (a: int, b) => a - b
    })
    // IntSet.
Before (text): tests/analysis_tests/tests/src/AppliedFunctor.res
    "detail": "(t, O.t) => array<O.t>"
After (text): tests/analysis_tests/tests/src/AppliedFunctor.res
    "detail": "(t, int) => array<int>"

Diagnostic modified (hover on a type of an applied functor):
Before (text):
    type IntSet.t = array<O.t>
After (text):
    type IntSet.t = array<int>

Review: Why raise the stamp counter before renaming?
    The renamed identifiers get stamps from the analysis process's own
    counter, which starts low and would hand out stamps that the typed
    tree already uses; above 2^40 they cannot meet one.

Fixes: #9072
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Kbf3gLMawVgtmiKy3TMBc3
Claude-Session: https://claude.ai/code/session_01Kr4cjoUi2f5VpMvE6wT9bo
Signed-off-by: Christoph Knittel <ck@cca.io>
Codex review on #9084: the members of `module M = Other.Make(X)` were
registered in the current file with the locations of Other's functor
body, so Go to Definition and hover's type-definition link combined
Other's location with the current file. Their module path now records
the functor, as it does for included modules, so both resolve to the
functor's file.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Kbf3gLMawVgtmiKy3TMBc3
Claude-Session: https://claude.ai/code/session_01Kr4cjoUi2f5VpMvE6wT9bo
Signed-off-by: Christoph Knittel <ck@cca.io>
Codex review on #9084: signature help built its Type definition link from
the caller's file, so for a type of an applied functor from another file
it pointed into the caller. It now takes the file from the type's
declaration, as hover does; the link function requires it, so no caller
can fall back to the wrong file.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Kbf3gLMawVgtmiKy3TMBc3
Claude-Session: https://claude.ai/code/session_01Kr4cjoUi2f5VpMvE6wT9bo
Signed-off-by: Christoph Knittel <ck@cca.io>
Codex review on #9084: the members of an applied functor are registered
under fresh stamps, so references to `IntSet.add` were no longer
references to `MakeSet.add`; Find References missed them and renaming the
declaration left them unchanged. Each renamed stamp now maps to the stamp
it was renamed from: a use of the member is also recorded as a use of
the original, and references starting from the member start from the
original.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Kbf3gLMawVgtmiKy3TMBc3
Claude-Session: https://claude.ai/code/session_01Kr4cjoUi2f5VpMvE6wT9bo
Signed-off-by: Christoph Knittel <ck@cca.io>
Codex review on #9084: uses of a module path such as `M.Nested` were
recorded only under the renamed stamp. They are now also recorded under
the original, like value uses. The originals are taken from the functor's
result signature: when the argument is a path, the application's
signature was already renamed by the compiler and doesn't carry the
body's stamps.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Kbf3gLMawVgtmiKy3TMBc3
Claude-Session: https://claude.ai/code/session_01Kr4cjoUi2f5VpMvE6wT9bo
Signed-off-by: Christoph Knittel <ck@cca.io>
Codex review on #9084: an applied functor's record fields and
constructors are read from its signature, where they have no location.
Go to Definition returned that missing location, and rename added it as a
reference, producing edits at character -1. Their lookups now go through
the type they were renamed from, which has the body's locations, and
fields and constructors without a location are not registered as
references.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Kbf3gLMawVgtmiKy3TMBc3
Claude-Session: https://claude.ai/code/session_01Kr4cjoUi2f5VpMvE6wT9bo
Signed-off-by: Christoph Knittel <ck@cca.io>
Codex review on #9084: the applied signature's module types were dropped,
because the signature walk handled modules but not module types, so a
member declared with one, such as `Applied.Nested.value` with
`module Nested: S`, no longer resolved. Module types are registered like
those of a structure now.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Kbf3gLMawVgtmiKy3TMBc3
Claude-Session: https://claude.ai/code/session_01Kr4cjoUi2f5VpMvE6wT9bo
Signed-off-by: Christoph Knittel <ck@cca.io>
…tions

Codex review on #9084: only a module type's own identifier was mapped to
the functor body's, not those inside its signature, so a member reached
through the applied module type, such as `X.value` with `X: Applied.S`,
was missing from the references and renames of `S.value`. Module type
signatures are now walked like those of modules.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Kbf3gGkPma9LAZimuQjnrP
Claude-Session: https://claude.ai/code/session_01Kr4cjoUi2f5VpMvE6wT9bo
Signed-off-by: Christoph Knittel <ck@cca.io>
Codex review on #9084: an immediately applied inline functor was no longer
walked, so its parameters and declarations were missing and `O.compare` in
its body had no definition. The functor is walked again before its
application. The results of curried applications now take the body's
identifiers from the functor applied first, as the compiler had already
renamed those of the inner application.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Kbf3gGkPma9LAZimuQjnrP
Claude-Session: https://claude.ai/code/session_01Kr4cjoUi2f5VpMvE6wT9bo
Signed-off-by: Christoph Knittel <ck@cca.io>
Codex review on #9084: Go to Definition on a nested module and Go to Type
Definition paired the functor file's locations with the caller's URI. Both
now take the URI from the declaration's module path, like value
definitions. Fields and constructors of such a functor are found in its
file, and its items no longer register locations and references at the
same positions of the caller's file.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Kbf3gGkPma9LAZimuQjnrP
Claude-Session: https://claude.ai/code/session_01Kr4cjoUi2f5VpMvE6wT9bo
Signed-off-by: Christoph Knittel <ck@cca.io>
A use of a member of a functor applied from another file referred to the
caller's copy, so references and renames no longer crossed files as they
did when the application resolved to the functor. Such a use refers to the
functor's member again, for values, types, fields, constructors and
modules, and a signature's nested modules now name their items' paths.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Kbf3gGkPma9LAZimuQjnrP
Claude-Session: https://claude.ai/code/session_01Kr4cjoUi2f5VpMvE6wT9bo
Signed-off-by: Christoph Knittel <ck@cca.io>
@cknitt
cknitt force-pushed the fix-9072-applied-functor-types branch from c416188 to d22c654 Compare October 29, 2026 13:17
Review fix: a functor from another file applied through a local alias,
such as `module Make = AppliedFunctor.MakeSet` then `Make(IntOrd)`, kept
the alias as the members' source, so Go to Definition and type-definition
links pointed into the caller at the functor's line numbers, and uses
didn't reach the functor's references and renames. The source is now the
path the compiler resolved the alias chain to, through modules too.

Analysis modified (go to definition of an applied member):
Example:
    module Make = AppliedFunctor.MakeSet
    module Aliased = Make(AppliedFunctor.IntOrd)
    let a = Aliased.add([], 1)
Before (text): definition of `add`
    file:///AppliedFunctorUse.res 7:6-7:9
After (text): definition of `add`
    file:///AppliedFunctor.res 7:6-7:9

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Kr4cjoUi2f5VpMvE6wT9bo
Signed-off-by: Christoph Knittel <ck@cca.io>
@cknitt

cknitt commented Oct 29, 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: ff8f5bef7b

ℹ️ 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 on lines +262 to +264
| Tmod_ident _ | Tmod_structure _ | Tmod_functor _ | Tmod_constraint _
| Tmod_unpack _ ->
mod_expr.mod_type

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Recover original stamps through named partial applications

When a curried functor is applied in separate bindings, for example module First = MakeTwo(IntOrd) followed by module Final = First(IntOrd), body_type stops at the Tmod_ident for First. Its result signature already contains identifiers renamed by the compiler's first application (Typemod.type_module calls Subst.modtype for path arguments), so record_renamed_stamps maps Final's members to those intermediate identifiers rather than the declarations in MakeTwo's body. Consequently, Find References and Rename from the original member omit Final.member, and renaming from that usage misses the declaration. Resolve the named partial application's original result identities before recording this mapping, rather than handling only applications nested in one expression.

Useful? React with 👍 / 👎.

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.

Hover and completion on an applied functor show the functor body's types

1 participant