Conversation
Values in a functor body whose result is constrained to a module type defined in another module (via .mli or inline) are reported dead even when instances are used from live code.
When a module or functor result is constrained to a module type defined in another file (via .mli or inline), the typed tree's declaration dependencies link each implementation value to the `val` item of that module type, which lives in another compilation unit's cmt. The extractor only loaded the local cmt and cmti, so those links were dropped and every value in the functor body was reported dead. - Index all cmt/cmti files by compilation unit up front and resolve foreign uids from them (OCaml 5.3+). - Defer processing of value dependencies until all files are scanned. When the signature side is not a declaration (a `val` inside a named module type), forward the references made to it onto the implementation rather than treating it as an always-live reference, so unused items in the signature are still reported.
- In ReScript project mode, collect the cmt files of every source directory before processing any, so declaration dependencies across directories resolve. - When forwarding references from a module-type val item onto its implementation, also forward the recorded optional-argument calls. Otherwise a call like H.f ~x:1 () through a constrained functor result would report x as never used. Covered by with_opt in the fixture.
The analysis root can contain several units with the same name (e.g. unwrapped libraries in different directories). Their declarations share uids, so merging every candidate into one table first-one-wins could resolve a functor's module type constraint to the wrong unit and leave a used value reported dead. Cross-unit lookups now keep one declaration table per candidate file, narrow the candidates down using the interface digest the importer recorded in cmt_imports, and consult every remaining candidate when the digest cannot disambiguate. Adds a regression fixture with two unwrapped libraries defining Dup_sig.
JonoPrest
force-pushed
the
jono-fix-functor-false-positive
branch
from
September 17, 2026 10:12
6a83d4b to
dc2d4de
Compare
Contributor
Author
|
@codex review |
JonoPrest
marked this pull request as ready for review
September 17, 2026 10:20
Contributor
Author
|
I can't stack PRs from my fork owned branches so closed for #217 |
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.
When a functor result is constrained to a module type defined in another file, every value in the functor body is reported dead even when instances are used from live code.
Before:
find_optandhash.Makeare reported dead. Expected: onlyunused_in_sigandtruly_dead.On OCaml 5.3+ the
find_optbinding depends on the uid ofval find_optingen.ml, but the dependency extractor only loaded the local.cmt/.cmti, so the link was dropped.Fix:
valin a module type rather than a declaration, forward its references onto theimplementation, so unused signature items are still reported.
Fixtures cover
.mliand inline constraints, plus a duplicate-unit regre