rust-lang / rust-lang/rust

Valid mutually recursive functions fail with E0391 at opt-level 2 and 3

Open
#161,234 5 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

A-mir-opt A-mir-opt-inlining C-bug I-cycle I-prioritize regression-from-stable-to-stable S-has-bisection T-compiler
Dominant language
Rust
Stars
119k
Forks
16.1k
PR merge metrics
PR metrics pending

Description

I tried this code:

fn a() {
    b();
    c();
}

fn b() {
    a();
    d();
}

fn c() {
    d();
    b();
}

fn d() {
    c();
    a();
}

fn main() {
    a();
}

Compile it with:

rustc -C opt-level=2 repro.rs

The same problem also occurs with:

rustc -C opt-level=3 repro.rs

I expected to see this happen:

The program should compile successfully. Mutually recursive functions are valid Rust.

The program recurses indefinitely and will eventually overflow the stack if it is executed, but this runtime behavior should not prevent compilation.

Instead, this happened:

Compilation fails with E0391:

error[E0391]: cycle detected when whether the item should be made inlinable across crates
 --> repro.rs:1:1
  |
1 | fn a() {
  | ^^^^^^
  |
  = note: ...which requires optimizing MIR for `a`...
note: ...which requires whether the item should be made inlinable across crates...
  --> repro.rs:11:1
   |
11 | fn c() {
   | ^^^^^^
   = note: ...which requires optimizing MIR for `c`...
note: ...which requires whether the item should be made inlinable across crates...
 --> repro.rs:6:1
  |
6 | fn b() {
  | ^^^^^^
  = note: ...which requires optimizing MIR for `b`...
note: ...which requires whether the item should be made inlinable across crates...
  --> repro.rs:16:1
   |
16 | fn d() {
   | ^^^^^^
   = note: ...which requires optimizing MIR for `d`...
   = note: ...which again requires whether the item should be made inlinable across crates, completing the cycle
note: cycle used when optimizing MIR for `main`
  --> repro.rs:21:1
   |
21 | fn main() {
   | ^^^^^^^^^

error: aborting due to 1 previous error

I tested the minimized reproducer with the latest stable and nightly toolchains available on 2026-08-17.

Toolchain -C opt-level=0 -C opt-level=1 -C opt-level=2 -C opt-level=3
Latest stable 1.97.1 Compiles Compiles E0391 E0391
Latest nightly 1.100.0-nightly (2026-08-16) Compiles Compiles E0391 E0391

This is a minimized/reduced standalone test case.

The cycle appears to be in rustc's MIR optimization / cross-crate inlinability queries. Such an internal query cycle should not cause rustc to reject an otherwise valid Rust program.

Meta

Latest stable:

rustc --version --verbose:

rustc 1.97.1 (8bab26f4f 2026-07-14)
binary: rustc
commit-hash: 8bab26f4f68e0e26f0bb7960be334d5b520ea452
commit-date: 2026-07-14
host: x86_64-unknown-linux-gnu
release: 1.97.1
LLVM version: 22.1.6

Latest nightly:

rustc +nightly --version --verbose:

rustc 1.100.0-nightly (34baba539 2026-08-16)
binary: rustc
commit-hash: 34baba5394fcbda4cba7b7c1964a6db421c77c91
commit-date: 2026-08-16
host: x86_64-unknown-linux-gnu
release: 1.100.0-nightly
LLVM version: 23.1.0
Backtrace

Not applicable: rustc does not panic. It reports E0391 and aborts compilation.

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start with the minimized standalone reproducer in the issue and run it with rustc at opt-level 0 through 3 to confirm the regression. Then trace rustc's MIR optimization and cross-crate inlinability queries around the E0391 cycle. Done means the reproducer compiles successfully at opt-level 2 and 3 without rejecting valid mutually recursive functions.

Written by the indexing model from the issue text.

Assessment

Tech stack
rust
Domain
compilers
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Quiet
Clarity
Clearly specified
Newbie friendliness
55/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.