Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

error[E0275]: overflow evaluating the requirement _: std::marker::Sized #39959

Open
SimonSapin opened this issue Feb 19, 2017 · 25 comments
Open
Labels
A-diagnostics Area: Messages for errors, warnings, and lints C-bug Category: This is a bug. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.

Comments

@SimonSapin
Copy link
Contributor

Reduced test case:

#![recursion_limit = "5"]

fn main() {}

trait Serialize {}

struct Ser<'a, T: 'a>(&'a T);

impl<'a, T> Ser<'a, T> where Ser<'a, T>: Serialize {
    pub fn new(value: &'a T) -> Self {
        Ser(value)
    }
}

impl<'a, T> Serialize for Ser<'a, Option<T>> where Ser<'a, T>: Serialize {}

fn serialize<'a, T>(value: &'a T) where Ser<'a, T>: Serialize {
    Ser::new(value);
}

Output in rustc 1.17.0-nightly (536a900 2017-02-17):

error[E0275]: overflow evaluating the requirement `_: std::marker::Sized`
  --> a.rs:20:5
   |
20 |     Ser::new(value);
   |     ^^^^^^^^
   |
   = note: consider adding a `#![recursion_limit="10"]` attribute to your crate
   = note: required because of the requirements on the impl of `Serialize` for `Ser<'_, std::option::Option<_>>`
   = note: required because of the requirements on the impl of `Serialize` for `Ser<'_, std::option::Option<std::option::Option<_>>>`
   = note: required because of the requirements on the impl of `Serialize` for `Ser<'_, std::option::Option<std::option::Option<std::option::Option<_>>>>`
   = note: required because of the requirements on the impl of `Serialize` for `Ser<'_, std::option::Option<std::option::Option<std::option::Option<std::option::Option<_>>>>>`
   = note: required because of the requirements on the impl of `Serialize` for `Ser<std::option::Option<std::option::Option<std::option::Option<std::option::Option<std::option::Option<_>>>>>>`

error: aborting due to previous error

Without #![recursion_limit = "5"], the error message is similar but much larger. If this isn’t a bug, at least the diagnostic should be improved.

lloydmeta added a commit to lloydmeta/frunk that referenced this issue Apr 19, 2017
Sadly, due to rust-lang/rust#39959, we can't make take
the mapper by reference
lloydmeta added a commit to lloydmeta/frunk that referenced this issue Apr 19, 2017
* Add non-consuming Coproduct fold, HList map and foldLeft
* Missing HList foldRight because of rust-lang/rust#39959
@chrivers
Copy link

I've also hit this bug (is it fair to say it is a bug?)

I was able to condense my error condition down to

// the writing is on the wall, let's not look at the entire wall
#![recursion_limit="10"]

struct Encoder {}

trait CanEncode { fn write(self); }

impl Encoder {
    fn write<E: CanEncode>(&mut self, x: E) { x.write() }
}

impl<'a, T> CanEncode for &'a [T] where
    &'a T: CanEncode
{
    fn write(self) {}
}

fn main() {
    let mut wtr = Encoder {};
    wtr.write::<&[_]>(42).unwrap();
}

this gives the curious and (to me) nonsensical error message:

rustc 1.17.0 (56124baa9 2017-04-24)
error[E0275]: overflow evaluating the requirement `_: std::marker::Sized`
  --> <anon>:20:9
   |
20 |     wtr.write::<&[_]>(42).unwrap();
   |         ^^^^^
   |
   = help: consider adding a `#![recursion_limit="20"]` attribute to your crate
   = note: required because of the requirements on the impl of `CanEncode` for `&[_]`
   = note: required because of the requirements on the impl of `CanEncode` for `&[[_]]`
   = note: required because of the requirements on the impl of `CanEncode` for `&[[[_]]]`
   = note: required because of the requirements on the impl of `CanEncode` for `&[[[[_]]]]`
   = note: required because of the requirements on the impl of `CanEncode` for `&[[[[[_]]]]]`
   = note: required because of the requirements on the impl of `CanEncode` for `&[[[[[[_]]]]]]`
   = note: required because of the requirements on the impl of `CanEncode` for `&[[[[[[[_]]]]]]]`
   = note: required because of the requirements on the impl of `CanEncode` for `&[[[[[[[[_]]]]]]]]`
   = note: required because of the requirements on the impl of `CanEncode` for `&[[[[[[[[[_]]]]]]]]]`
   = note: required because of the requirements on the impl of `CanEncode` for `&[[[[[[[[[[_]]]]]]]]]]`

error: aborting due to previous error

Compilation failed.

It's not very clear what's going on here. I have absolutely no idea why the compiler is checking &[[[_]]] and so forth, and I have absolutely no idea why it's checking Sized for these, and why it can't figure out it's never going to work.

