Skip to content

Impl Trait forces unnecessary lifetime bounds #80083

Open
@CryZe

Description

@CryZe

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

Playground

@HeroicKatora mentioned that a similar problem happens with trait objects as well: Playground

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-impl-traitArea: `impl Trait`. Universally / existentially quantified anonymous types with static dispatch.A-lifetimesArea: Lifetimes / regionsA-varianceArea: Variance (https://doc.rust-lang.org/nomicon/subtyping.html)

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions