It's always bugged me that
--emit metadata produces different output depending on what else is being emitted - that is, check builds vs pipelined builds.
I've run into this in a very concrete way while trying to implement manual, brute-force pipelining to increase build parallelism for a non-Cargo build system. That is, separately invoke
rustc --emit metadata to produce inputs for dependent libraries, and
rustc --emit link for the final link.
(Yes, this is strictly less efficient than a pipelined build as the frontend work is duplicated. I have the limitation that I can't get intermediate results until the action is complete, but the problem I'm solving is that there isn't enough parallelism available to fill all the cores so the duplicate work shouldn't matter.)
This nearly works except that rustc crashes with:
error: internal compiler error: compiler/rustc_mir/src/monomorphize/collector.rs:826:9: no MIR available for DefId(18:3 ~ bar::bar)
I can work around this with
-Zalways-encode-mir=yes, but of course that's unstable.
So back to the original question: what if we had
--emit check to generate minimal metadata suitable for check builds, and make
--emit metadata unconditionally produce full mir-enabled metadata?
This would be backwards compatible (with old invokers not knowing about
check getting a perf hit from
metadata, but no functional loss). Forwards compatibility would require
cargo check to see if
--emit check (perhaps streamlined by adding
rustc --print emits?).
And it would also restore the property that artifacts produced by
--emit are independent of the other artifacts, so that invoking rustc once or multiple times is just a performance difference, not a functional one.
Or is there some other solution I've overlooked? Another option would be to keep the existing behaviour and stabilize
-Zalways-emit-mir, but I feel that's less clean (but definitely simpler to implement).