All in all, it's really confusing, and it smells a lot like a bug, to me.

@Mark-Simulacrum Mark-Simulacrum added the T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. label Jun 22, 2017
@Mark-Simulacrum Mark-Simulacrum added the C-bug Category: This is a bug. label Jul 27, 2017
@0e4ef622
Copy link
Contributor

Is there any way to fix this, and if not, will it be fixed when chalk lands?

@zhaofengli
Copy link

The plot thickens...

use std::io::{Read, Write};
use std::fs::File;
use std::path::Path;

// Comment this out... and everything will work fine
use thisdoesntexistyolo::haha;

struct Something<T: Read + Write> {
    thing: T,
}

impl<'a, T: 'a + Read + Write> Something<T>
    where &'a T: Read
{
    fn new(thing: T) -> Something<T> {
        Something { thing }
    }
}

fn main() {
    let file = File::open(Path::new("doesntmatter.txt")).unwrap();
    let mut st: Something<File> = Something::new(file);
}
error[E0275]: overflow evaluating the requirement `_: std::io::Read`
  --> src/main.rs:22:35
   |
22 |     let mut st: Something<File> = Something::new(file);
   |                                   ^^^^^^^^^^^^^^
   |
   = help: consider adding a `#![recursion_limit="128"]` attribute to your crate
   = note: required because of the requirements on the impl of `std::io::Read` for `&tar::archive::ArchiveInner<_>`
   = note: required because of the requirements on the impl of `std::io::Read` for `&tokio_reactor::poll_evented::PollEvented<tar::archive::ArchiveInner<_>>`
   = note: required because of the requirements on the impl of `std::io::Read` for `&tokio_reactor::poll_evented::PollEvented<tokio_reactor::poll_evented::PollEvented<tar::archive::ArchiveInner<_>>>`
   = note: required because of the requirements on the impl of `std::io::Read` for `&tokio_reactor::poll_evented::PollEvented<tokio_reactor::poll_evented::PollEvented<tokio_reactor::poll_evented::PollEvented<tar::archive::ArchiveInner<_>>>>`
   = note: required because of the requirements on the impl of `std::io::Read` for `&tokio_reactor::poll_evented::PollEvented<tokio_reactor::poll_evented::PollEvented<tokio_reactor::poll_evented::PollEvented<tokio_reactor::poll_evented::PollEvented<tar::archive::ArchiveInner<_>>>>>`

@hcpl
Copy link

hcpl commented Mar 21, 2019

Minimized test case from #39959 (comment) (also changed to Vec<T> because it's Sized but the error overflows evaluating _: Sized requirement here too):

trait Trait {}
impl<'a, T> Trait for &'a Vec<T> where &'a T: Trait {}

fn call<E: Trait>() {}
    
fn foo() {
    call::<&Vec<_>>();
}

Reproducible on every stable Rust back to 1.0, beta and nightly.

Playground: https://play.rust-lang.org/?version=stable&mode=debug&edition=2018&gist=7ffb08380a25020785bf958a3e600687.

@atorstling
Copy link

atorstling commented May 23, 2019

Same error with a struct instead of Vec. I couldn't repro with any other trait than Sized, external or not.

struct Struct<T> where T: Sized {
  t: T
}

trait Trait {}
impl<'a, T> Trait for &'a Struct<T> where &'a T: Trait {}

fn call<E: Trait>() {}
    
fn foo() {
    call::<&Struct<_>>();
}

Playground

teddywing added a commit to teddywing/git-suggestion that referenced this issue Aug 5, 2020
We can't read from the original file, because we want to be able to use
that as the writer in `apply()`.

Previously, this would result in the original file simply being
truncated, as we weren't reading from the correct file.

To fix this, we need to give `apply_to()` both a reader and a writer.
Now, in `apply()`, we can pass it the temporary file to read, and the
original to write to.

Used a `Path` as an input to `apply_to()` instead of a `Read`er because
I got an error that didn't really make sense to me when I did so:

    error[E0275]: overflow evaluating the requirement `&tokio_reactor::poll_evented::PollEvented<_>: std::io::Read`
      |
      = help: consider adding a `#![recursion_limit="256"]` attribute to your crate (`git_suggested_patch`)
      = note: required because of the requirements on the impl of `std::io::Read` for `&tokio_reactor::poll_evented::PollEvented<tokio_reactor::poll_evented::PollEvented<_>>`
      = note: required because of the requirements on the impl of `std::io::Read` for `&tokio_reactor::poll_evented::PollEvented<tokio_reactor::poll_evented::PollEvented<tokio_reactor::poll_evented::PollEvented<_>>>`

A search for the error message turned up a few active issues:

- rust-lang/rust#57854
- rust-lang/rust#62755
- rust-lang/rust#39959

