Trait lifetimes and associated constants that ref &Self


#1

I would like to define a trait with an associated constant containing a reference to an array of Self. The only way I can do this is to make the trait dependent on 'static (correct terminology?)

use std::fmt::Debug ;

// This all breaks unless the trait has a 'static lifetime
trait CardinalEnum : Sized+Debug+'static
{
    const SETSIZE: usize ;
    const SETMEMBERS: &'static [Self] ;
}

#[derive(Debug)]
enum States {
    Alpha = 0,
    Beta = 1,
    Gamma = 2
}

impl CardinalEnum for States {
    const SETSIZE: usize = 3 ;
    const SETMEMBERS: &'static [States] = &[States::Alpha,States::Beta,States::Gamma] ;
}

fn showme<T:CardinalEnum>() {
    println!("Set Size is {}",T::SETSIZE) ;

    for x in T::SETMEMBERS {
        println!("Results:{:?}",x);
    }
}

fn main() {
    showme::<States>() ;
}

The question is, what does it really mean when I say the trait depends on 'static? Given that I am defining constants that will last as long as the program, why do I have to declare lifetimes at all?

FYI, What I would really like to do is something like

trait CardinalEnum : Sized+Debug
    {
        const SETSIZE: usize ;
        const SETMEMBERS: [Self ; CardinalEnum::SETSIZE] ;
    }

But the array size for an associated constant can’t depend on another associated constant.


#2

CardinalEnum has a 'static bound. (the “dependencies” of a trait are also often called supertraits, but I don’t think anybody would call 'static a supertrait. OTOH, “bound” applies universally)

Trait: 'static means that T: Trait is only allowed if T: 'static. So you can’t implement the trait for types like &'a T because they don’t live long enough.

Why even care? Good question. I think the general sentiment as of late has been that these lifetime bounds on types are often not very useful to bother the programmer with since it is (often? usually? always?) impossible to construct cases that don’t meet the bound.

For instance, in your specific case, specifying Trait: 'static seems unnecessary because nobody could possibly implement it for a non-'static type anyways (they wouldn’t be able to define values for the constants because all const expressions are 'static. I think hope).

In other words this may be ground where things could change in the future.