1
+ ## Variance of type and lifetime parameters
2
+
1
3
This file infers the variance of type and lifetime parameters. The
2
4
algorithm is taken from Section 4 of the paper "Taming the Wildcards:
3
5
Combining Definition- and Use-Site Variance" published in PLDI'11 and
@@ -52,11 +54,11 @@ These indicate that (1) the variance of A must be at most covariant;
52
54
variance of C must be at most covariant * and* contravariant. All of these
53
55
results are based on a variance lattice defined as follows:
54
56
55
- * Top (bivariant)
56
- - +
57
- o Bottom (invariant)
57
+ * Top (bivariant)
58
+ - +
59
+ o Bottom (invariant)
58
60
59
- Based on this lattice, the solution V(A)=+, V(B)=-, V(C)=o is the
61
+ Based on this lattice, the solution ` V(A)=+ ` , ` V(B)=- ` , ` V(C)=o ` is the
60
62
optimal solution. Note that there is always a naive solution which
61
63
just declares all variables to be invariant.
62
64
@@ -68,11 +70,11 @@ take the form:
68
70
V(X) <= Term
69
71
Term := + | - | * | o | V(X) | Term x Term
70
72
71
- Here the notation V(X) indicates the variance of a type/region
73
+ Here the notation ` V(X) ` indicates the variance of a type/region
72
74
parameter ` X ` with respect to its defining class. ` Term x Term `
73
75
represents the "variance transform" as defined in the paper:
74
76
75
- If the variance of a type variable ` X ` in type expression ` E ` is ` V2 `
77
+ > If the variance of a type variable ` X ` in type expression ` E ` is ` V2 `
76
78
and the definition-site variance of the [ corresponding] type parameter
77
79
of a class ` C ` is ` V1 ` , then the variance of ` X ` in the type expression
78
80
` C<E> ` is ` V3 = V1.xform(V2) ` .
@@ -267,7 +269,7 @@ expressions -- must be invariant with respect to all of their
267
269
inputs. To see why this makes sense, consider what subtyping for a
268
270
trait reference means:
269
271
270
- <T as Trait > <: <U as Trait >
272
+ <T as Trait> <: <U as Trait>
271
273
272
274
means that if I know that ` T as Trait ` , I also know that `U as
273
275
Trait`. Moreover, if you think of it as dictionary passing style,
@@ -291,9 +293,9 @@ impl<T> Identity for T { type Out = T; ... }
291
293
Now if I have ` <&'static () as Identity>::Out ` , this can be
292
294
validly derived as ` &'a () ` for any ` 'a ` :
293
295
294
- <&'a () as Identity> <: <&'static () as Identity>
295
- if &'static () < : &'a () -- Identity is contravariant in Self
296
- if 'static : 'a -- Subtyping rules for relations
296
+ <&'a () as Identity> <: <&'static () as Identity>
297
+ if &'static () < : &'a () -- Identity is contravariant in Self
298
+ if 'static : 'a -- Subtyping rules for relations
297
299
298
300
This change otoh means that ` <'static () as Identity>::Out ` is
299
301
always ` &'static () ` (which might then be upcast to ` 'a () ` ,
0 commit comments