The above issues indicate that this could come from having a variable
with an inferred type. However, for the moment the issue isn't resolved,
and the error message doesn't indicate where the problem is actually
coming from. As I was unable to track down the source of the problem, I
decided not to bother using a `Read` argument.
@thanatos
Copy link
Contributor

I think I've found an even nastier reproduction of this. Not only do I get the same (long) error output, but mine didn't even reference a file, or a line… Just the error message, number, and the recursion. That is,

error[E0275]: overflow evaluating the requirement `std::io::Cursor<&mut Vec<u8>>: std::io::Write`
  |
  = help: consider adding a `#![recursion_limit="256"]` attribute to your crate (`foobar`)
  = note: required because of the requirements on the impl of `std::io::Write` for `&mut std::io::Cursor<&mut Vec<u8>>`
  = note: required because of the requirements on the impl of `std::io::Write` for `&mut &mut std::io::Cursor<&mut Vec<u8>>`
(and so on)

error: aborting due to previous error

Rust Playground Example

In my example, there is an error in the code: Tag::write calls XmlItem::write with a &mut W, which becomes W in XmlItem. XmlItem then recurses back to Tag with a &mut W, or really, a &mut &mut W from the original W. And so on, ad infinitum; the template can't be instantiated b/c it would require infinite instantiation. The diagnostic isn't helpful, however.

Stable, 1.48.0, and nightly 2020-12-03, though nightly is kind enough to elide some of the redundant impls. (But still fails to identify a line/file.)

@estebank
Copy link
Contributor

estebank commented Feb 20, 2021

Triage: almost no change. The requirements list now hides the intermediary steps if they repeat, so at least now the output is less verbose.

The last case still doesn't have a span.

@lemmih
Copy link

lemmih commented May 16, 2021

I'm writing a numerical crate and am encountering this bug a lot. So far, I've been able to get around it by cloning my values which reduces the complexity of my trait constraints but I can never tell what triggers the bug.

Here's a minimal example: https://play.rust-lang.org/?version=stable&mode=debug&edition=2018&gist=88f2fbd8464ede697605101f29dbcda0
Code is also here: https://gist.github.com/88f2fbd8464ede697605101f29dbcda0

@e2-71828
Copy link

Another instance of this showed up on URLO with a playground link that produces the error.

I was able to find a workaround for this case by adding a bound type variable. I have reproduced the differing sections below.

Compile Error:

impl<X, Xs> Foo for (Cons<X, Xs>, ())
where
    (Xs, ()): Foo,
   <(Xs, ()) as Foo>::X: Any,
{
    type X = Tuple;
}

Compiles Successfully:

impl<X, Xs, X2> Foo for (Cons<X, Xs>, ())
where
    (Xs, ()): Foo<X=X2>,
    X2: Any,
{
    type X = Tuple;
}

@RamiHg
Copy link

RamiHg commented Jul 27, 2021

Here's another tiny test-case by @lemmih that we ran into when using the ordered_float crate: reem/rust-ordered-float#91 (comment)

@estebank
Copy link
Contributor

estebank commented Aug 4, 2021

Triage:

Current output for original report:

error[E0275]: overflow evaluating the requirement `Ser<'_, Option<_>>: Serialize`
  --> src/main.rs:18:5
   |
18 |     Ser::new(value);
   |     ^^^^^^^^
   |
   = help: consider adding a `#![recursion_limit="10"]` attribute to your crate (`playground`)
note: required because of the requirements on the impl of `Serialize` for `Ser<'_, Option<Option<_>>>`
  --> src/main.rs:15:13
   |
15 | impl<'a, T> Serialize for Ser<'a, Option<T>> where Ser<'a, T>: Serialize {}
   |             ^^^^^^^^^     ^^^^^^^^^^^^^^^^^^
   = note: 4 redundant requirements hidden
   = note: required because of the requirements on the impl of `Serialize` for `Ser<Option<Option<Option<Option<Option<Option<_>>>>>>>`

For the third report:

error[E0432]: unresolved import `thisdoesntexistyolo`
 --> src/main.rs:8:5
  |
8 | use thisdoesntexistyolo::haha;
  |     ^^^^^^^^^^^^^^^^^^^ use of undeclared crate or module `thisdoesntexistyolo`

Fourth report:

error[E0275]: overflow evaluating the requirement `_: Sized`
 --> src/lib.rs:7:5
  |
4 | fn call<E: Trait>() {}
  |            ----- required by this bound in `call`
...
7 |     call::<&Vec<_>>();
  |     ^^^^^^^^^^^^^^^
  |
  = help: consider adding a `#![recursion_limit="256"]` attribute to your crate (`playground`)
note: required because of the requirements on the impl of `Trait` for `&Vec<_>`
 --> src/lib.rs:2:13
  |
