Skip to content

Commit 4160921

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 8c1a6dc commit 4160921

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
@@ -3923,20 +3923,27 @@ object Types {
39233923
case Range(parentLo, parentHi) =>
39243924
range(derivedRefinedType(tp, parentLo, info), derivedRefinedType(tp, parentHi, info))
39253925
case _ =>
3926+
def propagate(lo: Type, hi: Type) =
3927+
range(derivedRefinedType(tp, parent, lo), derivedRefinedType(tp, parent, hi))
39263928
if (parent.isBottomType) parent
39273929
else info match {
3930+
case Range(infoLo: TypeBounds, infoHi: TypeBounds) =>
3931+
assert(variance == 0)
3932+
val v1 = infoLo.variance
3933+
val v2 = infoHi.variance
3934+
// There's some weirdness coming from the way aliases can have variance
3935+
// If infoLo and infoHi are both aliases with the same non-zero variance
3936+
// we can propagate to a range of the refined types. If they are both
3937+
// non-alias ranges we know that infoLo <:< infoHi and therefore we can
3938+
// propagate to refined types with infoLo and infoHi as bounds.
3939+
// In all other cases, Nothing..Any is the only interval that contains
3940+
// the range. i966.scala is a test case.
3941+
if (v1 > 0 && v2 > 0) propagate(infoLo, infoHi)
3942+
else if (v1 < 0 && v2 < 0) propagate(infoHi, infoLo)
3943+
else if (!infoLo.isAlias && !infoHi.isAlias) propagate(infoLo, infoHi)
3944+
else range(tp.bottomType, tp.topType)
39283945
case Range(infoLo, infoHi) =>
3929-
def propagate(lo: Type, hi: Type) =
3930-
range(derivedRefinedType(tp, parent, lo), derivedRefinedType(tp, parent, hi))
3931-
tp.refinedInfo match {
3932-
case rinfo: TypeBounds =>
3933-
val v = if (rinfo.isAlias) rinfo.variance * variance else variance
3934-
if (v > 0) tp.derivedRefinedType(parent, tp.refinedName, rangeToBounds(info))
3935-
else if (v < 0) propagate(infoHi, infoLo)
3936-
else range(tp.bottomType, tp.topType)
3937-
case _ =>
3938-
propagate(infoLo, infoHi)
3939-
}
3946+
propagate(infoLo, infoHi)
39403947
case _ =>
39413948
tp.derivedRefinedType(parent, tp.refinedName, info)
39423949
}

0 commit comments

Comments
 (0)