Skip to content

Commit 104516b

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 1f04bba commit 104516b

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
@@ -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

Comments
 (0)