2 | impl<'a, T> Trait for &'a Vec<T> where &'a T: Trait {}
  |             ^^^^^     ^^^^^^^^^^
  = note: 128 redundant requirements hidden
  = note: required because of the requirements on the impl of `Trait` for `&Vec<Vec<Vec<Vec<Vec<Vec<Vec<Vec<Vec<Vec<Vec<Vec<Vec<Vec<Vec<Vec<Vec<Vec<Vec<Vec<Vec<Vec<Vec<Vec<Vec<Vec<Vec<Vec<Vec<Vec<Vec<Vec<Vec<Vec<Vec<Vec<Vec<Vec<Vec<Vec<Vec<Vec<Vec<Vec<Vec<Vec<Vec<Vec<Vec<Vec<Vec<Vec<Vec<Vec<Vec<Vec<Vec<Vec<Vec<Vec<Vec<Vec<Vec<Vec<Vec<Vec<Vec<Vec<Vec<Vec<Vec<Vec<Vec<Vec<Vec<Vec<Vec<Vec<Vec<Vec<Vec<Vec<Vec<Vec<Vec<Vec<Vec<Vec<Vec<Vec<Vec<Vec<Vec<Vec<Vec<Vec<Vec<Vec<Vec<Vec<Vec<Vec<Vec<Vec<Vec<Vec<Vec<Vec<Vec<Vec<Vec<Vec<Vec<Vec<Vec<Vec<Vec<Vec<Vec<Vec<Vec<Vec<Vec<Vec<Vec<Vec<Vec<Vec<Vec<_>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>`

For the second report:

error[E0275]: overflow evaluating the requirement `_: Sized`
  --> src/main.rs:20:9
   |
20 |     wtr.write::<&[_]>(42).unwrap();
   |         ^^^^^
   |
   = help: consider adding a `#![recursion_limit="20"]` attribute to your crate (`playground`)
note: required because of the requirements on the impl of `CanEncode` for `&[_]`
  --> src/main.rs:12:13
   |
12 | impl<'a, T> CanEncode for &'a [T] where
   |             ^^^^^^^^^     ^^^^^^^
   = note: 10 redundant requirements hidden
   = note: required because of the requirements on the impl of `CanEncode` for `&[[[[[[[[[[[_]]]]]]]]]]]`

Fifth report:

error[E0275]: overflow evaluating the requirement `_: Sized`
  --> src/lib.rs:11:5
   |
8  | fn call<E: Trait>() {}
   |            ----- required by this bound in `call`
...
11 |     call::<&Struct<_>>();
   |     ^^^^^^^^^^^^^^^^^^
   |
   = help: consider adding a `#![recursion_limit="256"]` attribute to your crate (`playground`)
note: required because of the requirements on the impl of `Trait` for `&Struct<_>`
  --> src/lib.rs:6:13
   |
6  | impl<'a, T> Trait for &'a Struct<T> where &'a T: Trait {}
   |             ^^^^^     ^^^^^^^^^^^^^
   = note: 128 redundant requirements hidden
   = note: required because of the requirements on the impl of `Trait` for `&Struct<Struct<Struct<Struct<Struct<Struct<Struct<Struct<Struct<Struct<Struct<Struct<Struct<Struct<Struct<Struct<Struct<Struct<Struct<Struct<Struct<Struct<Struct<Struct<Struct<Struct<Struct<Struct<Struct<Struct<Struct<Struct<Struct<Struct<Struct<Struct<Struct<Struct<Struct<Struct<Struct<Struct<Struct<Struct<Struct<Struct<Struct<Struct<Struct<Struct<Struct<Struct<Struct<Struct<Struct<Struct<Struct<Struct<Struct<Struct<Struct<Struct<Struct<Struct<Struct<Struct<Struct<Struct<Struct<Struct<Struct<Struct<Struct<Struct<Struct<Struct<Struct<Struct<Struct<Struct<Struct<Struct<Struct<Struct<Struct<Struct<Struct<Struct<Struct<Struct<Struct<Struct<Struct<Struct<Struct<Struct<Struct<Struct<Struct<Struct<Struct<Struct<Struct<Struct<Struct<Struct<Struct<Struct<Struct<Struct<Struct<Struct<Struct<Struct<Struct<Struct<Struct<Struct<Struct<Struct<Struct<Struct<Struct<Struct<Struct<Struct<Struct<Struct<Struct<_>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>`

The case that loses spans now looks like this, still without a span:

error[E0275]: overflow evaluating the requirement `&mut Vec<u8>: std::io::Write`
  |
  = help: consider adding a `#![recursion_limit="256"]` attribute to your crate (`playground`)
  = note: required because of the requirements on the impl of `std::io::Write` for `&mut &mut Vec<u8>`
  = note: 128 redundant requirements hidden
  = note: required because of the requirements on the impl of `std::io::Write` for `&mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut Vec<u8>`

