Skip to content

Rustc "overflow evaluating the requirement" while it should work. #96634

@wdanilo

Description

@wdanilo

Consider this code:

#![recursion_limit = "256"]

pub trait Visit<T: ?Sized> {
    fn visit(&mut self, elem: &T);
}

pub enum Ast {
    Null,
    App(Box<Ast>,Box<Ast>)
}

impl<T> Visit<Ast> for T
where T: Visit<Box<Ast>> {
    fn visit(&mut self, elem: &Ast) {}
}

impl<T,S:?Sized> Visit<Box<S>> for T
where T: Visit<S> {
    fn visit(&mut self, elem: &Box<S>) {}
}

pub struct MyVisitor{}

fn test() {
    MyVisitor{}.visit(&Ast::Null);
}

Playground: https://play.rust-lang.org/?version=stable&mode=debug&edition=2021&gist=9014c0167fc65f14c8a2668428fc5df4

It gives the error:

error[[E0275]](https://doc.rust-lang.org/stable/error-index.html#E0275): overflow evaluating the requirement `MyVisitor: Visit<_>`
  [--> src/lib.rs:25:17
](https://play.rust-lang.org/?version=stable&mode=debug&edition=2021&gist=9014c0167fc65f14c8a2668428fc5df4#)   |
25 |     MyVisitor{}.visit(&Ast::Null);
   |                 ^^^^^
   |
   = help: consider increasing the recursion limit by adding a `#![recursion_limit = "512"]` attribute to your crate (`playground`)
   = note: required because of the requirements on the impl of `Visit<Box<_>>` for `MyVisitor`
   = note: 256 redundant requirements hidden
   = note: required because of the requirements on the impl of `Visit<Box<Box<Box<Box<Box<Box<Box<Box<Box<Box<Box<Box<Box<Box<Box<Box<Box<Box<Box<Box<Box<Box<Box<Box<Box<Box<Box<Box<Box<Box<Box<Box<Box<Box<Box<Box<Box<Box<Box<Box<Box<Box<Box<Box<Box<Box<Box<Box<Box<Box<Box<Box<Box<Box<Box<Box<Box<Box<Box<Box<Box<Box<Box<Box<Box<Box<Box<Box<Box<Box<Box<Box<Box<Box<Box<Box<Box<Box<Box<Box<Box<Box<Box<Box<Box<Box<Box<Box<Box<Box<Box<Box<Box<Box<Box<Box<Box<Box<Box<Box<Box<Box<Box<Box<Box<Box<Box<Box<Box<Box<Box<Box<Box<Box<Box<Box<Box<Box<Box<Box<Box<Box<Box<Box<Box<Box<Box<Box<Box<Box<Box<Box<Box<Box<Box<Box<Box<Box<Box<Box<Box<Box<Box<Box<Box<Box<Box<Box<Box<Box<Box<Box<Box<Box<Box<Box<Box<Box<Box<Box<Box<Box<Box<Box<Box<Box<Box<Box<Box<Box<Box<Box<Box<Box<Box<Box<Box<Box<Box<Box<Box<Box<Box<Box<Box<Box<Box<Box<Box<Box<Box<Box<Box<Box<Box<Box<Box<Box<Box<Box<Box<Box<Box<Box<Box<Box<Box<Box<Box<Box<Box<Box<Box<Box<Box<Box<Box<Box<Box<Box<Box<Box<Box<Box<Box<Box<Box<Box<Box<Box<Box<Box<Box<Box<Box<Box<Box<Box<Box<Box<Box<Box<Box<Box<Box<Box<Box<Box<Box<Box<Box<Box<Box<Box<Box<Box<Box<_>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>` for `MyVisitor`

For more information about this error, try `rustc --explain E0275`.
error: could not compile `playground` due to previous error

Which does not make sense. Let me explain:

  1. We do MyVisitor{}.visit(&Ast::Null), which requires a bound MyVisitor: Visit<Ast>.
  2. This bound is implemented (impl<T> Visit<Ast> for T), so another bound to be checked is added, which is MyVisitor: Visit<Box<Ast>>.
  3. This bound is again implemented (impl<T,S:?Sized> Visit<Box<S>> for T), which while resolving (T is MyVisitor and S is Ast) results in another bound to be resolved: MyVisitor: Visit<Ast>. However, this is our initial bound that we are currently resolving so it should compile fine.

A few things to be noted:

  1. The code compiles if the function test is commented out (only the usage throws the error (the impls are correct)).
  2. The Box<Box<Box<... situation should never happen in the Rustc type resolver - there is something wrong happening under the hood.

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-trait-systemArea: Trait systemC-bugCategory: This is a bug.T-compilerRelevant to the compiler team, which will review and decide on the PR/issue.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