runtimeverification / runtimeverification/stable-mir-json
The Curious Case of stdlib: nightly compatibility findings
Nobody has claimed this yet.
- Dominant language
- Rust
- Stars
- 11
- Forks
- 6
- PR merge metrics
- No merged PRs in 30d
Description
Context
I set out to answer a simple question: can stable-mir-json emit smir.json for Rust's standard library? Turns out the answer is yes, but the journey there surfaced some interesting findings about the nightly compatibility story.
What happened
-
Caught a rustc layout panic.
ty.layout()returnsResult<Layout, Error>, promising graceful failure. But for certain types (specificallycore::fmt::Formatter<'_>, whose&mut dyn fmt::Writefield triggers aSizedcheck on a trait object with escaping bound vars), rustc panics instead of returningErr. I wrapped the call incatch_unwindto keep going (see the fix commit for the full call chain analysis). This is arguably a rustc bug; theResultcontract should have caught this before it became a panic at the stable MIR API boundary. -
Added
make stdlib-smir. A single command that builds stable-mir-json, creates a throwaway crate in a temp directory, runs-Zbuild-stdthrough the driver, and collects the resultingsmir.jsonartifacts. Againstnightly-2024-11-29, this produces 21 artifacts (~100MB total), includingstd(44MB, 11,950 items),core(16MB),alloc,proc_macro, and all their transitive dependencies. -
Binary-searched for the most recent working nightly. This is where the compat layer's value became clear.
Nightly compatibility: what I found
Starting from the pinned nightly-2024-11-29, I walked forward to find how far the current codebase can go without changes:
| Nightly | Status | Breaking change |
|---|---|---|
2024-11-29 (pinned) |
builds | |
2024-12-14 |
builds | (last working) |
2024-12-15 |
1 error | AggregateKind::CoroutineClosure added |
2025-01-15 |
1 error | same |
2025-03-01 |
7 errors | more stable MIR API evolution |
2025-07-14 |
44 errors | accumulated breakage |
2026-03-07 |
can't find crate | stable_mir renamed to rustc_public |
A natural question: shouldn't the compat layer handle all of these? Turns out, no; and that's by design. The breaks fall into two categories:
Category 1: rustc internals (compat handles these). Crate renames (stable_mir to rustc_public, rustc_smir to rustc_public_bridge), function signature changes, struct field changes. These are one-line fixes in compat/mod.rs or compat/*.rs. The 13-month stress test (ADR-003) validated this.
Category 2: stable MIR public API evolution (compat intentionally does not handle these). New enum variants (AggregateKind::CoroutineClosure), changed parameter types (Rvalue::AddressOf), removed variants (StatementKind::Deinit). These are types that printer/ and mk_graph/ directly pattern-match on. Any consumer of stable MIR would face the same breakage; wrapping every enum in a compat shim would mean reimplementing the entire API surface, defeating the purpose.
What the compat layer tells us
The compat layer's value here isn't that it magically absorbs all changes; it's that it gives a clean diagnostic signal. When you bump the nightly and hit errors:
- Errors in
src/compat/orsrc/driver.rs: rustc internals shifted. Fix them in-place; nothing else needs to change. - Errors in
src/printer/orsrc/mk_graph/: stable MIR's public contract evolved. These require real code changes (new match arms, updated call sites), and any stable MIR consumer would need the same fixes.
Without the compat layer, both categories would be tangled together across the entire codebase, and there'd be no way to tell which changes are mechanical (rename/re-export) vs. semantic (new language feature support).
What needs to happen to support newer nightlies
The first break (nightly-2024-12-15) is a single new enum variant: AggregateKind::CoroutineClosure. That's a straightforward match arm addition. Beyond that, the stable MIR API changes accumulate gradually (7 errors by March 2025, 44 by July 2025), and the crate rename lands around July 2025.
A reasonably cromulent plan:
- Handle
CoroutineClosureand the other stable MIR API changes inprinter/andmk_graph/(these are real semantic additions, not compat busywork) - Add compat aliases for the
stable_mir->rustc_publicrename (one-line change, already validated in the stress test) - Bump the pinned nightly
Each step is independently testable: build, run integration tests, run make stdlib-smir, run make test-ui.
Contributor guide
No contributing guide indexed for this repository
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
Start with the pinned nightly and the compatibility paths in src/compat/, then inspect the stable MIR pattern matches in src/printer/ and src/mk_graph/. Build against the newer nightly and run the integration tests, make stdlib-smir, and make test-ui; done means the planned compatibility and API changes build and those checks pass.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- rust
- Domain
- compilers
- Issue type
- Feature
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 45/100