@@ -1988,9 +1988,10 @@ object Types {
1988
1988
}
1989
1989
1990
1990
/** The argument corresponding to class type parameter `tparam` as seen from
1991
- * prefix `pre`.
1991
+ * prefix `pre`. Can produce a TypeBounds type in case prefix is an & or | type
1992
+ * and parameter is non-variant.
1992
1993
*/
1993
- def argForParam (pre : Type )(implicit ctx : Context ): Type = {
1994
+ def argForParam (pre : Type , variance : Int )(implicit ctx : Context ): Type = {
1994
1995
val tparam = symbol
1995
1996
val cls = tparam.owner
1996
1997
val base = pre.baseType(cls)
@@ -2010,10 +2011,17 @@ object Types {
2010
2011
idx += 1
2011
2012
}
2012
2013
NoType
2013
- case OrType (base1, base2) => argForParam(base1) | argForParam(base2)
2014
- case AndType (base1, base2) => argForParam(base1) & argForParam(base2)
2014
+ case base : AndOrType =>
2015
+ var tp1 = argForParam(base.tp1, variance)
2016
+ var tp2 = argForParam(base.tp2, variance)
2017
+ if (tp1.isInstanceOf [TypeBounds ] || tp2.isInstanceOf [TypeBounds ] || variance == 0 ) {
2018
+ // compute argument as a type bounds instead of a point type
2019
+ tp1 = tp1.bounds
2020
+ tp2 = tp2.bounds
2021
+ }
2022
+ if (base.isAnd == variance >= 0 ) tp1 & tp2 else tp1 | tp2
2015
2023
case _ =>
2016
- if (pre.termSymbol is Package ) argForParam(pre.select(nme.PACKAGE ))
2024
+ if (pre.termSymbol is Package ) argForParam(pre.select(nme.PACKAGE ), variance )
2017
2025
else if (pre.isBottomType) pre
2018
2026
else NoType
2019
2027
}
@@ -2037,7 +2045,7 @@ object Types {
2037
2045
else {
2038
2046
if (isType) {
2039
2047
val res =
2040
- if (currentSymbol.is(ClassTypeParam )) argForParam(prefix)
2048
+ if (currentSymbol.is(ClassTypeParam )) argForParam(prefix, currentSymbol.paramVariance )
2041
2049
else prefix.lookupRefined(name)
2042
2050
if (res.exists) return res
2043
2051
if (Config .splitProjections)
@@ -4462,14 +4470,17 @@ object Types {
4462
4470
* If the expansion is a wildcard parameter reference, convert its
4463
4471
* underlying bounds to a range, otherwise return the expansion.
4464
4472
*/
4465
- def expandParam (tp : NamedType , pre : Type ): Type = tp.argForParam(pre) match {
4466
- case arg @ TypeRef (pre, _) if pre.isArgPrefixOf(arg.symbol) =>
4467
- arg.info match {
4468
- case TypeBounds (lo, hi) => range(atVariance(- variance)(reapply(lo)), reapply(hi))
4469
- case arg => reapply(arg)
4470
- }
4471
- case arg => reapply(arg)
4472
- }
4473
+ def expandParam (tp : NamedType , pre : Type , variance : Int ): Type =
4474
+ tp.argForParam(pre, variance) match {
4475
+ case arg @ TypeRef (pre, _) if pre.isArgPrefixOf(arg.symbol) =>
4476
+ arg.info match {
4477
+ case TypeBounds (lo, hi) => range(atVariance(- variance)(reapply(lo)), reapply(hi))
4478
+ case arg => reapply(arg)
4479
+ }
4480
+ case TypeBounds (lo, hi) =>
4481
+ range(lo, hi)
4482
+ case arg => reapply(arg)
4483
+ }
4473
4484
4474
4485
/** Derived selection.
4475
4486
* @pre the (upper bound of) prefix `pre` has a member named `tp.name`.
@@ -4479,12 +4490,15 @@ object Types {
4479
4490
else pre match {
4480
4491
case Range (preLo, preHi) =>
4481
4492
val forwarded =
4482
- if (tp.symbol.is(ClassTypeParam )) expandParam(tp, preHi)
4493
+ if (tp.symbol.is(ClassTypeParam )) expandParam(tp, preHi, tp.symbol.paramVariance )
4483
4494
else tryWiden(tp, preHi)
4484
4495
forwarded.orElse(
4485
4496
range(super .derivedSelect(tp, preLo), super .derivedSelect(tp, preHi)))
4486
4497
case _ =>
4487
- super .derivedSelect(tp, pre)
4498
+ super .derivedSelect(tp, pre) match {
4499
+ case TypeBounds (lo, hi) => range(lo, hi)
4500
+ case tp => tp
4501
+ }
4488
4502
}
4489
4503
4490
4504
override protected def derivedRefinedType (tp : RefinedType , parent : Type , info : Type ): Type =
0 commit comments