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