miri
miri copied to clipboard
`cargo miri test` hangs on doc-tests with edition 2024
cargo miri test hangs on doc-tests with edition 2024 with cargo 1.87.0-nightly (ce948f461 2025-02-14).
Steps to reproduce:
- Create a project:
$ cargo init --lib --edition 2024 foo
- Put this in
src/lib.rs:
/// ```
/// foo::bar();
/// ```
pub fn bar() {}
- Run
cargo +nightly miri test:
$ cargo +nightly miri test
⋮
running 0 tests
test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.03s
Doc-tests foo
It hangs on Doc-tests foo. If you change the edition to 2021 in Cargo.toml it no longer hangs.
It looks like the behavior of rustdoc that cargo-miri was relying on changed in the 2024 edition. I'm sure it changed for the better, we just need equivalent tweaks to cargo-miri.
...and also we don't test cargo-miri very much 🤦
We do test cargo-miri quite a bit but not on edition 2024.^^
Cc @rust-lang/rustdoc in case you have an idea what might have changed here.
Rustdoc combined tests is the biggest change I remember happening. If cargo-miri is looking for the test binaries itself or somehow relying on one test-per-binary that may be a problem?
Skimming the code and running with debug-output it looks like cargo-miri isn't relying on that, it's probably some issue with the --test-builder integration, it hangs after:
[cargo-miri rustdoc] running command:
MIRI_CALLED_FROM_RUSTDOC="1"
"rustdoc"
"--edition=2024"
"--crate-type" "lib"
"--color" "auto"
"--crate-name" "foo"
"--test" "src/lib.rs"
"--test-run-directory" "/tmp/scratch.rust.2025-02-23T13-20.lXPYnS/foo"
"--target" "x86_64-unknown-linux-gnu"
"-C" "panic=abort"
"-L" "dependency=/home/nemo157/.cache/cargo/target/shared/miri/x86_64-unknown-linux-gnu/debug/deps"
"-L" "dependency=/home/nemo157/.cache/cargo/target/shared/miri/debug/deps"
"--extern" "foo=/home/nemo157/.cache/cargo/target/shared/miri/x86_64-unknown-linux-gnu/debug/deps/libfoo-b7c6659b6edbedff.rmeta"
"-C" "embed-bitcode=no"
"--check-cfg" "cfg(docsrs,test)"
"--check-cfg" "cfg(feature, values())"
"--error-format" "human"
"-Zunstable-options"
"--sysroot" "/home/nemo157/.cache/miri"
"--cfg" "miri"
"--test-builder" "/nix/store/kapbv1gd461aiyb40d1v5ypyiharb03z-rust-minimal-1.86.0-nightly-2025-02-09/bin/.cargo-miri-wrapped"
"--runtool" "/nix/store/kapbv1gd461aiyb40d1v5ypyiharb03z-rust-minimal-1.86.0-nightly-2025-02-09/bin/.cargo-miri-wrapped"
...
DEBUG rustdoc::doctest compiler invocation for doctest:
"/nix/store/kapbv1gd461aiyb40d1v5ypyiharb03z-rust-minimal-1.86.0-nightly-2025-02-09/bin/.cargo-miri-wrapped"
"@/tmp/nix-shell.sDyCLQ/rustdoctest4iQR71/rustdoc-cfgs"
"--sysroot=/home/nemo157/.cache/miri"
"--edition" "2024"
"-o" "/tmp/nix-shell.sDyCLQ/rustdoctesthOn9M8/rust_out"
"--target" "x86_64-unknown-linux-gnu"
"--color" "always"
"--error-format=short"
"/tmp/nix-shell.sDyCLQ/rustdoctesthOn9M8/doctest_2024.rs"
while in edition=2021 the final line looks like (then it continues to actually compile and run the tests):
DEBUG rustdoc::doctest compiler invocation for doctest:
UNSTABLE_RUSTDOC_TEST_LINE="-1"
UNSTABLE_RUSTDOC_TEST_PATH="src/lib.rs"
"/nix/store/kapbv1gd461aiyb40d1v5ypyiharb03z-rust-minimal-1.86.0-nightly-2025-02-09/bin/.cargo-miri-wrapped"
"@/tmp/nix-shell.sDyCLQ/rustdoctestbaqfQx/rustdoc-cfgs"
"--sysroot=/home/nemo157/.cache/miri"
"--edition" "2021"
"-o" "/tmp/nix-shell.sDyCLQ/rustdoctestQ9jEuV/rust_out"
"--target" "x86_64-unknown-linux-gnu"
"--color" "always"
"-"
(the rustdoc-cfgs are identical between the two).
The biggest difference is using a file vs. stdin for the code, looks like cargo-miri assumes rustdoc always uses stdin:
https://github.com/rust-lang/miri/blob/939ae796f9ac121a6948a20013dd3b58da9f97d8/cargo-miri/src/phases.rs#L377
Ah yes, we do feed the file to rustdoc via stdin. Hm, will we have to detect the edition to know whether to forward stdin or not?
Should be able to just check if the final arg is - (hopefully rustdoc never puts flags after the file arg? EDIT: it's at least true with the current implementation).
We can fairly easily check if an arg of - is present, that should work. It's hard to tell apart positional arguments from flags but - shouldn't otherwise occur.
Strangely, if I try to reproduce this in test-cargo-miri, doctests work fine even after setting the edition to 2024. Is there something about workspaces with mixed editions where the new behavior won't kick in? That would make it quite annoying to test...
No I just can't reproduce this at all. I followed your instructions, @orium , but everything works fine here.
$ cargo +miri miri test
Compiling foo v0.1.0 (/home/r/src/rust/tmp/foo)
Finished `test` profile [unoptimized + debuginfo] target(s) in 0.11s
Running unittests src/lib.rs (target/miri/x86_64-unknown-linux-gnu/debug/deps/foo-8a458c35bf738a5d)
running 1 test
test tests::it_works ... ok
test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.22s
Doc-tests foo
running 1 test
test src/lib.rs - bar (line 1) ... ok
test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.09s
Can you share more details about your setup? OS/version, anything else you can think of?
https://github.com/rust-lang/miri/pull/4248 can't reproduce this on any of our CI systems either.
I can try and re-reproduce what I did to test it with old and new nightlies in a bit, there were some changes to how combined doctests get generated so it may not be an issue anymore.
Yes: the issue is gone. Miri no longer hangs!
Thanks for confirming!
Odd, I wish I knew what changed, since this may come back in the future... I'll try to add a test in CI that would hopefully catch this, but ofc it's hard to be sure.