The other example linked:

error[E0275]: overflow evaluating the requirement `&BTreeSet<_>: Sub<&BTreeSet<_>>`
  --> src/main.rs:28:30
   |
17 | fn test<T, const N: usize>(p: &Vector<T, N>) -> Vector<T, N>
   |    ---- required by a bound in this
18 | where
19 |     for<'a> &'a T: Sub<&'a T, Output = T>,
   |                    ---------------------- required by this bound in `test`
...
28 |     println!("Output: {:?}", test(&a)); // This fails
   |                              ^^^^
   |
   = help: consider adding a `#![recursion_limit="256"]` attribute to your crate (`playground`)
note: required because of the requirements on the impl of `Sub<&Vector<BTreeSet<_>, {_: usize}>>` for `&Vector<BTreeSet<_>, {_: usize}>`
  --> src/main.rs:6:33
   |
6  | impl<'a, 'b, T, const N: usize> Sub<&'a Vector<T, N>> for &'b Vector<T, N>
   |                                 ^^^^^^^^^^^^^^^^^^^^^     ^^^^^^^^^^^^^^^^
   = note: 127 redundant requirements hidden
   = note: required because of the requirements on the impl of `for<'a> Sub` for `&'a Vector<Vector<Vector<Vector<Vector<Vector<Vector<Vector<Vector<Vector<Vector<Vector<Vector<Vector<Vector<Vector<Vector<Vector<Vector<Vector<Vector<Vector<Vector<Vector<Vector<Vector<Vector<Vector<Vector<Vector<Vector<Vector<Vector<Vector<Vector<Vector<Vector<Vector<Vector<Vector<Vector<Vector<Vector<Vector<Vector<Vector<Vector<Vector<Vector<Vector<Vector<Vector<Vector<Vector<Vector<Vector<Vector<Vector<Vector<Vector<Vector<Vector<Vector<Vector<Vector<Vector<Vector<Vector<Vector<Vector<Vector<Vector<Vector<Vector<Vector<Vector<Vector<Vector<Vector<Vector<Vector<Vector<Vector<Vector<Vector<Vector<Vector<Vector<Vector<Vector<Vector<Vector<Vector<Vector<Vector<Vector<Vector<Vector<Vector<Vector<Vector<Vector<Vector<Vector<Vector<Vector<Vector<Vector<Vector<Vector<Vector<Vector<Vector<Vector<Vector<Vector<Vector<Vector<Vector<Vector<Vector<Vector<Vector<Vector<Vector<Vector<Vector<Vector<BTreeSet<_>, {_: usize}>, {_: usize}>, {_: usize}>, {_: usize}>, {_: usize}>, {_: usize}>, {_: usize}>, {_: usize}>, {_: usize}>, {_: usize}>, {_: usize}>, {_: usize}>, {_: usize}>, {_: usize}>, {_: usize}>, {_: usize}>, {_: usize}>, {_: usize}>, {_: usize}>, {_: usize}>, {_: usize}>, {_: usize}>, {_: usize}>, {_: usize}>, {_: usize}>, {_: usize}>, {_: usize}>, {_: usize}>, {_: usize}>, {_: usize}>, {_: usize}>, {_: usize}>, {_: usize}>, {_: usize}>, {_: usize}>, {_: usize}>, {_: usize}>, {_: usize}>, {_: usize}>, {_: usize}>, {_: usize}>, {_: usize}>, {_: usize}>, {_: usize}>, {_: usize}>, {_: usize}>, {_: usize}>, {_: usize}>, {_: usize}>, {_: usize}>, {_: usize}>, {_: usize}>, {_: usize}>, {_: usize}>, {_: usize}>, {_: usize}>, {_: usize}>, {_: usize}>, {_: usize}>, {_: usize}>, {_: usize}>, {_: usize}>, {_: usize}>, {_: usize}>, {_: usize}>, {_: usize}>, {_: usize}>, {_: usize}>, {_: usize}>, {_: usize}>, {_: usize}>, {_: usize}>, {_: usize}>, {_: usize}>, {_: usize}>, {_: usize}>, {_: usize}>, {_: usize}>, {_: usize}>, {_: usize}>, {_: usize}>, {_: usize}>, {_: usize}>, {_: usize}>, {_: usize}>, {_: usize}>, {_: usize}>, {_: usize}>, {_: usize}>, {_: usize}>, {_: usize}>, {_: usize}>, {_: usize}>, {_: usize}>, {_: usize}>, {_: usize}>, {_: usize}>, {_: usize}>, {_: usize}>, {_: usize}>, {_: usize}>, {_: usize}>, {_: usize}>, {_: usize}>, {_: usize}>, {_: usize}>, {_: usize}>, {_: usize}>, {_: usize}>, {_: usize}>, {_: usize}>, {_: usize}>, {_: usize}>, {_: usize}>, {_: usize}>, {_: usize}>, {_: usize}>, {_: usize}>, {_: usize}>, {_: usize}>, {_: usize}>, {_: usize}>, {_: usize}>, {_: usize}>, {_: usize}>, {_: usize}>, {_: usize}>, {_: usize}>`

