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 isBivariant(no inherent contribution). For&Tand&mut T, this isCovariant(from the lifetime'a). For*mut T, this isInvariant(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:
- Start with
base - For each
(position, shape)indeps:- Get
shape’s variance (recursively, with cycle detection) - If position is Contravariant, flip the variance
- Combine with the running total
- Get
- Return the result
Fields§
§base: VarianceThe base variance this type contributes.
Bivariantfor types that only derive variance from dependenciesCovariantfor types with an inherent lifetime (like&'a T,&'a mut T)Invariantfor 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
impl VarianceDesc
Sourcepub const BIVARIANT: VarianceDesc
pub const BIVARIANT: VarianceDesc
Always bivariant — no lifetime parameters.
Examples: i32, String, bool, ().
Sourcepub const INVARIANT: VarianceDesc
pub const INVARIANT: VarianceDesc
Always invariant — no lifetime, invariant with respect to type parameter.
Examples: *mut T.
Sourcepub const fn new(base: Variance, deps: &'static [VarianceDep]) -> VarianceDesc
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
impl Clone for VarianceDesc
Source§fn clone(&self) -> VarianceDesc
fn clone(&self) -> VarianceDesc
1.0.0 · Source§fn clone_from(&mut self, source: &Self)
fn clone_from(&mut self, source: &Self)
source. Read more