Description
Problem
Over at Zed we've noticed that even seemingly innocent changes to the crate that has many dependents causes us to rebuild (almost) the whole world. Adding a dbg!
statement to the body of non-inlineable function, formatting code, updating a dependency to a new minor version and such still forces us to rebuild all dependants of an affected crate.
Our build graph could probably be improved by splitting out crates into smaller units, but the underlying issue is that we're rebuilding the world even when the public API of a crate did not change.
Attached is our timing file for making non-public-facing change to one of the core crates of Zed: timings.zip
What could take about 9 seconds (rebuilding project + relinking zed) takes 18 seconds instead.
Proposed Solution
There are efforts in flight to make Cargo rely less on mtime as a trigger for rebuilding the crate, but we are interested in an even stronger form of this PR where only a change to the public API of a crate should trigger a rebuild of the downstream dependants.
Notes
We have an internal prototype for one potential solution that relies on rustc emitting a hash of the public API of a crate as a part of it's "Metadata Finished" notification (Zulip Thread, rustc and cargo).