@@ -27,88 +27,6 @@ object Variances {
2727 else if (v == Contravariant ) Covariant
2828 else v
2929
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-
11230 def setStructuralVariances (lam : HKTypeLambda )(using Context ): Unit =
11331 assert(! lam.isDeclaredVarianceLambda)
11432 for param <- lam.typeParams do param.storedVariance = Bivariant
@@ -127,12 +45,12 @@ object Variances {
12745 /** Does variance `v1` conform to variance `v2`?
12846 * This is the case if the variances are the same or `sym` is nonvariant.
12947 */
130- def varianceConforms (v1 : Int , v2 : Int ): Boolean =
48+ def varianceConforms (v1 : Int , v2 : Int ): Boolean =
13149 v1 == v2 || v2 == 0
13250
13351 /** Does the variance of type parameter `tparam1` conform to the variance of type parameter `tparam2`?
13452 */
135- def varianceConforms (tparam1 : TypeParamInfo , tparam2 : TypeParamInfo )(using Context ): Boolean =
53+ def varianceConforms (tparam1 : TypeParamInfo , tparam2 : TypeParamInfo )(using Context ): Boolean =
13654 tparam1.paramVariance.isAllOf(tparam2.paramVariance)
13755
13856 /** Do the variances of type parameters `tparams1` conform to the variances
@@ -147,15 +65,18 @@ object Variances {
14765 if needsDetailedCheck then tparams1.corresponds(tparams2)(varianceConforms)
14866 else tparams1.hasSameLengthAs(tparams2)
14967
150- def varianceSign (sym : Symbol )(using Context ): String =
151- varianceSign(sym.variance)
152-
15368 def varianceSign (v : Variance ): String = varianceSign(varianceToInt(v))
69+ def varianceLabel (v : Variance ): String = varianceLabel(varianceToInt(v))
15470
15571 def varianceSign (v : Int ): String =
15672 if (v > 0 ) " +"
15773 else if (v < 0 ) " -"
15874 else " "
15975
76+ def varianceLabel (v : Int ): String =
77+ if v < 0 then " contravariant"
78+ else if v > 0 then " covariant"
79+ else " invariant"
80+
16081 val alwaysInvariant : Any => Invariant .type = Function .const(Invariant )
16182}
0 commit comments