rust-lang / rust-lang/rust

Compiler hang due to exponentially growing type using GAT

Open
#155,476 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

A-GATs C-bug fixed-by-next-solver I-hang T-compiler
Dominant language
Rust
Stars
119k
Forks
16.1k
PR merge metrics
PR metrics pending

Description

The following code (playground) causes a compiler hang:

trait Ty: Deferred {
    type Gat<T>: Ty;
}
trait Deferred {
    type Eval: Ty;
}

type G<A, B> = <Eval<A> as Ty>::Gat<B>;
type Eval<N> = <N as Deferred>::Eval;

pub struct Rec<L, R>(L, R);
impl<L: Deferred, R: Deferred> Deferred for Rec<L, R> {
    type Eval = G<
        L,
        G<
            Eval<
                Rec<
                    L::Eval, //
                    R::Eval,
                >,
            >,
            Eval<
                Rec<
                    L::Eval, //
                    R::Eval,
                >,
            >,
        >,
    >;
}

impl Ty for () {
    type Gat<T> = ();
}
impl Deferred for () {
    type Eval = Self;
}
fn main() {
    size_of::<Eval<Rec<(), ()>>>();
}

Some notes about the code:

  • Rec::<L,R>::Eval expands to G<L, G<Rec::<L', R'>::Eval, Rec::<L',R'>::Eval>>, an infinite loop with exponential growth.
  • G<L, ...> looks redundant, but is somehow necessary.
  • From my testing, G must be a GAT.
  • The compiler correctly errors when using -Znext-solver.

Versions: Stable 1.95.0, Nightly 2026-04-09

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 linked Rust Playground reproducer and compare stable behavior with -Znext-solver, which the report says rejects the example. Trace the GAT and type-alias evaluation path responsible for the expanding Rec::Eval projection; done means the compiler no longer hangs on the reproducer and retains the reported diagnostic behavior.

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
Mostly clear
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.