Repository navigation
Conversation
Running DCE on the ReScript compiler (OCaml 5.5, dune, native and browser profiles) produced several classes of false positives: - On case-insensitive file systems (macOS, Windows), a unit's sibling .cmt was found under two spellings, so the unit looked ambiguous and exceptions raised across modules of a wrapped library were reported as never raised. Sibling candidates now need an exact directory entry. - Type re-exports `type t = M.t = A | B` declare the same constructors and labels as `M.t`. They are now linked both ways (OCaml 5.3+, found through shapes), also when `M` is a local module alias, whose shape carries no uid of its own. - Types in a submodule of an interface (`module M : sig type t = A end`) were declared without the submodule path, so they never matched their implementation. - Several build trees of one project (e.g. two dune profiles) can now be analyzed together: sources found only in a build tree (generated files) are read from the nearest ancestor of the .cmt that contains them, and a unit compiled from the same source in several trees resolves to the copy strictly closest to the consumer. Ties stay ambiguous, as before. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Kbf3gLDo8mBJKpNE25WAwT
Member
Author
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.
Running DCE on the ReScript compiler's OCaml sources (OCaml 5.5.2, dune, native + browser profiles) surfaced several classes of false positives. This fixes them.
Fixes
candidateFilesForUnitprobes sibling files as bothUnit.cmtandunit.cmt. On a case-insensitive FS both exist, so one file was listed under two paths with different unit keys, and the lookup was rejected as ambiguous. Exceptions raised across modules of a dune wrapped library (raise (Lib.Mod.Exn ...)) were then reported as never raised. Sibling candidates now require an exact directory entry. (Same fix in value-dependency extraction.)type t = M.t = A | B. Constructors and labels are shared withM.t, but were tracked separately: constructingReexp.AleftOrig.A"never constructed", and readingorig.xleft the re-export's label "never read". The original declaration is now resolved through shapes (typeDeclOfPath, OCaml 5.3+) and same-named constructors/labels are linked both ways.module Child = Orighas an alias shape without the binding's uid, somoduleShapeOfPath (Pident Child)failed. It now follows the aliased path. This makes (2) work fortype t = Child.t = ....module Color : sig type setting = Auto | Never end) were declared without the submodule in their path (setting.Autoinstead ofColor.setting.Auto), so they never matched the implementation and the.mlconstructors looked unused.processSignatureItemnow passes its path toDeadType.addDeclaration._build/defaultand a--profile browserbuild that contains extra executables). Needed so that uses that exist in only one configuration count..cmts are relative to the build root andcmt_builddiris normalized to/workspace_root. When a source isn't found from the cwd or scan root, it is now looked up in the ancestors of the.cmt(dune's.ml-genwrappers excepted). The directory is remembered so reports and-writeread the right file.ambiguous-provider-contextsexpectation is unchanged.Effect on the ReScript compiler
Reports dropped from 1221 to 1138. That's about 80 false positives removed plus 13 recovered uses from the browser-only playground. The remaining reports I checked were genuine, apart from known semantics (fields read only via polymorphic
=, exception aliases that are only matched).New tests
examples/regression:Type_reexport*(re-export via another module and via a local alias; constructors, labels, and genuinely unused ones still reported) andNested_sig_type*(types in an.mlisubmodule), with assertions inrun_integration_tests.js. The re-export assertions are gated on OCaml ≥ 5.3.scripts/test_build_trees.js: one library built in two trees with different generatedplatform.ml, consumers in another directory, analyzed together from the source tree. It fails without the ancestor lookup and without the closest-copy rule.The case-insensitive FS fix has no automated test, because CI is Linux-only and a case-insensitive FS can't be simulated there. I verified it manually on a macOS-backed mount: a wrapped-library repro went from 4 false "never raised" reports to 0.
🤖 Generated with Claude Code
https://claude.ai/code/session_01Kbf3gLDo8mBJKpNE25WAwT