# [−][src]Crate type_variance

Marker types to indicate precisely the variance relationship between a generic type and its parameters.

Rust supports three different modes of variance between a generic type `F`

and a type parameter `T`

:^{1}

- Covariance:
`F<T>`

is a subtype of`F<U>`

if`T`

is a subtype of`U`

. - Contravariance:
`F<T>`

is a subtype of`F<U>`

if`U`

is a subtype of`T`

. - Invariance:
`F<T>`

is never a subtype of`F<U>`

(unless`T = U`

).

Rust is usually able to infer the variance of a type parameter from its use,
but fails if the type parameter is not used within the type definition.
Typically, this is resolved by using a `PhantomData`

to indicate the
parameter's use within the type:

use std::marker::PhantomData; struct Slice<'a, T: 'a> { start: *const T, end: *const T, phantom: PhantomData<&'a T>, }

However, in some cases, the subtyping relation is not always obvious from a
`PhantomData`

field. In such cases, it can be useful to make the variance
explicit with one of the markers `Covariant`

, `Contravariant`

, and
`Invariant`

.

use type_variance::{Covariant, Contravariant}; struct Func<Arg, Ret> { arg: Covariant<Arg>, ret: Contravariant<Ret>, }

## Enforcing invariance

Another use case is when a type parameter is used, but the Rust compiler
deduces a more permissive variance than is desired. In this case, the
`Invariant`

marker can be used to ensure that the generic type is invariant
with respect to the given type parameter.

use type_variance::Invariant; struct Opaque<T> { inner: Box<T>, // Implies `Opaque` is covariant to `T` marker: Invariant<T>, // Ensures that `Opaque` is invariant to `T` }

The `Invariant`

overrules any other implied variances and so `Opaque`

becomes invariant to `T`

.

## Lifetime parameters

Like `PhantomData`

, the provided variance markers only accept type
parameters. To indicate a generic type's variance with respect to its
lifetime parameters, use the `Lifetime`

wrapper, which converts a
lifetime to a regular type while preserving its subtyping relation.

# Limitations

The marker traits `Covariant`

and `Contravariant`

*do not* necessarily
guarantee that the compiler will use the marked variance. If two uses of a
type parameter imply differing variances, the compiler will consider the
generic type *invariant* with respect to the parameter.

For example:

struct Ref<'a, T> { inner: &'a T, // Implies `Ref` is covariant to `T` marker: Contravariant<T>, // Implies `Ref` is contravariant to `T` }

As a result of these conflicting variances, the compiler will decide that
`Ref`

is invariant to `T`

.

Due to this, it is recommended that `Covariant`

and `Contravariant`

are only
used on type parameters that are not used in any other fields of the type.

## Structs

Contravariant | Zero-sized type used to mark a type as contravariant with respect to its type
parameter |

Covariant | Zero-sized type used to mark a type as covariant with respect to its type
parameter |

Invariant | Zero-sized type used to mark a type as invariant with respect to its type
parameter |

Lifetime | Variance-preserving type wrapper around a lifetime parameter. |

## Traits

Variance | A sealed trait implemented by |

## Functions

variance | A convenience function for constructing any of |