-
Notifications
You must be signed in to change notification settings - Fork 409
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Demonstrate various types of module cycles that aren't cycles if we separate the module interface and module implementation graphs Signed-off-by: Rudi Grinberg <me@rgrinberg.com>
- Loading branch information
Showing
1 changed file
with
78 additions
and
0 deletions.
There are no files selected for viewing
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,78 @@ | ||
This test demonstrate a dependency cycle if we consider nodes as modules, but a | ||
valid dependency graph if we consider the implementations and interfaces of | ||
modules as having separate dependencies. | ||
|
||
Reproduces #7018 | ||
|
||
$ cat >dune-project <<EOF | ||
> (lang dune 3.7) | ||
> EOF | ||
$ cat >dune <<EOF | ||
> (library | ||
> (wrapped false) | ||
> (name foobar)) | ||
> EOF | ||
|
||
$ cat >x.mli <<EOF | ||
> type t = unit | ||
> EOF | ||
|
||
$ cat >y.mli <<EOF | ||
> val foo : X.t -> unit | ||
> EOF | ||
$ cat >y.ml <<EOF | ||
> let foo _ = () | ||
> EOF | ||
|
||
$ runtest() { | ||
> cat >x.ml <<EOF | ||
> type t = unit | ||
> let () = Y.foo $1 | ||
> EOF | ||
> dune build | ||
> } | ||
|
||
First we try to construct X.t directly | ||
|
||
$ runtest "()" | ||
Error: dependency cycle between modules in _build/default: | ||
X | ||
-> X | ||
-> required by _build/default/foobar.a | ||
-> required by alias all | ||
-> required by alias default | ||
File "x.ml", line 2, characters 15-17: | ||
2 | let () = Y.foo () | ||
^^ | ||
Error: This expression has type t but an expression was expected of type X.t | ||
X.t is abstract because no corresponding cmi file was found in path. | ||
[1] | ||
|
||
Now we use a polymorphic type: | ||
|
||
$ runtest "(assert false)" | ||
Error: dependency cycle between modules in _build/default: | ||
X | ||
-> X | ||
-> required by _build/default/foobar.a | ||
-> required by alias all | ||
-> required by alias default | ||
[1] | ||
|
||
Or, we can use another module: | ||
|
||
$ cat > unit.ml <<EOF | ||
> let x = () | ||
> EOF | ||
$ cat > unit.mli <<EOF | ||
> val x : X.t | ||
> EOF | ||
|
||
$ runtest "Unit.x" | ||
Error: dependency cycle between modules in _build/default: | ||
X | ||
-> X | ||
-> required by _build/default/foobar.a | ||
-> required by alias all | ||
-> required by alias default | ||
[1] |