Description
This is a tracking issue for existential lifetimes.
Description:
Allow hiding a type (via impl Trait
) that is invariant over some lifetime without explicitly mentioning the invariant lifetime.
Consider the following:
impl Trait<'b> for Cell<&'a u32> { }
fn foo(x: Cell<&'x u32>) -> impl Trait<'y> where 'x: 'y { x }
There is no reason this cannot be legal, although it is not permitted at present. We would want to translate the function signature internally into something like:
fn foo(x: Cell<&'x u32>) -> impl exists<'x: 'y> Trait<'y> where 'x: 'y { x }
Although it be noted there is no need for user-facing exists<...>
syntax; only HIR and ty
representations probably. The concrete type corresponding to impl exists<'x: 'y> Trait<'y>
can this be soundly checked by the compiler at use site.
Note, we still need to be careful to ban situations like those mentioned by @matthewjasper in #59402. By actually embedding the existential lifetime in the type rather than simply doing a check when resolving the opaque type, we should be able to resolve these issues, however. One can view this solution as a "compiler-internalised" version of the Captures
marker trait solution, in some sense.
Steps:
- Decide on exact semantics of existential lifetimes. Perhaps @nikomatsakis can briefly write up his thoughts here.
- Implement the RFC (cc previous attempts Allow hidden lifetimes in
impl Trait
#57870 and Allow hidden lifetimes inimpl Trait
, take 2 #59402, @nikomatsakis for mentoring instructions?) - Stabilization PR (see instructions on rustc-guide)