Misleading compile error

This is a striped down version of an error I recently stumbled into:

struct Foo<T>(T);

impl<'a, T> IntoIterator for &'a Foo<T> where &'a T: IntoIterator {
    type Item = <&'a T as IntoIterator>::Item;
    type IntoIter = <&'a T as IntoIterator>::IntoIter;

    fn into_iter(self) -> Self::IntoIter {
        self.0.into_iter()
    }
}

fn main() {
    for _ in Foo([]) {}
}

(Playground)

Errors:

   Compiling playground v0.0.1 (/playground)
error[E0275]: overflow evaluating the requirement `&_: IntoIterator`
  |
  = help: consider increasing the recursion limit by adding a `#![recursion_limit = "256"]` attribute to your crate (`playground`)
note: required for `&Foo<_>` to implement `IntoIterator`
 --> src/main.rs:3:13
  |
3 | impl<'a, T> IntoIterator for &'a Foo<T> where &'a T: IntoIterator {
  |             ^^^^^^^^^^^^     ^^^^^^^^^^              ------------ unsatisfied trait bound introduced here
  = note: 126 redundant requirements hidden
  = note: required for `&Foo<Foo<Foo<Foo<Foo<Foo<Foo<Foo<Foo<Foo<Foo<Foo<Foo<Foo<Foo<Foo<Foo<Foo<Foo<Foo<Foo<...>>>>>>>>>>>>>>>>>>>>>` to implement `IntoIterator`
  = note: the full name for the type has been written to '/playground/target/debug/deps/playground-cd56f89b016b72c1.long-type-5180598437654316909.txt'
  = note: consider using `--verbose` to print the full type name to the console

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

I would have wished to be informed about Iterator not being implemented for Foo itself. Nevertheless, providing IntoIter for Foo and trying to iterate &Foo([]) instead seems to behave as expected.

This might be a bug and I was wondering if and where I should report it.

Any time rustc (or the standard library) has a bug, the place to report it is https://github.com/rust-lang/rust/issues. A good place to start is to search for a key phrase from the error, such as the error code (E0275) when there is one, and see whether one of the existing issues describes your situation.

In this case, your code seems to have a similar structure to It's possible to impose generic bounds that later make type inference recurse infinitely · Issue #48767 · rust-lang/rust · GitHub, but it might be different enough to still be worth logging — I'm not sure.

A lot of these issues are tagged "fixed-by-next-solver" which means that the upcoming (but still not ready to use) version of the trait solver can handle them. This seems to be true for your example code:

error[E0277]: `Foo<[_; 0]>` is not an iterator
  --> src/lib.rs:16:14
   |
16 |     for _ in Foo([]) {}
   |              ^^^^^^^ `Foo<[_; 0]>` is not an iterator
   |
   = help: the trait `Iterator` is not implemented for `Foo<[_; 0]>`
   = help: the trait `IntoIterator` is implemented for `&Foo<T>`
   = note: required for `Foo<[_; 0]>` to implement `IntoIterator`

You can test if this is true of your original code by running:

RUSTFLAGS=-Znext-solver cargo +nightly build

That might produce unrelated errors, but if it succeeds, that is evidence (but not certainty) that there is no need to report this bug.

3 Likes