diff --git a/src/dune_rules/scope.ml b/src/dune_rules/scope.ml index 91513dc4b6f5..de097e1a0b0f 100644 --- a/src/dune_rules/scope.ml +++ b/src/dune_rules/scope.ml @@ -441,6 +441,12 @@ module DB = struct | Deprecated_library_name { old_name = old_public_name, _; _ } -> Public_lib.name old_public_name ;; + + let loc = function + | Library lib -> Lib.Local.to_lib lib |> Lib.info |> Lib_info.loc + | Deprecated_library_name { old_name = old_public_name, _; _ } -> + Public_lib.loc old_public_name + ;; end let lib_entries_of_package = @@ -502,6 +508,39 @@ module DB = struct in fun (ctx : Context_name.t) pkg_name -> let+ map = per_context ctx in - Package.Name.Map.Multi.find map pkg_name + match Package.Name.Map.Multi.find map pkg_name with + | ([] | [ _ ]) as xs -> xs + | libs -> + let _by_name = + List.fold_left libs ~init:Lib_name.Map.empty ~f:(fun by_name entry2 -> + let public_name = Lib_entry.name entry2 in + Lib_name.Map.update by_name public_name ~f:(function + | None -> Some entry2 + | Some entry1 -> + let loc1 = Lib_entry.loc entry1 + and loc2 = Lib_entry.loc entry2 in + let main_message = + Pp.textf + "Public library %s is defined twice:" + (Lib_name.to_string public_name) + in + let annots = + let main = User_message.make ~loc:loc2 [ main_message ] in + let related = + [ User_message.make ~loc:loc1 [ Pp.text "Already defined here" ] ] + in + User_message.Annots.singleton + Compound_user_error.annot + [ Compound_user_error.make ~main ~related ] + in + User_error.raise + ~annots + ~loc:loc2 + [ main_message + ; Pp.textf "- %s" (Loc.to_file_colon_line loc1) + ; Pp.textf "- %s" (Loc.to_file_colon_line loc2) + ])) + in + libs ;; end diff --git a/test/blackbox-tests/test-cases/lib-collision/lib-collision-public-same-public-name-same-folder.t b/test/blackbox-tests/test-cases/lib-collision/lib-collision-public-same-public-name-same-folder.t new file mode 100644 index 000000000000..b925fd7d492f --- /dev/null +++ b/test/blackbox-tests/test-cases/lib-collision/lib-collision-public-same-public-name-same-folder.t @@ -0,0 +1,53 @@ +Public libraries using the same library name, in the same context, defined in +the same folder. + + $ mkdir -p a b + + $ cat > dune-project << EOF + > (lang dune 3.13) + > (package (name bar) (allow_empty)) + > EOF + + $ cat > a/dune << EOF + > (library + > (name foo) + > (public_name bar.foo)) + > (library + > (name bar) + > (public_name bar.foo)) + > EOF + +Without any consumers of the libraries + + $ dune build + File "a/dune", lines 1-3, characters 0-44: + 1 | (library + 2 | (name foo) + 3 | (public_name bar.foo)) + Error: Public library bar.foo is defined twice: + - a/dune:4 + - a/dune:1 + [1] + +With some consumer + + $ cat > dune << EOF + > (executable + > (name main) + > (libraries foo)) + > EOF + + $ cat > main.ml < let () = Foo.x + > EOF + + $ dune build + File "a/dune", lines 1-3, characters 0-44: + 1 | (library + 2 | (name foo) + 3 | (public_name bar.foo)) + Error: Public library bar.foo is defined twice: + - a/dune:4 + - a/dune:1 + [1] + diff --git a/test/blackbox-tests/test-cases/lib-collision/lib-collision-public-same-public-name.t b/test/blackbox-tests/test-cases/lib-collision/lib-collision-public-same-public-name.t index 3ed2f14afeb1..c73066e69077 100644 --- a/test/blackbox-tests/test-cases/lib-collision/lib-collision-public-same-public-name.t +++ b/test/blackbox-tests/test-cases/lib-collision/lib-collision-public-same-public-name.t @@ -23,6 +23,14 @@ different folders. Without any consumers of the libraries $ dune build + File "b/dune", lines 1-3, characters 0-44: + 1 | (library + 2 | (name bar) + 3 | (public_name bar.foo)) + Error: Public library bar.foo is defined twice: + - a/dune:1 + - b/dune:1 + [1] With some consumer @@ -37,11 +45,11 @@ With some consumer > EOF $ dune build - File "a/dune", lines 1-3, characters 0-44: + File "b/dune", lines 1-3, characters 0-44: 1 | (library - 2 | (name foo) + 2 | (name bar) 3 | (public_name bar.foo)) - Error: Library with name "bar.foo" is already defined in b/dune:1. Either - change one of the names, or enable them conditionally using the 'enabled_if' - field. + Error: Public library bar.foo is defined twice: + - a/dune:1 + - b/dune:1 [1]