rust-lang / cargo

The Rust package manager
https://doc.rust-lang.org/cargo
Apache License 2.0
12.76k stars 2.42k forks source link

cargo build shows cached transient build errors #8830

Open pwaller opened 4 years ago

pwaller commented 4 years ago

Problem

I'm reporting this as a user experience problem as a rust newbie.

If there is a transient error during compilation causing the compiler to emit errors, cargo build shows the cached error output.

The issue I'm filing is that there is cached error output, not the specific error message generated, because the situation is a confusing one to get into, in my case taking my usual actions did not cause the cache to go away, and I was unaware I was looking at cached output. The output gently implied a real and current condition.

I'm using the vscode rust (0.7.8) and rust-analyzer extensions (0.2.368). It seems these are known to have an issue where if you run cargo at the command line it can conflict with cargo running inside vscode. In my case, it resulted in warnings like the following:

[elide 28 identical errors]
error: failed to remove /home/pwaller/Projects/thumbs/target/debug/build/thumbs-42b683eb45e99a75/build_script_build-42b683eb45e99a75.4r7yql6ivq9vl3qo.rcgu.o: No such file or directory (os error 2)
warning: Error finalizing incremental compilation session directory `/home/pwaller/Projects/thumbs/target/debug/incremental/build_script_build-mmzgn3kthere/s-fsnqv6p9fg-1nrsky3-working`: No such file or directory (os error 2)
error: aborting due to 29 previous errors
    Finished dev [unoptimized + debuginfo] target(s) in 0.01s

The problem is that these errors are now sticky. Somehow, I get these errors every time I run, even though I'm doing a rebuild and getting a successful rebuild. It's true that these files don't exist. What's implied is that the error condition remains, but it's actually cached build output. I'm not expecting that this is cached build output since I have actually changed my target. In this case the thing which is cached looks to my eyes to be the build script, which I'm not changing (but I didn't realise this until writing this bug report). I'm using bindgen.

Steps

Described in the problem statement. Sorry, I'm unable to provide a reliable reproducer at this time, since it likely came as a race between two cargo invocations (one at command line, and one through vscode), though I explain above how I got here.

Possible Solution(s)

If a build step has error output, it probably shouldn't be permanently cached in this way, otherwise how can it respond to transient errors? How can a user fix this transient error?

Workaround: I was able to workaround this by eliminating my target directory. (As a newbie I wasn't expecting this to have any effect, I was expecting a reliable reproducible build of sorts, so the same result each time).

As a newcomer to rust this behaviour was confusing to me - I didn't realise that cargo was printing cached output until I attached rr to cargo run to find the source of the messages was in cargo::core::compiler::replay_output_cache. I also didn't expect errors to be shown but to get a successful re-compilation.

Notes

Someone reported a now closed issue, a very similar one running vscode on WSL: https://github.com/rust-lang/rust/issues/62031

Output of cargo version:

Ubuntu 20.04.

cargo 1.43.0 (2cbe9048e 2020-05-03)
alexcrichton commented 4 years ago

Thanks for the report, and what an interesting issue! Cargo caches the output of rustc and will replay it when subsequent builds are done, primarily to replay warning diagnostics. This is an unusual case though where rustc prints a warning/error despite compilation being successful. Cargo doesn't know this, however, and treats it like any other lint warning.

This seems like it might be best fixed with a flag in rustc in the JSON message with the diagnostic indicating whether Cargo should ignore it or not on replays. For example these messages seem largely advisory and not critical to compilation or code, so presumably Cargo could just skip replaying these messages.