VarianceDesc

Struct VarianceDesc 

Source
pub struct VarianceDesc {
    pub base: Variance,
    pub deps: &'static [VarianceDep],
}
Expand description

Declarative description of a type’s variance.

Instead of using a function that computes variance (which could accidentally create new visited sets and break cycle detection), types declare their variance as data. The central computed_variance_impl function interprets this description, ensuring consistent cycle detection across all types.

§Structure

  • base: The variance this type contributes regardless of its dependencies. For most types this is Bivariant (no inherent contribution). For &T and &mut T, this is Covariant (from the lifetime 'a). For *mut T, this is Invariant (no lifetime, always invariant with respect to T).

  • deps: Type dependencies to combine. Each dependency has a position (covariant, contravariant, or invariant) that determines how its variance is transformed before combining.

§Examples

From the Rustonomicon:

&'a T:        base=Covariant,  deps=[(Covariant, T)]
              // covariant with respect to 'a, covariant with respect to T
&'a mut T:    base=Covariant,  deps=[(Invariant, T)]
              // covariant with respect to 'a, invariant with respect to T
*const T:     base=Bivariant,  deps=[(Covariant, T)]
              // covariant with respect to T
*mut T:       base=Invariant,  deps=[]
              // invariant with respect to T (no lifetime to be covariant with respect to)
Box<T>:       base=Bivariant,  deps=[(Covariant, T)]
fn(A) -> R:   base=Bivariant,  deps=[(Contravariant, A), (Covariant, R)]
struct {x,y}: base=Bivariant,  deps=[(Covariant, x), (Covariant, y)]

Note: an (Invariant, shape) dependency doesn’t automatically force the whole type to be invariant. If shape’s computed variance is Bivariant (it doesn’t mention the parameter being analyzed), it contributes nothing.

§Computation

The final variance is computed as:

  1. Start with base
  2. For each (position, shape) in deps:
    • Get shape’s variance (recursively, with cycle detection)
    • If position is Contravariant, flip the variance
    • Combine with the running total
  3. Return the result

Fields§

§base: Variance

The base variance this type contributes.

  • Bivariant for types that only derive variance from dependencies
  • Covariant for types with an inherent lifetime (like &'a T, &'a mut T)
  • Invariant for types that are always invariant (like *mut T)
§deps: &'static [VarianceDep]

Dependencies whose variances are combined to produce the final variance.

Empty for types with constant variance (like *mut T which is always Invariant). For &'a mut T, contains T in Invariant position.

Implementations§

Source§

impl VarianceDesc

Source

pub const BIVARIANT: VarianceDesc

Always bivariant — no lifetime parameters.

Examples: i32, String, bool, ().

Source

pub const INVARIANT: VarianceDesc

Always invariant — no lifetime, invariant with respect to type parameter.

Examples: *mut T.

Source

pub const fn new(base: Variance, deps: &'static [VarianceDep]) -> VarianceDesc

Create a variance description with the given base and dependencies.

Trait Implementations§

Source§

impl Clone for VarianceDesc

Source§

fn clone(&self) -> VarianceDesc

Returns a duplicate of the value. Read more
1.0.0 · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl Debug for VarianceDesc

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error>

Formats the value using the given formatter. Read more
Source§

impl Copy for VarianceDesc

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.