Associated type is bound to `'static`, but compiler disagrees

I would expect the following code to compile. Instead, I get errors about foo not living long enough (even though Foo is bound to 'static), and about it being mutably borrowed in more than once place.

Is this a bug in the compiler or is there something I don't understand? If the former, has an issue
already been opened about it?

trait Foo: 'static {
    type Bar<'a>: Bar<Baz: 'static>;

    fn bar(&mut self) -> Self::Bar<'_>;

    fn handle_static<T: 'static>(&mut self, t: T);
}

trait Bar {
    // Compiles if this is bound to `'static`.
    //
    // But the code above already bounds it to `'static`,
    // so why does it have to be bound twice?.
    type Baz /* : 'static */;

    fn into_baz(self) -> Self::Baz;
}

fn handle_foo<T: Foo>(mut foo: T) {
    let bar = foo.bar();
    let baz = bar.into_baz();
    foo.handle_static(baz);
}

Playground.

Actually I was confused by your phrase about foo not living long about even if Foo is bound to 'static.

I'm pretty sure you would hit that issue, too, just later.

Here it's just issue #20671, just with lifetimes.

A way to solve this can be to do

trait Foo: 'static {
    type Bar<'a>: Bar<Baz = Self::Baz>;
    type Baz;
    …
1 Like

Supertrait bounds are another workaround.

trait FooButReally: for<'a> Foo<Bar<'a>: Bar<Baz: 'static>> {}
impl<T: ?Sized + for<'a> Foo<Bar<'a>: Bar<Baz: 'static>>> FooButReally for T {}

This is the closest GAT-specific issue I found, I think.

1 Like