@@ -27,88 +27,6 @@ object Variances {
27
27
else if (v == Contravariant ) Covariant
28
28
else v
29
29
30
- /** Map everything below Bivariant to Invariant */
31
- def cut (v : Variance ): Variance =
32
- if (v == Bivariant ) v else Invariant
33
-
34
- def compose (v : Variance , boundsVariance : Int ): Variance =
35
- if (boundsVariance == 1 ) v
36
- else if (boundsVariance == - 1 ) flip(v)
37
- else cut(v)
38
-
39
- /** Compute variance of type parameter `tparam` in types of all symbols `sym`. */
40
- def varianceInSyms (syms : List [Symbol ])(tparam : Symbol )(using Context ): Variance =
41
- syms.foldLeft(Bivariant ) ((v, sym) => v & varianceInSym(sym)(tparam))
42
-
43
- /** Compute variance of type parameter `tparam` in type of symbol `sym`. */
44
- def varianceInSym (sym : Symbol )(tparam : Symbol )(using Context ): Variance =
45
- if (sym.isAliasType) cut(varianceInType(sym.info)(tparam))
46
- else varianceInType(sym.info)(tparam)
47
-
48
- /** Compute variance of type parameter `tparam` in all types `tps`. */
49
- def varianceInTypes (tps : List [Type ])(tparam : Symbol )(using Context ): Variance =
50
- tps.foldLeft(Bivariant ) ((v, tp) => v & varianceInType(tp)(tparam))
51
-
52
- /** Compute variance of type parameter `tparam` in all type arguments
53
- * <code>tps</code> which correspond to formal type parameters `tparams1`.
54
- */
55
- def varianceInArgs (tps : List [Type ], tparams1 : List [Symbol ])(tparam : Symbol )(using Context ): Variance = {
56
- var v : Variance = Bivariant ;
57
- for ((tp, tparam1) <- tps zip tparams1) {
58
- val v1 = varianceInType(tp)(tparam)
59
- v = v & (if (tparam1.is(Covariant )) v1
60
- else if (tparam1.is(Contravariant )) flip(v1)
61
- else cut(v1))
62
- }
63
- v
64
- }
65
-
66
- /** Compute variance of type parameter `tparam` in all type annotations `annots`. */
67
- def varianceInAnnots (annots : List [Annotation ])(tparam : Symbol )(using Context ): Variance =
68
- annots.foldLeft(Bivariant ) ((v, annot) => v & varianceInAnnot(annot)(tparam))
69
-
70
- /** Compute variance of type parameter `tparam` in type annotation `annot`. */
71
- def varianceInAnnot (annot : Annotation )(tparam : Symbol )(using Context ): Variance =
72
- varianceInType(annot.tree.tpe)(tparam)
73
-
74
- /** Compute variance of type parameter <code>tparam</code> in type <code>tp</code>. */
75
- def varianceInType (tp : Type )(tparam : Symbol )(using Context ): Variance = tp match {
76
- case TermRef (pre, _) =>
77
- varianceInType(pre)(tparam)
78
- case tp @ TypeRef (pre, _) =>
79
- if (tp.symbol == tparam) Covariant else varianceInType(pre)(tparam)
80
- case tp @ TypeBounds (lo, hi) =>
81
- if (lo eq hi) cut(varianceInType(hi)(tparam))
82
- else flip(varianceInType(lo)(tparam)) & varianceInType(hi)(tparam)
83
- case tp @ RefinedType (parent, _, rinfo) =>
84
- varianceInType(parent)(tparam) & varianceInType(rinfo)(tparam)
85
- case tp : RecType =>
86
- varianceInType(tp.parent)(tparam)
87
- case tp : MethodOrPoly =>
88
- flip(varianceInTypes(tp.paramInfos)(tparam)) & varianceInType(tp.resultType)(tparam)
89
- case ExprType (restpe) =>
90
- varianceInType(restpe)(tparam)
91
- case tp @ AppliedType (tycon, args) =>
92
- def varianceInArgs (v : Variance , args : List [Type ], tparams : List [ParamInfo ]): Variance =
93
- args match {
94
- case arg :: args1 =>
95
- varianceInArgs(
96
- v & compose(varianceInType(arg)(tparam), tparams.head.paramVarianceSign),
97
- args1, tparams.tail)
98
- case nil =>
99
- v
100
- }
101
- varianceInArgs(varianceInType(tycon)(tparam), args, tycon.typeParams)
102
- case AnnotatedType (tp, annot) =>
103
- varianceInType(tp)(tparam) & varianceInAnnot(annot)(tparam)
104
- case AndType (tp1, tp2) =>
105
- varianceInType(tp1)(tparam) & varianceInType(tp2)(tparam)
106
- case OrType (tp1, tp2) =>
107
- varianceInType(tp1)(tparam) & varianceInType(tp2)(tparam)
108
- case _ =>
109
- Bivariant
110
- }
111
-
112
30
def setStructuralVariances (lam : HKTypeLambda )(using Context ): Unit =
113
31
assert(! lam.isDeclaredVarianceLambda)
114
32
for param <- lam.typeParams do param.storedVariance = Bivariant
@@ -127,12 +45,12 @@ object Variances {
127
45
/** Does variance `v1` conform to variance `v2`?
128
46
* This is the case if the variances are the same or `sym` is nonvariant.
129
47
*/
130
- def varianceConforms (v1 : Int , v2 : Int ): Boolean =
48
+ def varianceConforms (v1 : Int , v2 : Int ): Boolean =
131
49
v1 == v2 || v2 == 0
132
50
133
51
/** Does the variance of type parameter `tparam1` conform to the variance of type parameter `tparam2`?
134
52
*/
135
- def varianceConforms (tparam1 : TypeParamInfo , tparam2 : TypeParamInfo )(using Context ): Boolean =
53
+ def varianceConforms (tparam1 : TypeParamInfo , tparam2 : TypeParamInfo )(using Context ): Boolean =
136
54
tparam1.paramVariance.isAllOf(tparam2.paramVariance)
137
55
138
56
/** Do the variances of type parameters `tparams1` conform to the variances
@@ -147,15 +65,18 @@ object Variances {
147
65
if needsDetailedCheck then tparams1.corresponds(tparams2)(varianceConforms)
148
66
else tparams1.hasSameLengthAs(tparams2)
149
67
150
- def varianceSign (sym : Symbol )(using Context ): String =
151
- varianceSign(sym.variance)
152
-
153
68
def varianceSign (v : Variance ): String = varianceSign(varianceToInt(v))
69
+ def varianceLabel (v : Variance ): String = varianceLabel(varianceToInt(v))
154
70
155
71
def varianceSign (v : Int ): String =
156
72
if (v > 0 ) " +"
157
73
else if (v < 0 ) " -"
158
74
else " "
159
75
76
+ def varianceLabel (v : Int ): String =
77
+ if v < 0 then " contravariant"
78
+ else if v > 0 then " covariant"
79
+ else " invariant"
80
+
160
81
val alwaysInvariant : Any => Invariant .type = Function .const(Invariant )
161
82
}
0 commit comments