Semantic Diff

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

6 commits

beb423d9411b3e39f7c07cd8bed109d485f33339..pr-9084

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

Use the applied signature for modules created by functor application

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.

modifiedDiagnostic 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
Before tests/analysis_tests/tests/src/AppliedFunctor.res
After tests/analysis_tests/tests/src/AppliedFunctor.res
"detail": "(t, O.t) => array<O.t>""detail": "(t, int) => array<int>"

modifiedDiagnostic hover on a type of an applied functor

text
Before
After
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.
8e3cbb2ef · cknitt + Claude · Oct 27, 2026, 17:45 UTC

Keep the functor's file for members of an applied functor

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.

934e2ec8b · cknitt + Claude · Oct 27, 2026, 20:22 UTC

Link signature help type definitions to their declaring file

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.

0e4be6590 · cknitt + Claude · Oct 27, 2026, 20:22 UTC

Connect renamed members of an applied functor to their declarations

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.

39c5bf6dd · cknitt + Claude · Oct 27, 2026, 21:23 UTC

Connect nested modules of an applied functor to their declarations

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.

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

Resolve applied fields and constructors to the functor's declarations

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.