And the output for the last two comments, which are using recent compilers so their output hasn't changed:

error[E0275]: overflow evaluating the requirement `(Cons<_, _>, ()): Foo`
  |
  = help: consider adding a `#![recursion_limit="256"]` attribute to your crate (`playground`)
  = note: required because of the requirements on the impl of `Foo` for `(Cons<_, Cons<_, _>>, ())`
  = note: 127 redundant requirements hidden
  = note: required because of the requirements on the impl of `Foo` for `(Cons<_, Cons<_, Cons<_, Cons<_, Cons<_, Cons<_, Cons<_, Cons<_, Cons<_, Cons<_, Cons<_, Cons<_, Cons<_, Cons<_, Cons<_, Cons<_, Cons<_, Cons<_, Cons<_, Cons<_, Cons<_, Cons<_, Cons<_, Cons<_, Cons<_, Cons<_, Cons<_, Cons<_, Cons<_, Cons<_, Cons<_, Cons<_, Cons<_, Cons<_, Cons<_, Cons<_, Cons<_, Cons<_, Cons<_, Cons<_, Cons<_, Cons<_, Cons<_, Cons<_, Cons<_, Cons<_, Cons<_, Cons<_, Cons<_, Cons<_, Cons<_, Cons<_, Cons<_, Cons<_, Cons<_, Cons<_, Cons<_, Cons<_, Cons<_, Cons<_, Cons<_, Cons<_, Cons<_, Cons<_, Cons<_, Cons<_, Cons<_, Cons<_, Cons<_, Cons<_, Cons<_, Cons<_, Cons<_, Cons<_, Cons<_, Cons<_, Cons<_, Cons<_, Cons<_, Cons<_, Cons<_, Cons<_, Cons<_, Cons<_, Cons<_, Cons<_, Cons<_, Cons<_, Cons<_, Cons<_, Cons<_, Cons<_, Cons<_, Cons<_, Cons<_, Cons<_, Cons<_, Cons<_, Cons<_, Cons<_, Cons<_, Cons<_, Cons<_, Cons<_, Cons<_, Cons<_, Cons<_, Cons<_, Cons<_, Cons<_, Cons<_, Cons<_, Cons<_, Cons<_, Cons<_, Cons<_, Cons<_, Cons<_, Cons<_, Cons<_, Cons<_, Cons<_, Cons<_, Cons<_, Cons<_, Cons<_, Cons<_, Cons<_, Cons<_, _>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>, ())`

error[E0275]: overflow evaluating the requirement `&HashSet<_, _>: Sub`
  --> src/lib.rs:11:22
   |
3  | fn test<T>(p: T) -> T
   |    ---- required by a bound in this
4  | where
5  |     for<'a> &'a T: std::ops::Sub<&'a T, Output = T>,
   |                    -------------------------------- required by this bound in `test`
...
11 |     println!("{:?}", test(0.0_f64));
   |                      ^^^^
   |
   = help: consider adding a `#![recursion_limit="256"]` attribute to your crate (`error_case`)
   = note: required because of the requirements on the impl of `Sub` for `&OrderedFloat<HashSet<_, _>>`
   = note: 127 redundant requirements hidden
   = note: required because of the requirements on the impl of `for<'a> Sub` for `&'a OrderedFloat<OrderedFloat<OrderedFloat<OrderedFloat<OrderedFloat<OrderedFloat<OrderedFloat<OrderedFloat<OrderedFloat<OrderedFloat<OrderedFloat<OrderedFloat<OrderedFloat<OrderedFloat<OrderedFloat<OrderedFloat<OrderedFloat<OrderedFloat<OrderedFloat<OrderedFloat<OrderedFloat<OrderedFloat<OrderedFloat<OrderedFloat<OrderedFloat<OrderedFloat<OrderedFloat<OrderedFloat<OrderedFloat<OrderedFloat<OrderedFloat<OrderedFloat<OrderedFloat<OrderedFloat<OrderedFloat<OrderedFloat<OrderedFloat<OrderedFloat<OrderedFloat<OrderedFloat<OrderedFloat<OrderedFloat<OrderedFloat<OrderedFloat<OrderedFloat<OrderedFloat<OrderedFloat<OrderedFloat<OrderedFloat<OrderedFloat<OrderedFloat<OrderedFloat<OrderedFloat<OrderedFloat<OrderedFloat<OrderedFloat<OrderedFloat<OrderedFloat<OrderedFloat<OrderedFloat<OrderedFloat<OrderedFloat<OrderedFloat<OrderedFloat<OrderedFloat<OrderedFloat<OrderedFloat<OrderedFloat<OrderedFloat<OrderedFloat<OrderedFloat<OrderedFloat<OrderedFloat<OrderedFloat<OrderedFloat<OrderedFloat<OrderedFloat<OrderedFloat<OrderedFloat<OrderedFloat<OrderedFloat<OrderedFloat<OrderedFloat<OrderedFloat<OrderedFloat<OrderedFloat<OrderedFloat<OrderedFloat<OrderedFloat<OrderedFloat<OrderedFloat<OrderedFloat<OrderedFloat<OrderedFloat<OrderedFloat<OrderedFloat<OrderedFloat<OrderedFloat<OrderedFloat<OrderedFloat<OrderedFloat<OrderedFloat<OrderedFloat<OrderedFloat<OrderedFloat<OrderedFloat<OrderedFloat<OrderedFloat<OrderedFloat<OrderedFloat<OrderedFloat<OrderedFloat<OrderedFloat<OrderedFloat<OrderedFloat<OrderedFloat<OrderedFloat<OrderedFloat<OrderedFloat<OrderedFloat<OrderedFloat<OrderedFloat<OrderedFloat<OrderedFloat<OrderedFloat<OrderedFloat<OrderedFloat<OrderedFloat<HashSet<_, _>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>`

