Multiple Unrelated Lifetimes in Existential Types
what we don’t allow today but want to:
existential type T<'a, 'b>; // = (&'a (), &'b ())
fn foo<'a, 'b>(x: &'a (), y: &'b ()) -> T<'a, 'b> { (x, y) }

what we can’t allow (matches behavior for types):
existential type T<'a, 'b>; // = (&'a (), &'b ())
fn foo<'a>(x: &'a (), y: &'a ()) -> T<'a, 'a> { (x, y) }
// ^^ this can't be a defining use
// because this could exist: (doesn't use 'b *at all*)
fn bar<'a, 'b>(x: &'a (), y: &'a ()) -> T<'a, 'b> { (x, x) }
// OR this could exist: (*does* use 'b)
fn bar<'a, 'b>(x: &'a (), y: &'a ()) -> T<'a, 'b> { (x, y) }

subtyping makes this even harder
// does this concrete type use `'b` or not?
fn bar<'a, 'b: 'a>(...) -> T<'a, 'b> { (x, y) }

what we want to allow, more depth


existential type T<'a, 'b>; // = (&'a (), &'b ())
fn foo<'a, 'b>(x: &'a (), y: &'b ()) -> T<'a, 'b> { (x, y) }

  • we will create a type variable ?H representing the hidden type
  • (&'0 (), &'1 ())
  • (&'a (), &'b ()) <: (&'0 () ,&'1 ())
  • 'a: '0
  • 'b: '1
  • '0 in { 'a, 'b, 'static } // currently no way to represent this
  • '1 in { 'a, 'b, 'static }

  • as-is:
  • there is a unique sol’n '0 = 'a and '1 = 'b
  • problem:
  • if we had 'a: 'b as a where-clause, there would be no unique solution to this set of constraints
  • 'a == '0, but '1 can be either 'a or 'b

  • to what extent does it matter what we choose?
  • within the module, they care because they have full visibility
  • outside the module, what about auto traits?

struct Foo<'a, 'b> {
  ..
}

impl<'a> Send for Foo<'a, 'a> {}

async fn make_foo(x: &'a u32, y; &'b u32) {
    let x = Foo(x, y);
    await!(some_thing());