Hi, I've noticed what seems to be an error in rustc. Here's a minimal code example:
trait Foo {
fn iter<'a>(&self, v: &'a Vec<usize>) -> impl Iterator<Item = usize> + 'a;
}
struct Bar;
impl Foo for Bar {
fn iter<'a>(&self, v: &'a Vec<usize>) -> impl Iterator<Item = usize> + 'a {
v.iter().copied()
}
}
Basically, I have a trait Foo
which has a method iter
that produces an iterator whose lifetime is bound to the argument v
, but not to self
. I implement this on a struct Bar
. However, when I end up using that method, e.g.:
impl Bar {
fn skip_first<'a>(&self, v: &'a Vec<usize>) -> impl Iterator<Item = usize> + 'a {
self.iter(v).skip(1)
}
}
I get a lifetime error, saying impl Iterator<Item = usize> + 'a
implicitly captures &self
's lifetime:
error[E0700]: hidden type for `impl Iterator<Item = usize> + 'a` captures lifetime that does not appear in bounds
--> varbade/src/lib.rs:144:13
|
143 | fn skip_first<'a>(&self, v: &'a Vec<usize>) -> impl Iterator<Item = usize> + 'a {
| ----- -------------------------------- opaque type defined here
| |
| hidden type `Skip<impl Iterator<Item = usize> + 'a>` captures the anonymous lifetime defined here
144 | self.iter(v).skip(1)
| ^^^^^^^^^^^^^^^^^^^^
|
help: to declare that `impl Iterator<Item = usize> + 'a` captures `'_`, you can add an explicit `'_` lifetime bound
|
143 | fn skip_first<'a>(&self, v: &'a Vec<usize>) -> impl Iterator<Item = usize> + 'a + '_ {
| ++++
This is not correct, and indeed if I move the implementation of fn iter
outside of the trait and into a regular impl Bar { ... }
, the error disappears.
Is this a limitation of opaque return types in traits? Thanks for your help