@estebank estebank added the A-diagnostics Area: Messages for errors, warnings, and lints label Aug 4, 2021
Iron-E added a commit to Iron-E/winvoice-cli that referenced this issue Jan 7, 2022
Further progress on this application is blocked by rust-lang/rust#39959
@cmpute
Copy link

cmpute commented Apr 20, 2022

Another case here on URLO

@joonazan
Copy link

joonazan commented Nov 8, 2022

There are multiple bugs here and the most minimal example does not show the worst bug.

struct Struct<T>(T);

trait Trait {}
impl<T> Trait for Struct<T> where T: Trait {}
impl Trait for u8 {}

fn call<E: Trait>() {}
    
fn foo() {
    call::<Struct<_>>();
}

The above code must fail with "type annotations needed" because both Struct<Struct<u8>> and Struct<u8> are valid solutions. With references it should fail with that message as well but instead it recurses.

But the actually bad bug, which I'm fairly sure exists is that code that should compile does not. @e2-71828 posted an example of that but that one compiles in the current playground. I'm pretty sure that I've encountered it recently but unfortunately I didn't save the problematic version of the code anywhere.

If you find this issue while debugging that, please post the code.

@insou22
Copy link

insou22 commented Nov 15, 2022

@e2-71828 posted an example of that but that one compiles in the current playground.

I was interested where that issue got fixed (I originally authored that example) so I spent some time bisecting the fix today.

bors 4a99c5f is the first commit that builds my example successfully, which is an auto-merge of #97345
That PR looks (to me at least) like it's simply targeting performance improvement and seems to have unintentionally fixed the bug... I'm hoping the implementation details of that PR might help suggest where the root cause of these type inference loops lie.

@e2-71828
Copy link

The nature of the speedup from that PR is seemingly some kind of early pruning inside the trait solver. It’s possible that the logic used there consistently prunes away the problematic branches before they get a chance to infinitely recurse.

@quietfanatic
Copy link

quietfanatic commented Nov 24, 2022

Hello, I have another repro to add to the pile. https://play.rust-lang.org/?version=nightly&mode=debug&edition=2021&gist=3d0813888dd49475147c9cfbed636797 Looks like it's okay if the trait recurses immediately (taking an i32 / Vec<T>), but adding one layer of indirection to the types (taking an &i32 / &Vec<T>) makes it evaluate the recursion forever.

@joonazan
Copy link

I have figured out the root cause!

evaluate_stack has code that is supposed to prevent exactly this case.

But there is a bug in rustc_middle::ty::_match::Match. It is supposed to check if two types can be unified. For example FreshTy(9) as std::marker::Sized and Union<FreshTy(1), FreshTy(2)> as Trait can be unified but Match thinks this is not the case because the relevant Relate implementation thinks the trait bounds have to match.

I am not yet sure what the fix is because while this is incorrect for Match I haven't looked at other things that use Relate.

@estebank
Copy link
Contributor

