Well, okay. It seems I have understood why that fails while I've been spelling the issue out as a to-be-posted issue in Cargo.
Consider the following project layout (source code):
libexample
[dev-dependencies] ├─ Cargo.toml <----------+
| ├─ lib.rs |
| └─ tests |
| ├─ test.rs |
| └─ utils |
+-------------> ├─ Cargo.toml [dependencies]
└─ lib.rs
There are multiple tests there:
-
example has
#[cfg(test)]
unit tests using utils
-
tests/test.rs is an integration test using both example and utils
-
utils have their own
#[cfg(test)]
unit tests
Now, libexample
builds fine:
$ cargo build
Unit tests for tests/utils
build and run fine:
$ cd tests/utils
$ cargo test
The integration test tests/test.rs
builds and runs fine:
$ cd -
$ cargo test --test test
But unit tests for example
fail to build:
$ cargo test --lib
Compiling example v0.1.0 (file:///home/ilammy/dev/libexample)
Compiling utils v0.1.0 (file:///home/ilammy/dev/libexample/tests/utils)
error[E0308]: mismatched types
--> lib.rs:18:23
|
18 | assert!(equal(Number(4), double(Number(2))));
| ^^^^^^^^^ expected struct `example::Number`, found struct `Number`
|
= note: expected type `example::Number`
= note: found type `Number`
error[E0308]: mismatched types
--> lib.rs:18:34
|
18 | assert!(equal(Number(4), double(Number(2))));
| ^^^^^^^^^^^^^^^^^ expected struct `example::Number`, found struct `Number`
|
= note: expected type `example::Number`
= note: found type `Number`
error: aborting due to 2 previous errors
error: Could not compile `example`.
To learn more, run the command again with --verbose.
It seems that in this case utils use their own example-as-utils-dependency crate, and example-as-itself is a different one and cannot be reused.
I expect The dependency graph to look something like this:
+-------> (1) example.rlib <---- (3) utils.rlib (with #[cfg(test)])
| ^ ^
tests (5) | |
| | |
+-------> (2) utils.rlib (4) utils
^
|
|
(6) example.rlib (with #[cfg(test)])
^
|
|
(7) example
(1) and (6) are different crates and their Numbers are in fact different and cannot be used interchangeably. Unit tests in (7) create Numbers from (6) while its dependency (2) works only with Numbers from (1).
--verbose
output seems to confirm this:
Cargo output
$ cargo test --lib --verbose
Compiling example v0.1.0 (file:///home/ilammy/dev/libexample)
Running `rustc lib.rs --crate-name example --crate-type lib -g
-C metadata=b5e747e7654ba59a --out-dir /home/ilammy/dev/libexample/target/debug/deps
--emit=dep-info,link -L dependency=/home/ilammy/dev/libexample/target/debug/deps`
Compiling utils v0.1.0 (file:///home/ilammy/dev/libexample/tests/utils)
Running `rustc tests/utils/lib.rs --crate-name utils --crate-type lib -g
-C metadata=39d3d7de3615e756 --out-dir /home/ilammy/dev/libexample/target/debug/deps
--emit=dep-info,link -L dependency=/home/ilammy/dev/libexample/target/debug/deps
--extern example=/home/ilammy/dev/libexample/target/debug/deps/libexample.rlib`
Running `rustc lib.rs --crate-name example -g --test
-C metadata=0a02a15d79a43617 -C extra-filename=-0a02a15d79a43617
--out-dir /home/ilammy/dev/libexample/target/debug/deps
--emit=dep-info,link -L dependency=/home/ilammy/dev/libexample/target/debug/deps
--extern utils=/home/ilammy/dev/libexample/target/debug/deps/libutils.rlib`
error[E0308]: mismatched types
--> lib.rs:18:23
|
18 | assert!(equal(Number(4), double(Number(2))));
| ^^^^^^^^^ expected struct `example::Number`, found struct `Number`
|
= note: expected type `example::Number`
= note: found type `Number`
error[E0308]: mismatched types
--> lib.rs:18:34
|
18 | assert!(equal(Number(4), double(Number(2))));
| ^^^^^^^^^^^^^^^^^ expected struct `example::Number`, found struct `Number`
|
= note: expected type `example::Number`
= note: found type `Number`
error: aborting due to 2 previous errors
error: Could not compile `example`.
Caused by:
process didn't exit successfully: `rustc lib.rs --crate-name example -g --test
-C metadata=0a02a15d79a43617 -C extra-filename=-0a02a15d79a43617
--out-dir /home/ilammy/dev/libexample/target/debug/deps
--emit=dep-info,link -L dependency=/home/ilammy/dev/libexample/target/debug/deps
--extern utils=/home/ilammy/dev/libexample/target/debug/deps/libutils.rlib`
(exit code: 101)
$ cargo test --test test --verbose
Fresh utils v0.1.0 (file:///home/ilammy/dev/libexample/tests/utils)
Compiling example v0.1.0 (file:///home/ilammy/dev/libexample)
Running `rustc tests/test.rs --crate-name test -g --test
-C metadata=1dfc87e5a6315fee -C extra-filename=-1dfc87e5a6315fee
--out-dir /home/ilammy/dev/libexample/target/debug
--emit=dep-info,link -L dependency=/home/ilammy/dev/libexample/target/debug/deps
--extern utils=/home/ilammy/dev/libexample/target/debug/deps/libutils.rlib
--extern example=/home/ilammy/dev/libexample/target/debug/deps/libexample.rlib`
Finished debug [unoptimized + debuginfo] target(s) in 0.30 secs
Running `/home/ilammy/dev/libexample/target/debug/test-1dfc87e5a6315fee`
running 1 test
test test ... ok
test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured