From aae05cd8357c715ce7c8e17fa2e63dc2e752c718 Mon Sep 17 00:00:00 2001 From: Robin Bate Boerop Date: Wed, 8 Apr 2026 19:07:50 -0400 Subject: [PATCH] test: document module name shadowing between stanza and library When an internal module name shadows an unwrapped library's module name, the internal module takes precedence and the library's module is inaccessible. This means ocamldep will report the internal module, not the library's, so dependency filtering that treats stanza-internal names as non-library references is correct. Signed-off-by: Robin Bate Boerop --- .../module-name-shadowing.t | 68 +++++++++++++++++++ 1 file changed, 68 insertions(+) create mode 100644 test/blackbox-tests/test-cases/per-module-lib-deps/module-name-shadowing.t diff --git a/test/blackbox-tests/test-cases/per-module-lib-deps/module-name-shadowing.t b/test/blackbox-tests/test-cases/per-module-lib-deps/module-name-shadowing.t new file mode 100644 index 00000000000..a7d7b52dfba --- /dev/null +++ b/test/blackbox-tests/test-cases/per-module-lib-deps/module-name-shadowing.t @@ -0,0 +1,68 @@ +Test that when a stanza's internal module name shadows a library module name, +the internal module takes precedence. This validates that ocamldep-based +dependency filtering (which treats modules defined within the same stanza as +internal) correctly reflects the compiler's resolution order. + +See: https://github.com/ocaml/dune/issues/4572 + + $ cat > dune-project < (lang dune 3.0) + > EOF + +--- Unwrapped library: internal module shadows library module --- + +An unwrapped library exposes module Helper. The executable also has a module +named Helper. The internal module takes precedence — the library's Helper is +inaccessible. + + $ mkdir unwrapped_lib + $ cat > unwrapped_lib/dune < (library + > (name unwrapped_lib) + > (wrapped false)) + > EOF + + $ cat > unwrapped_lib/helper.ml < let lib_value = 42 + > EOF + + $ cat > unwrapped_lib/helper.mli < val lib_value : int + > EOF + + $ cat > dune < (executable + > (name main) + > (libraries unwrapped_lib)) + > EOF + + $ cat > helper.ml < let local_value = 1 + > EOF + + $ cat > main.ml < let () = print_int Helper.local_value + > EOF + +The build succeeds using the internal Helper: + + $ dune build ./main.exe + +The dependencies of main.ml's native compilation show dune__exe__Helper +(the internal module), not unwrapped_lib's helper: + + $ dune rules --deps _build/default/.main.eobjs/native/dune__exe__Main.cmx | grep dune__exe__Helper + (File (In_build_dir _build/default/.main.eobjs/byte/dune__exe__Helper.cmi)) + +The library's Helper.lib_value is not accessible: + + $ cat > main.ml < let () = print_int Helper.lib_value + > EOF + + $ dune build ./main.exe + File "main.ml", line 1, characters 19-35: + 1 | let () = print_int Helper.lib_value + ^^^^^^^^^^^^^^^^ + Error: Unbound value Helper.lib_value + [1]