Skip to content

Commit d5e0d6a

Browse files
committed
fix: keep [Stdlib]-provider lib in [kept_libs] under narrowing
Every OCaml/Melange compile implicitly opens [Stdlib] before reading its source. The implicit open is not visible in [ocamldep -modules] output (ocamldep reports only modules named in source), so it never appears in the BFS frontier and the lib that provides [Stdlib] is dropped from [kept_libs] under L6's filtered-include-flags path. For OCaml-mode compiles this is typically invisible: [Stdlib] lives on the compiler's built-in include path (via [+stdlib]); no dune-managed lib provides a module named [Stdlib], so the [Lib_index] lookup for [Stdlib] is empty and no narrowing decision depends on it. For Melange-mode compiles (post-L10), [Stdlib] lives in the [melange]/[stdlib] dune library, and dropping its [-I] from a consumer's compile rule causes [Error: Unbound module Stdlib] at the [-open] resolution step the moment that consumer's source references any [Stdlib] type ([int], [float], etc.) without syntactically naming a [Stdlib.X] member. Force [Stdlib] onto the initial BFS frontier in [lib_deps_for_module] alongside [all_raw] and [open_modules]. The injection is mode-agnostic — the [Lib_index] lookup decides what (if anything) to include: - Typical OCaml project: no dune lib named [Stdlib], lookup is empty, zero effect. - Melange project: pulls in the [melange]/[stdlib] lib via the normal classification path. Fixes the Stdlib-resolution bug. - Unwrapped OCaml lib that exports a [Stdlib] module (rare): the lookup hits and that lib's [-I] + [Stdlib.cmi] are kept in every consumer's compile rule. Matches the broad-dep path's behavior pre-narrowing — slight precision loss (extra dep) but soundness preserved. - Wrapped lib with a [Stdlib.ml] sibling: index records only the wrapper name, lookup is empty, no effect. Reproduced and fixed against: - belt unit lib (melange 6.0.1-54): rebuild from scratch under L10 dune now produces all [belt__Belt_*.cmi]/[cmj] artefacts (was failing with [Error: Unbound module Stdlib] on every [.pp.mli] whose source did not syntactically name [Stdlib.X]). - ocaml#14732 CI: macOS opam [Install deps] step failed compiling melange.6.0.1-54 with hundreds of identical errors, same root cause. Signed-off-by: Robin Bate Boerop <me@robinbb.com>
1 parent 6cf56fa commit d5e0d6a

1 file changed

Lines changed: 16 additions & 1 deletion

File tree

src/dune_rules/module_compilation.ml

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -180,7 +180,22 @@ let lib_deps_for_module ~cctx ~obj_dir ~for_ ~dep_graph ~opaque ~cm_kind ~ml_kin
180180
let all_raw = Module_name.Set.union m_raw trans_raw in
181181
let* flags = Ocaml_flags.get (Compilation_context.flags cctx) mode in
182182
let open_modules = Ocaml_flags.extract_open_module_names flags in
183-
let referenced = Module_name.Set.union all_raw open_modules in
183+
(* [Stdlib] is implicitly opened by every compile and so is referenced by
184+
every consumer even when ocamldep doesn't list it. For OCaml-mode
185+
compiles the compiler's built-in stdlib path supplies it (no dune lib
186+
to keep); for Melange-mode compiles the [melange]/[stdlib] lib supplies
187+
it as a regular dune dependency, and would otherwise be dropped from
188+
[kept_libs] for consumers that don't syntactically name a [Stdlib.X]
189+
member. Force it onto the frontier so the [Lib_index] lookup adds it
190+
when present. *)
191+
let referenced =
192+
let implicit_stdlib =
193+
match Module_name.of_string_opt "Stdlib" with
194+
| Some n -> Module_name.Set.singleton n
195+
| None -> Module_name.Set.empty
196+
in
197+
Module_name.Set.union (Module_name.Set.union all_raw open_modules) implicit_stdlib
198+
in
184199
let { Lib_file_deps.Lib_index.tight; non_tight } =
185200
Lib_file_deps.Lib_index.filter_libs_with_modules
186201
lib_index

0 commit comments

Comments
 (0)