Skip to content

Circularly defined GAT is somehow allowed and ICEs Miri #149898

@theemathas

Description

@theemathas

I tried this code:

trait NotImplemented {}

trait Trait {
    type Assoc<T: Trait>: NotImplemented;
}

struct Thing;
impl Trait for Thing {
    type Assoc<T: Trait> = T::Assoc<T>;
}

fn foo<T: Trait>() {
    let _: Option<&<T as Trait>::Assoc<T>> = None;
}

fn main() {
    foo::<Thing>();
}

This code probably shouldn't compile, since <Thing as Trait>::Assoc<Thing> is circularly defined. Instead, it compiles and runs without errors.

Running this code with Miri gives the following ICE:

ICE with Miri
error[E0275]: overflow evaluating the requirement `<Thing as Trait>::Assoc<Thing> == _`


Miri caused an ICE during evaluation. Here's the interpreter backtrace at the time of the panic:
note: the place in the program where the ICE was triggered
  --> src/main.rs:13:46
   |
13 |     let _: Option<&<T as Trait>::Assoc<T>> = None;
   |                                              ^^^^
   |
   = note: BACKTRACE:
   = note: inside `foo::<Thing>` at src/main.rs:13:46: 13:50
note: inside `main`
  --> src/main.rs:17:5
   |
17 |     foo::<Thing>();
   |     ^^^^^^^^^^^^^^
   = note: inside `<fn() as std::ops::FnOnce<()>>::call_once - shim(fn())` at /Users/timch/.rustup/toolchains/nightly-aarch64-apple-darwin/lib/rustlib/src/rust/library/core/src/ops/function.rs:250:5: 250:71
   = note: inside `std::sys::backtrace::__rust_begin_short_backtrace::<fn(), ()>` at /Users/timch/.rustup/toolchains/nightly-aarch64-apple-darwin/lib/rustlib/src/rust/library/std/src/sys/backtrace.rs:160:18: 160:21
   = note: inside closure at /Users/timch/.rustup/toolchains/nightly-aarch64-apple-darwin/lib/rustlib/src/rust/library/std/src/rt.rs:206:18: 206:75
   = note: inside `std::ops::function::impls::<impl std::ops::FnOnce<()> for &dyn std::ops::Fn() -> i32 + std::marker::Sync + std::panic::RefUnwindSafe>::call_once` at /Users/timch/.rustup/toolchains/nightly-aarch64-apple-darwin/lib/rustlib/src/rust/library/core/src/ops/function.rs:287:13: 287:31
   = note: inside `std::panicking::catch_unwind::do_call::<&dyn std::ops::Fn() -> i32 + std::marker::Sync + std::panic::RefUnwindSafe, i32>` at /Users/timch/.rustup/toolchains/nightly-aarch64-apple-darwin/lib/rustlib/src/rust/library/std/src/panicking.rs:581:40: 581:43
   = note: inside `std::panicking::catch_unwind::<i32, &dyn std::ops::Fn() -> i32 + std::marker::Sync + std::panic::RefUnwindSafe>` at /Users/timch/.rustup/toolchains/nightly-aarch64-apple-darwin/lib/rustlib/src/rust/library/std/src/panicking.rs:544:19: 544:88
   = note: inside `std::panic::catch_unwind::<&dyn std::ops::Fn() -> i32 + std::marker::Sync + std::panic::RefUnwindSafe, i32>` at /Users/timch/.rustup/toolchains/nightly-aarch64-apple-darwin/lib/rustlib/src/rust/library/std/src/panic.rs:359:14: 359:40
   = note: inside closure at /Users/timch/.rustup/toolchains/nightly-aarch64-apple-darwin/lib/rustlib/src/rust/library/std/src/rt.rs:175:24: 175:49
   = note: inside `std::panicking::catch_unwind::do_call::<{closure@std::rt::lang_start_internal::{closure#0}}, isize>` at /Users/timch/.rustup/toolchains/nightly-aarch64-apple-darwin/lib/rustlib/src/rust/library/std/src/panicking.rs:581:40: 581:43
   = note: inside `std::panicking::catch_unwind::<isize, {closure@std::rt::lang_start_internal::{closure#0}}>` at /Users/timch/.rustup/toolchains/nightly-aarch64-apple-darwin/lib/rustlib/src/rust/library/std/src/panicking.rs:544:19: 544:88
   = note: inside `std::panic::catch_unwind::<{closure@std::rt::lang_start_internal::{closure#0}}, isize>` at /Users/timch/.rustup/toolchains/nightly-aarch64-apple-darwin/lib/rustlib/src/rust/library/std/src/panic.rs:359:14: 359:40
   = note: inside `std::rt::lang_start_internal` at /Users/timch/.rustup/toolchains/nightly-aarch64-apple-darwin/lib/rustlib/src/rust/library/std/src/rt.rs:171:5: 193:7
   = note: inside `std::rt::lang_start::<()>` at /Users/timch/.rustup/toolchains/nightly-aarch64-apple-darwin/lib/rustlib/src/rust/library/std/src/rt.rs:205:5: 210:6

error: aborting due to 1 previous error

For more information about this error, try `rustc --explain E0275`.

Additionally, compiling the code with -Zmir-opt-level=1 works without errors. However, compiling with -Zmir-opt-level=0 gives the following error:

Error with -Zmir-opt-level=0
error[E0275]: overflow evaluating the requirement `<Thing as Trait>::Assoc<Thing> == _`

For more information about this error, try `rustc --explain E0275`.
error: could not compile `foo` (bin "foo") due to 1 previous error

Also, changing the let _ into let _x gives the following error when compiled normally (identical to the above error):

Error with let _x
error[E0275]: overflow evaluating the requirement `<Thing as Trait>::Assoc<Thing> == _`

For more information about this error, try `rustc --explain E0275`.
error: could not compile `foo` (bin "foo") due to 1 previous error

Changing the code to let _x and also using cargo check instead of cargo build makes the code compile again.

Possibly related to #135246, #135011, and #115175

Meta

rustc --version --verbose:

rustc 1.94.0-nightly (f52090008 2025-12-10)
binary: rustc
commit-hash: f5209000832c9d3bc29c91f4daef4ca9f28dc797
commit-date: 2025-12-10
host: aarch64-apple-darwin
release: 1.94.0-nightly
LLVM version: 21.1.5

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-GATsArea: Generic associated types (GATs)A-associated-itemsArea: Associated items (types, constants & functions)A-mir-optArea: MIR optimizationsA-miriArea: The miri toolA-trait-systemArea: Trait systemC-bugCategory: This is a bug.I-ICEIssue: The compiler panicked, giving an Internal Compilation Error (ICE) ❄️T-typesRelevant to the types team, which will review and decide on the PR/issue.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions