@@ -1988,9 +1988,10 @@ object Types {
19881988 }
19891989
19901990 /** 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.
19921993 */
1993- def argForParam (pre : Type )(implicit ctx : Context ): Type = {
1994+ def argForParam (pre : Type , variance : Int )(implicit ctx : Context ): Type = {
19941995 val tparam = symbol
19951996 val cls = tparam.owner
19961997 val base = pre.baseType(cls)
@@ -2010,10 +2011,17 @@ object Types {
20102011 idx += 1
20112012 }
20122013 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
20152023 case _ =>
2016- if (pre.termSymbol is Package ) argForParam(pre.select(nme.PACKAGE ))
2024+ if (pre.termSymbol is Package ) argForParam(pre.select(nme.PACKAGE ), variance )
20172025 else if (pre.isBottomType) pre
20182026 else NoType
20192027 }
@@ -2037,7 +2045,7 @@ object Types {
20372045 else {
20382046 if (isType) {
20392047 val res =
2040- if (currentSymbol.is(ClassTypeParam )) argForParam(prefix)
2048+ if (currentSymbol.is(ClassTypeParam )) argForParam(prefix, currentSymbol.paramVariance )
20412049 else prefix.lookupRefined(name)
20422050 if (res.exists) return res
20432051 if (Config .splitProjections)
@@ -4462,14 +4470,17 @@ object Types {
44624470 * If the expansion is a wildcard parameter reference, convert its
44634471 * underlying bounds to a range, otherwise return the expansion.
44644472 */
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+ }
44734484
44744485 /** Derived selection.
44754486 * @pre the (upper bound of) prefix `pre` has a member named `tp.name`.
@@ -4479,12 +4490,15 @@ object Types {
44794490 else pre match {
44804491 case Range (preLo, preHi) =>
44814492 val forwarded =
4482- if (tp.symbol.is(ClassTypeParam )) expandParam(tp, preHi)
4493+ if (tp.symbol.is(ClassTypeParam )) expandParam(tp, preHi, tp.symbol.paramVariance )
44834494 else tryWiden(tp, preHi)
44844495 forwarded.orElse(
44854496 range(super .derivedSelect(tp, preLo), super .derivedSelect(tp, preHi)))
44864497 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+ }
44884502 }
44894503
44904504 override protected def derivedRefinedType (tp : RefinedType , parent : Type , info : Type ): Type =
0 commit comments