The original case now ICEs :(

@albertlarsan68
Copy link
Member

Doesn't look like it ICEs with the latest nightly (2023-07-13)

@estebank
Copy link
Contributor

Current output:

error[E0275]: overflow evaluating the requirement `Ser<'_, Option<_>>: Serialize`
  --> src/main.rs:18:10
   |
18 |     Ser::new(value);
   |          ^^^
   |
   = help: consider increasing the recursion limit by adding a `#![recursion_limit = "10"]` attribute to your crate (`playground`)
note: required for `Ser<'_, Option<Option<_>>>` to implement `Serialize`
  --> src/main.rs:15:13
   |
15 | impl<'a, T> Serialize for Ser<'a, Option<T>> where Ser<'a, T>: Serialize {}
   |             ^^^^^^^^^     ^^^^^^^^^^^^^^^^^^                   --------- unsatisfied trait bound introduced here
   = note: 3 redundant requirements hidden
   = note: required for `Ser<'_, Option<Option<Option<Option<Option<_>>>>>>` to implement `Serialize`
note: required by a bound in `Ser<'a, T>`
  --> src/main.rs:9:42
   |
9  | impl<'a, T> Ser<'a, T> where Ser<'a, T>: Serialize {
   |                                          ^^^^^^^^^ required by this bound in `Ser<'a, T>`

@Enselic
Copy link
Member

Enselic commented Jul 26, 2023

I don't see an ICE either any longer

@rustbot label -I-ICE

@rustbot rustbot removed the I-ICE Issue: The compiler panicked, giving an Internal Compilation Error (ICE) ❄️ label Jul 26, 2023
@jieyouxu
Copy link
Member

The test case in the description doesn't seem to overflow with -Znext-solver=globally (but still overflows without)

[13:57] Joe-Mac.local:rust (master %) | rustc +nightly -Znext-solver=globally test.rs                                                                                                                                                                                                                               (base)
warning: trait `Serialize` is never used
 --> test.rs:5:7
  |
5 | trait Serialize {}
  |       ^^^^^^^^^
  |
  = note: `#[warn(dead_code)]` on by default

warning: struct `Ser` is never constructed
 --> test.rs:7:8
  |
7 | struct Ser<'a, T: 'a>(&'a T);
  |        ^^^

warning: associated function `new` is never used
  --> test.rs:10:12
   |
9  | impl<'a, T> Ser<'a, T> where Ser<'a, T>: Serialize {
   | -------------------------------------------------- associated function in this implementation
10 |     pub fn new(value: &'a T) -> Self {
   |            ^^^

warning: function `serialize` is never used
  --> test.rs:17:4
   |
17 | fn serialize<'a, T>(value: &'a T) where Ser<'a, T>: Serialize {
   |    ^^^^^^^^^

warning: 4 warnings emitted

@jaw-sh
Copy link

jaw-sh commented May 4, 2024

I have created an interesting problem the compiler cannot resolve a type. I do not know if this is a compiler issue or if I am simply doing something wrong, but the diagnostic information I am given does not really help me understand what the issue. Before I updated my toolchain, it gave me no errors, and in my production code I can actually get the compiler to go into an infinite loop that never completes, but I'm not able to reproduce that.

The below code will work if I simply remove the trait hints on the trait type Ty. With any combination of trait hints, it breaks. All I'd like to do is require certain traits for the trait type.

error[E0275]: overflow evaluating the requirement `<St as Tr>::Ty == _`
trait Tr {
    type Ty where Self::Ty: Clone;
}

#[derive(Debug)]
struct St {
    fi: <Self as Tr>::Ty
}

impl Tr for St {
    type Ty = i64;
}

pub fn main() {
    let inst = St { fi: 42 };
    println!("{:?}, {}", inst, inst.fi + 12);
}

@AustinCase
Copy link

Interesting that we are having this problem but only on subsequent compiles. If we clear the target directory it compiles without fail... make one change and we get the overflow error. Our code example is rather complex with async-graphql wrapping deeply nested objects, but we combed through them ensuring they aren't self referential causing recursion.

@calo-chen
Copy link

calo-chen commented Oct 29, 2024

I have run into error[E0275] as well. If I have:

pub fn foo(it: impl Iterator<Item = i32>, x: i32) {
    if x >= 10 {
        return;
    } else {
        let it_next = it.map(|x| x + 1);
        foo(it_next, x + 1);
    }
}

I'm not sure if this should compile, because it looks like we are creating a infinite type here, but it does compile. However, as soon as I make it instantiate for another iterator type:

pub fn main() {
    foo([1, 2, 3].into_iter(), 0);
}

It throws the said error:

error[E0275]: overflow evaluating the requirement `the constant `3` has type `usize``

Edit: that was on 1.77.2, on 1.82 it now shows this:

error: reached the recursion limit while instantiating `foo::<std::iter::Map<std::iter::Map<std::iter::Map<std::iter::Map<std::iter::Map<..., ...>, ...>, ...>, ...>, ...>>`

Still, without calling it the function compiles, which I find confusing.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-diagnostics Area: Messages for errors, warnings, and lints C-bug Category: This is a bug. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.
Projects
None yet
Development

Successfully merging a pull request may close this issue.