Why is 'static required here?

trait Assoc {
    type Ty;
}

struct Foo<T: Assoc>(<T as Assoc>::Ty);

fn assert_static<T: 'static>() {}

fn test<T: Assoc>() {
    assert_static::<Foo<T>>();    
}

(playground)

The way I understand the lifetime of a type is that a type is 'static if all its fields are 'static.
In the code above Foo<T> should be 'static iff its field T::Ty is also 'static. So why does the compiler wants T to be 'static instead of wanting T::Ty to be 'static ?

Unfortunately that's false. For a type to be 'static all its generic parameters (both lifetime and type arguments) need to be 'static, which in turn does imply (at least with the current Rust) that all its field types are also 'static. This is because if it contains a lifetime, after that lifetime ends the type itself becomes invalid.

You could probably imagine a Rust-like language without this restriction, but its trait system would have to make very different assumptions on the validity of types.

1 Like

A type meets the 'static bound iff all of its generic parameters meet a 'static bound. In the playground, that means that Foo<T>: 'static iff T: 'static.

Note also that, even if Rust worked differently and the bounds were based on fields, your playground didn't guarantee that T::Ty: 'static. This compiles:

impl<'a> Assoc for &'a str {
    type Ty = &'a String;
}

fn test<T: Assoc>(_: T) {}

fn main() {
    let local = String::new();
    test(&*local);
}

It is the case that T: 'static does imply T::Ty: 'static:

fn assert_static<T: 'static>() {}

fn test<T: Assoc + 'static>() {
    assert_static::<T::Ty>();    
}

Because if the trait has no parameters and the implementing type is 'static, there's no way to name a type that isn't 'static when defining the associated type.[1]

But it's not the case that T::Ty: 'static implies T: 'static:

impl<'a> Assoc for &'a [f64] {
    type Ty = i32;
}

Sometimes it's "good enough" to just use something like Foo<&'static [f64]> for such cases. (But not always.)


  1. Incidentally, the rest of that RFC is what describes how lifetime bounds work. ↩ī¸Ž

1 Like

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.