Skip to content

existential impl trait overlooks "hidden" lifetimes from projections #51525

Closed
@nikomatsakis

Description

@nikomatsakis

In this example (play), we currently get an incorrect compilation error:

trait Foo<'a> {
    type Bar;
}

impl<'a> Foo<'a> for u32 {
    type Bar = &'a ();
}

fn baz<'a, T>() -> impl IntoIterator<Item = T::Bar>
where T: Foo<'a> { 
    None
}

fn main() { }

yields

error[E0308]: mismatched types
  --> src/main.rs:11:5
   |
11 |     None
   |     ^^^^ lifetime mismatch
   |
   = note: expected type `Foo<'static>`
              found type `Foo<'a>`

This does not seem correct. =) The problem is that T::Bar (at HIR lowering time) does not mention 'a. So we wind up mapping this -- because of the way the region desugaring works -- to <T as Foo<'static>>::Bar. If you manually write <T as Foo<'a>>::Bar in the original Rust source, the 'a becomes visible and is lowered correctly. In other words, this version compiles:

trait Foo<'a> {
    type Bar;
}

impl<'a> Foo<'a> for u32 {
    type Bar = &'a ();
}

fn baz<'a, T>() -> impl IntoIterator<Item = <T as Foo<'a>>::Bar>
where T: Foo<'a> { 
    None
}

fn main() { }

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.E-needs-testCall for participation: An issue has been fixed and does not reproduce, but no test has been added.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