@@ -61,25 +61,51 @@ Variance of types is automatically determined as follows
6161|  ` [T] `  and ` [T; n] `             |                    |  covariant         | 
6262|  ` fn() -> T `                    |                    |  covariant         | 
6363|  ` fn(T) -> () `                  |                    |  contravariant     | 
64- |  ` fn(T) -> T `                   |                    |  invariant         | 
6564|  ` std::cell::UnsafeCell<T> `     |                    |  invariant         | 
6665|  ` std::marker::PhantomData<T> `  |                    |  covariant         | 
6766|  ` dyn Trait<T> + 'a `            |  covariant         |  invariant         | 
6867
69- The variance of other ` struct ` , ` enum ` , ` union ` , and tuple  types is decided by
68+ The variance of other ` struct ` , ` enum ` , and  ` union `  types is decided by
7069looking at the variance of the types of their fields. If the parameter is used
7170in positions with different variances then the parameter is invariant. For
72- example the following struct is covariant in ` 'a `  and ` T `  and invariant in ` 'b ` 
71+ example the following struct is covariant in ` 'a `  and ` T `  and invariant in ` 'b ` ,  ` 'c ` , 
7372and ` U ` .
7473
7574``` rust 
7675use  std :: cell :: UnsafeCell ;
77- struct  Variance <'a , 'b , T , U :  'a > {
76+ struct  Variance <'a , 'b , ' c ,  T , U :  'a > {
7877    x :  & 'a  U ,               //  This makes `Variance` covariant in 'a, and would
7978                            //  make it covariant in U, but U is used later
8079    y :  * const  T ,            //  Covariant in T
8180    z :  UnsafeCell <& 'b  f64 >, //  Invariant in 'b
8281    w :  * mut  U ,              //  Invariant in U, makes the whole struct invariant
82+ 
83+     f :  fn (& 'c  ()) ->  & 'c  () //  Both co- and contravariant, makes 'c invariant
84+                             //  in the struct.
85+ }
86+ ``` 
87+ 
88+ When used outside of an ` struct ` , ` enum ` , or ` union ` , the variance for parameters is checked at each location separately.
89+ 
90+ ``` rust 
91+ # use  std :: cell :: UnsafeCell ;
92+ fn  generic_tuple <'short , 'long :  'short >(
93+     //  'long is used inside of a tuple in both a co- and invariant position.
94+     x :  (& 'long  u32 , UnsafeCell <& 'long  u32 >),
95+ ) {
96+     //  As the variance at these positions is computed separately,
97+     //  we can freely shrink 'long in the covariant position.
98+     let  _ :  (& 'short  u32 , UnsafeCell <& 'long  u32 >) =  x ;
99+ }
100+ 
101+ fn  takes_fn_ptr <'short , 'middle :  'short >(
102+     //  'middle is used in both a co- and contravariant position.
103+     f :  fn (& 'middle  ()) ->  & 'middle  (),
104+ ) {
105+     //  As the variance at these positions is computed separately,
106+     //  we can freely shrink 'middle in the covariant position
107+     //  and extend it in the contravariant position.
108+     let  _ :  fn (& 'static  ()) ->  & 'short  () =  f ;
83109}
84110``` 
85111
0 commit comments