Interaction between incremental compilation and --emit

Right now they don't play very well together, consider a simple example

$ export RUSTFLAGS="--emit asm"
$ cargo new --lib foo
     Created library `foo` package
$ cargo build -q
$ touch src/lib.rs
$ cargo build
error: could not copy 
  "/path/to/foo/target/debug/deps/foo-e307cc7fa7b6d64f.4qbzn9k8mosu50a5.rcgu.s" 
  to "/path/to/foo/target/debug/deps/foo-e307cc7fa7b6d64f.s": 
  No such file or directory (os error 2)

Incremental compilation logic checks if changes are needed since I touch lib.rs, sees that nothing needs to be done and at the end it fails since there was no codegen and .s was not produced.

Documentation for --emit doesn't specify when files should be created so behavior "We did no codegen therefore no .s files for you" would be valid, but not very useful from end user point of view.

To achieve useful behavior where files are produced even if no real work is done like with .rlib, etc, I see two options:

  • emitted files are stored in the incremental compilation cache and retrieved when needed
  • files are regenerated from from available information after data is fetched from incremental cache

Later approach seem fragile and I can imagine situation where codegen will have to run again just to produce those files.

Thoughts?

There's several tickets about this issue: Failure on subsequent builds when `--emit asm` used without `-C save-temps`. · Issue #89149 · rust-lang/rust · GitHub