rust-lang / rust

Empowering everyone to build reliable and efficient software.
https://www.rust-lang.org
Other
97.59k stars 12.62k forks source link

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

Open SimonSapin opened 7 years ago

SimonSapin commented 7 years ago

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 (536a900c4 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.

chrivers commented 7 years ago

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.

0e4ef622 commented 5 years ago

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

zhaofengli commented 5 years ago

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 commented 5 years ago

Minimized test case from https://github.com/rust-lang/rust/issues/39959#issuecomment-301342230 (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 commented 5 years ago

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

thanatos commented 3 years ago

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 commented 3 years ago

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 commented 3 years ago

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 commented 3 years ago

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 commented 3 years ago

Here's another tiny test-case by @Lemmih that we ran into when using the ordered_float crate: https://github.com/reem/rust-ordered-float/issues/91#issuecomment-865504545

estebank commented 3 years ago

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<_, _>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>`
cmpute commented 2 years ago

Another case here on URLO

joonazan commented 1 year ago

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 commented 1 year ago

@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 4a99c5f5 is the first commit that builds my example successfully, which is an auto-merge of https://github.com/rust-lang/rust/pull/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 commented 1 year ago

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 commented 1 year ago

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 commented 1 year ago

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 commented 1 year ago

The original case now ICEs :(

albertlarsan68 commented 1 year ago

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

estebank commented 1 year ago

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 commented 1 year ago

I don't see an ICE either any longer

@rustbot label -I-ICE

jieyouxu commented 7 months ago

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 commented 5 months ago

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);
}