Skip to content

Commit 0dae33c

Browse files
committed
Fix derivedRefinedType in ApproximatingTypeMap
The logic before was overcomplicated since I did not take into account that Range refinedInfos could only happen at variance 0. On the othet hand, it did not take into account all the subtleties of alias types with variances.
1 parent 47967b2 commit 0dae33c

File tree

1 file changed

+18
-11
lines changed

1 file changed

+18
-11
lines changed

compiler/src/dotty/tools/dotc/core/Types.scala

Lines changed: 18 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -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

Comments
 (0)