Clippy behavior affected by incremental compilation


#1

I recently failed to notice an improper use of write (when I should have been using write_all) in my code that was treated as a hard warning by Clippy.

However, I failed to find the issue with clippy, because cargo clippy and cargo check both gave me no output (other than the “Finished…” message), regardless of what command line arguments I used.

I find this behavior surprising and footgun-y. I wasn’t doing anything strange with my setup or Clippy usage (incremental compilation is on by default), and I wasn’t aware of this as a possible pitfall; I only discovered the problem because someone else happened to run Clippy on a clean copy of my codebase. (Even then, neither of us suspected that the state of the target folder would impact Clippy’s behavior, so it took me a while to even try cargo clean.)

So I have a few questions:

  1. Is there an easy way to force Clippy to re-evaluate all code without actually deleting the cached build output? I shouldn’t need to delete correctly-compiled code just to apply a linter. (Obviously I could do this in Bash: mv target{,.hide}; cargo clippy; rm -rf target/; mv target{.hide,} … but that seems like a kludge.) Would temporarily turning off incremental compilation force Clippy to perform a full analysis?
  2. How can I advocate/facilitate/design a fix for this issue? Even a warning like “some source files skipped because they have already been compiled” would at least give the user a heads-up about what’s going on. But ideally, the set of warnings and errors emitted by Clippy would never depend on the state of target, only on the state of src.
  3. Once this issue has been addressed for Clippy, would it be reasonable to push for a similar feature in rustc/cargo that would somehow cache warnings and ensure they are re-emitted even when the source file has not changed since the last build?

#2

This is tracked on the Clippy side with https://github.com/rust-lang/rust-clippy/issues/2604. For your point #1, you can use touch src/lib.rs or whatever your root source file is to force a recompile.

Recently there was support added to Cargo to force a rebuild for cargo fix, but it is not exposed externally. I’m not sure if this is the approach we ultimately want to go for clippy.

Eventually we want to cache diagnostic output. This is tracked in https://github.com/rust-lang/cargo/issues/3624. It is a relatively tricky problem to handle cross-platform. Recently, the fwdansi crate was created and added to Cargo which is one of the steps to move this along. Cargo also now streams all rustc output, which was another step on this journey. I think at this point, the final bits need to be designed. Cargo needs to save off the diagnostics, and then replay them if the target is fresh. There are some tricky issues, like invalidating the cache if flags like --color or --message-format are changed. There was some discussion of always using JSON with rustc, and having Cargo responsible for re-rendering for text output, but that has additional complications (but some benefits).

I can try to take a look at moving this along sometime soonish.