Derive Macro transient::Transient

source ·
#[derive(Transient)]
{
    // Attributes available to this derive:
    #[variance]
}
Expand description

Derive macro that implements the Transient trait for a struct with at most 1 lifetime parameter.

This macro is limited to structs satisfying the following conditions:

  • There must be at most 1 lifetime parameter. Structs with extra lifetime parameters can easily implement the trait by hand, but care must be taken to ensure that the invariants detailed in the trait’s safety docs are upheld.
  • There may be any number of type (or const) parameters, but the trait will only be implemented where T: 'static for each type parameter T.

§Customization

By default, the variance of a deriving struct is assumed to be invariant with respect to its lifetime parameter (if it has one), since this is the only type of variance that can be safely used for all types without analyzing the behavior of its fields (which this macro does not attempt to do). When the added flexibility of covariance or contravariance is needed, the “variance(…)” helper attribute can be used to unsafe-ly override this default if you are confident that the chosen variance is appropriate for the type; however, you should first review the safety docs for the Transient trait (particularly related to its Transience associated type to ensure that its invariants are upheld.

To set the variance for your type, annotate one of its fields (preferably either the first field or the field with the lifetime, but any will do) with the #[variance(...)] attribute, substituting the ellipsis for one of the following keywords:

KeywordAliasDescription
invariantinvDeclares a invariant relationship with the lifetime; this is the default for types with a lifetime parameter.
unsafe_covariantunsafe_coDeclares a covariant relationship with the lifetime; this is unsafe.
unsafe_contravariantunsafe_contraDeclares a covariant relationship with the lifetime; this is unsafe.

This can fail for any of the following reasons:

  • Requesting any variance for a type with no lifetime parameters
  • Requesting co- or contra-variance without the ‘unsafe_’ prefix
  • Providing more than one “variance” attribute with conflicting values

§Examples

Invocation with a type parameter and a lifetime parameter:

use transient::Transient;

#[derive(Debug, Clone, PartialEq, Eq, Transient)]
struct S<'a, T> {
    value: &'a T,
}

This will generate the following impl:

unsafe impl<'a, T: 'static> transient::Transient for S<'a, T> {
    type Static = S<'static, T>;
    type Transience = transient::Inv<'a>;
}

Invocation with a single lifetime and an attribute declaring covariance:

use transient::Transient;

#[derive(Debug, Clone, PartialEq, Eq, Transient)]
struct S<'a> {
    #[variance(unsafe_co)]
    name: String,
    values: &'a [i32]
}

The generated impl will then be:

unsafe impl<'a> transient::Transient for S<'a> {
    type Static = S<'static>;
    type Transience = transient::Co<'a>;
}