Which functions are "reachable", and therefore subject to monomorphization-time checks, is optimization-dependent
Nobody has claimed this yet.
- Dominant language
- Rust
- Stars
- 119k
- Forks
- 16.2k
- PR merge metrics
- PR metrics pending
Description
This is a variant of https://github.com/rust-lang/rust/issues/107503, but with a different underlying cause and hence not fixed by https://github.com/rust-lang/rust/pull/122568. @tmiasko provided this magnificent example (comments by me, they may be wrong):
//! This used to fail in optimized builds but pass in unoptimized builds. The reason is that in
//! optimized builds, `f` gets marked as cross-crate-inlineable, so the functions it calls become
//! reachable, and therefore `g` becomes a collection root. But in unoptimized builds, `g` is no
//! root, and the call to `g` disappears in an early `SimplifyCfg` before "mentioned items" are
//! gathered, so we never reach `g`.
#![crate_type = "lib"]
struct Fail<T>(T);
impl<T> Fail<T> {
const C: () = panic!(); //~ERROR: evaluation of `Fail::<i32>::C` failed
}
pub fn f() {
loop {}; g()
}
#[inline(never)]
fn g() {
h::<i32>()
}
// Make sure we only use the faulty const in a generic function, or
// else it gets evaluated by some MIR pass.
fn h<T>() {
Fail::<T>::C;
}
The symptom here is the opposite of https://github.com/rust-lang/rust/issues/107503: cargo build succeeds but cargo build --release fails. This is because more things become roots in optimized builds and therefore we evaluate more things.
I can think of two ways of fixing this:
- Making the set of collection roots opt-level-independent. This is what I tried in https://github.com/rust-lang/rust/commit/a303df006a5be15f799fdb9f987ac083f8de191d. It caused a ~2% slowdown on some benchmarks; it's hard to get the full picture as we only benchmarked it together with the rest of https://github.com/rust-lang/rust/pull/122568. There may be ways to reduce this cost.
- Make sure
gis considered "mentioned" inf. This requires either collecting (some of) the mentioned items very early during MIR building, or makingSimplifyCfgpreserved unreachable blocks. This likely has lower perf impact, but it means we'd still miss const-eval failures reachable from dead private monomorphic functions.
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Use the Rust snippet in the issue as the reproducer; compare cargo build with cargo build --release and inspect how collection roots and “mentioned” items differ around MIR SimplifyCfg. A complete fix should make the diagnostic behavior independent of optimization while addressing the performance or dead-private-function trade-off described in the proposed approaches.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- rust
- Domain
- compilers
- Issue type
- Bug
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 25/100