@@ -3927,20 +3927,27 @@ object Types {
39273927 case Range (parentLo, parentHi) =>
39283928 range(derivedRefinedType(tp, parentLo, info), derivedRefinedType(tp, parentHi, info))
39293929 case _ =>
3930+ def propagate (lo : Type , hi : Type ) =
3931+ range(derivedRefinedType(tp, parent, lo), derivedRefinedType(tp, parent, hi))
39303932 if (parent.isBottomType) parent
39313933 else info match {
3934+ case Range (infoLo : TypeBounds , infoHi : TypeBounds ) =>
3935+ assert(variance == 0 )
3936+ val v1 = infoLo.variance
3937+ val v2 = infoHi.variance
3938+ // There's some weirdness coming from the way aliases can have variance
3939+ // If infoLo and infoHi are both aliases with the same non-zero variance
3940+ // we can propagate to a range of the refined types. If they are both
3941+ // non-alias ranges we know that infoLo <:< infoHi and therefore we can
3942+ // propagate to refined types with infoLo and infoHi as bounds.
3943+ // In all other cases, Nothing..Any is the only interval that contains
3944+ // the range. i966.scala is a test case.
3945+ if (v1 > 0 && v2 > 0 ) propagate(infoLo, infoHi)
3946+ else if (v1 < 0 && v2 < 0 ) propagate(infoHi, infoLo)
3947+ else if (! infoLo.isAlias && ! infoHi.isAlias) propagate(infoLo, infoHi)
3948+ else range(tp.bottomType, tp.topType)
39323949 case Range (infoLo, infoHi) =>
3933- def propagate (lo : Type , hi : Type ) =
3934- range(derivedRefinedType(tp, parent, lo), derivedRefinedType(tp, parent, hi))
3935- tp.refinedInfo match {
3936- case rinfo : TypeBounds =>
3937- val v = if (rinfo.isAlias) rinfo.variance * variance else variance
3938- if (v > 0 ) tp.derivedRefinedType(parent, tp.refinedName, rangeToBounds(info))
3939- else if (v < 0 ) propagate(infoHi, infoLo)
3940- else range(tp.bottomType, tp.topType)
3941- case _ =>
3942- propagate(infoLo, infoHi)
3943- }
3950+ propagate(infoLo, infoHi)
39443951 case _ =>
39453952 tp.derivedRefinedType(parent, tp.refinedName, info)
39463953 }
0 commit comments