error[E0392]: lifetime parameter `'a` is never used
--> .\test.rs:1:19
|
1 | pub struct Struct<'a>;
| ^^ unused lifetime parameter
|
= help: consider removing `'a`, referring to it in a field, or using a marker such as `PhantomData`
error[E0392]: lifetime parameter `'a` is never used
--> .\test.rs:2:15
|
2 | pub enum Enum<'a> {}
| ^^ unused lifetime parameter
|
= help: consider removing `'a`, referring to it in a field, or using a marker such as `PhantomData`
error: aborting due to 2 previous errors
Because in the case of Struct and Enum, the borrow checker needs to deal with instances of them, while in the case of Trait, an unused lifetime is not an issue unless it appears in the contract.
Because it can be useful for marker traits (traits that add no functionality themselves, but are used to ensure that only types with certain permissions get through type checking, like Send and Unpin):
pub trait Trait<'a> {}
impl Trait<'static> for &'static str {}
impl<'a, 'b> Trait<'a> for &'b u32 {}
can only be called for a parameter of type &'static str if 'a: 'static and 'b: 'static, whereas it can be called for any &u32, regardless of lifetimes.
I can't, off the top of my head, think of a good reason to want this, but it's a feature that traits would otherwise lack.
Is it also because referencing a lifetime in a trait by adding a method would require implementing that method to use it, which is a bigger imposition than adding a private PhantomData field in the case of a struct?
AFAIK the reason is that types have variance, while traits don't. Given a struct Struct<'a> it is however not possible to determine whether it is covariant, contravariant or invariant with respect to 'a, so it is an error and you should specify that by introducing some field using it (e.g. PhantomData).