Skip to content

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

Description

@466774321-code

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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-mir-optArea: MIR optimizationsA-mir-opt-inliningArea: MIR inliningC-bugCategory: This is a bug.I-cycleIssue: A query cycle occurred while none was expectedI-prioritizeIssue needs a team member to assess the impact. Will be replaced by P-{low,medium,high,critical}S-has-bisectionStatus: A bisection has been found for this issueT-compilerRelevant to the compiler team, which will review and decide on the PR/issue.regression-from-stable-to-stablePerformance or correctness regression from one stable version to another.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions