Skip to content

Lifetimes get replaced with 'static in Self within (return position) impl Trait. #53613

Closed

Description

@eddyb
#[derive(Copy, Clone)]
struct Invariant<'a>(std::marker::PhantomData<&'a mut &'a ()>);

impl<'a> Invariant<'a> {
    fn lazy_dup(self) -> impl Fn() -> (Invariant<'a>, Self) {
        || (self, self)
    }
}
error[E0308]: mismatched types
 --> src/lib.rs:6:19
  |
6 |         || (self, self)
  |                   ^^^^ lifetime mismatch
  |
  = note: expected type `Invariant<'static>`
             found type `Invariant<'a>`

I didn't write 'static anywhere - it comes from part of the implementation of impl Trait, and Self references lifetimes (from the impl header) "indirectly", hiding them from impl Trait logic.

cc @cramertj @oli-obk @nikomatsakis

Activity

  1. added
    A-impl-traitArea: `impl Trait`. Universally / existentially quantified anonymous types with static dispatch.
    on Aug 22, 2018
  2. added
    C-bugCategory: This is a bug.
    T-compilerRelevant to the compiler team, which will review and decide on the PR/issue.
    on Jun 19, 2019
  3. nikomatsakis commented on Jul 5, 2019

    @nikomatsakis
    Contributor

    There is a variant of this problem that was revealed in #62221. If you write T::Item, and we expand that (in type-checking) to <T as Foo<'a>>::Item, the 'a is overlooked as well (playground):

    pub trait HasItem<'a> {
        type Item;
    }
    
    // Does not compile:
    fn example1<'a, T: HasItem<'a>>(item: T::Item) -> impl IntoIterator<Item = T::Item> {
        Some(item)
    }
    
    // Compiles:
    fn example2<'a, T: HasItem<'a>>(item: T::Item) -> impl IntoIterator<Item = <T as HasItem<'a>>::Item> {
        Some(item)
    }
    
    fn main() { }

    UPDATE: This is #51525

  4. nikomatsakis commented on Jul 9, 2019

    @nikomatsakis
    Contributor

    I left some notes in this Zulip topic that explain one way to fix this problem. The idea is basically to detect Self during lowering and take it into account.

  5. added 2 commits that reference this issue on Sep 28, 2023
  6. Arnavion commented on Aug 8, 2024

    @Arnavion
    Contributor

    Just like #61949 I guess this is also fixed by #115659 ? The test case in the OP compiles fine today, other than needing to add move to the closure to make it move || (self, self)

  7. Dylan-DPC commented on Dec 15, 2024

    @Dylan-DPC
    Member

    Closing this as it's fixed and it compiles to a different error with indication on how to fix it by adding move to the closure.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-impl-traitArea: `impl Trait`. Universally / existentially quantified anonymous types with static dispatch.A-lifetimesArea: Lifetimes / regionsC-bugCategory: This is a bug.T-compilerRelevant to the compiler team, which will review and decide on the PR/issue.

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions