Description
It seems like impl Trait forces its own lifetime bound onto anything that it touches, even if that doesn't make sense.
struct Never<T>(fn() -> T);
impl<T> Iterator for Never<T> {
type Item = T;
fn next(&mut self) -> Option<T> {
None
}
}
fn actual_type<T>(f: fn() -> T) -> Never<T> {
Never(f)
}
fn impl_trait<T>(f: fn() -> T) -> impl Iterator<Item = T> + 'static {
Never(f)
}
Here I create an iterator like type that takes a function that produces T values. The implementation of the iterator doesn't really matter here. If I now create a function constructing that type, returning the actual type lets the borrow checker correctly understand that T doesn't require any lifetimes. However if I return impl Iterator instead, the compiler is apparently seeing that T is part of the impl Trait and therefore forces me to apply the same lifetime as the iterator itself to the elements T, even if that makes no sense. I'm guessing impl Trait is not properly respecting variance.
error[E0310]: the parameter type `T` may not live long enough
--> src/lib.rs:14:35
|
14 | fn impl_trait<T>(f: fn() -> T) -> impl Iterator<Item = T> + 'static {
| - ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ...so that the type `Never<T>` will meet its required lifetime bounds
| |
| help: consider adding an explicit lifetime bound...: `T: 'static`
error: aborting due to previous error
@HeroicKatora mentioned that a similar problem happens with trait objects as well: Playground