rust-lang / rust-lang/rust

Infinite recursion when reordering bounds in where clause

Open
#126,864 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

A-trait-system C-bug fixed-by-next-solver T-types
Dominant language
Rust
Stars
119k
Forks
16.1k
PR merge metrics
PR metrics pending

Description

I ran into this issue while playing around with the type system a bit.

The code
struct Entity {
    id: u32,
}

trait Item {
    type Id;
}

impl Item for Entity {
    type Id = u32;
}

trait Get<Path, Output> {
    fn get(&self, path: &Path) -> Option<&Output>;
}

struct VecIndex<P, I>
where
    State: Get<P, Vec<I>>,
    I: Item,
{
    path: P,
    id: I::Id,
}

impl<P, I> Get<VecIndex<P, I>, I> for State
where
    State: Get<P, Vec<I>>,
    I: Item,
{
    fn get(&self, path: &VecIndex<P, I>) -> Option<&I> {
        todo!();
    }
}

struct State;

struct EntitiesPath;

impl Get<EntitiesPath, Vec<Entity>> for State {
    fn get(&self, _: &EntitiesPath) -> Option<&Vec<Entity>> {
        todo!()
    }
}

struct EntityIdPath<P>
where
    State: Get<P, Entity>,
{
    path: P,
}

impl<P> Get<EntityIdPath<P>, u32> for State
where
    State: Get<P, Entity>,
{
    fn get(&self, path: &EntityIdPath<P>) -> Option<&u32> {
        todo!()
    }
}

fn main() {
    let path = VecIndex {
        path: EntitiesPath,
        id: 23,
    };

    let path = EntityIdPath { path };
}
The problem

I couldn't get this code to compile after introducing the Item trait and adding the I bound to the where clause. I kept getting

error[E0275]: overflow evaluating the requirement `State: Get<VecIndex<_, Vec<Vec<Vec<Vec<...>>>>>, ...>`

After basically giving up, I was tidying up the code a bit and when I swapped the order of the bounds in the where clauses (I: Item with State: Get<..>), the code suddently compiled.

Only the where clause for the Get impl seems to matter in this case. Very concretely, this complies:

impl<P, I> Get<VecIndex<P, I>, I> for State
where
    I: Item,
    State: Get<P, Vec<I>>,
{
    // ...
}

But this doesn't:

impl<P, I> Get<VecIndex<P, I>, I> for State
where
    State: Get<P, Vec<I>>,
    I: Item,
{
    // ...
}
Related

I was trying to find related issues but had a hard time narrowing it down. I think it might be related to https://github.com/rust-lang/rust/issues/112991, but I don't understand what is happening here well enough to really judge.

Meta

I tested it on multiple versions of nightly (including the latest 1.81.0) and stable, the error is present in all of them.

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 by compiling the reduced Rust example and compare diagnostics with the two orderings of the Get impl's where clause. Investigate the overflow requirement involving nested VecIndex and Get bounds, using issue 112991 as related context; done means the valid ordering no longer changes compilation behavior or produces infinite recursion.

Written by the indexing model from the issue text.

Assessment

Tech stack
rust
Domain
compilers
Issue type
Bug
Difficulty
5/5
Estimated time
Over a week
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.