Skip to content

Commit fa79a0e

Browse files
committed
Refine derivedRefinedType
1 parent 3459627 commit fa79a0e

File tree

1 file changed

+24
-10
lines changed

1 file changed

+24
-10
lines changed

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

Lines changed: 24 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -3882,19 +3882,19 @@ object Types {
38823882
else if (variance < 0) lo
38833883
else Range(lower(lo), upper(hi))
38843884

3885-
private def isRange(tp: Type) = tp.isInstanceOf[Range]
3885+
protected def isRange(tp: Type) = tp.isInstanceOf[Range]
38863886

3887-
private def lower(tp: Type) = tp match {
3887+
protected def lower(tp: Type) = tp match {
38883888
case tp: Range => tp.lo
38893889
case _ => tp
38903890
}
38913891

3892-
private def upper(tp: Type) = tp match {
3892+
protected def upper(tp: Type) = tp match {
38933893
case tp: Range => tp.hi
38943894
case _ => tp
38953895
}
38963896

3897-
private def rangeToBounds(tp: Type) = tp match {
3897+
protected def rangeToBounds(tp: Type) = tp match {
38983898
case Range(lo, hi) => TypeBounds(lo, hi)
38993899
case _ => tp
39003900
}
@@ -3905,11 +3905,14 @@ object Types {
39053905
try op finally variance = saved
39063906
}
39073907

3908+
/** Derived selection.
3909+
* @pre the (upper bound of) prefix `pre` has a member named `tp.name`.
3910+
*/
39083911
override protected def derivedSelect(tp: NamedType, pre: Type) =
39093912
if (pre eq tp.prefix) tp
39103913
else pre match {
39113914
case Range(preLo, preHi) =>
3912-
preHi.member(tp.name).info match {
3915+
preHi.member(tp.name).info.widenExpr match {
39133916
case TypeAlias(alias) =>
39143917
// if H#T = U, then for any x in L..H, x.T =:= U,
39153918
// hence we can replace with U under all variances
@@ -3935,12 +3938,22 @@ object Types {
39353938
case _ =>
39363939
if (parent.isBottomType) parent
39373940
else info match {
3938-
case Range(infoLo, infoHi) if tp.refinedName.isTermName || variance <= 0 =>
3939-
range(derivedRefinedType(tp, parent, infoLo), derivedRefinedType(tp, parent, infoHi))
3941+
case Range(infoLo, infoHi) =>
3942+
def propagate(lo: Type, hi: Type) =
3943+
range(derivedRefinedType(tp, parent, lo), derivedRefinedType(tp, parent, hi))
3944+
tp.refinedInfo match {
3945+
case rinfo: TypeBounds =>
3946+
val v = if (rinfo.isAlias) rinfo.variance * variance else variance
3947+
if (v > 0) tp.derivedRefinedType(parent, tp.refinedName, rangeToBounds(info))
3948+
else if (v < 0) propagate(infoHi, infoLo)
3949+
else range(tp.bottomType, tp.topType)
3950+
case _ =>
3951+
propagate(infoLo, infoHi)
3952+
}
39403953
case _ =>
3941-
tp.derivedRefinedType(parent, tp.refinedName, rangeToBounds(info))
3954+
tp.derivedRefinedType(parent, tp.refinedName, info)
39423955
}
3943-
}
3956+
}
39443957

39453958
override protected def derivedRecType(tp: RecType, parent: Type) =
39463959
parent match {
@@ -3971,7 +3984,7 @@ object Types {
39713984
case Range(tyconLo, tyconHi) =>
39723985
range(derivedAppliedType(tp, tyconLo, args), derivedAppliedType(tp, tyconHi, args))
39733986
case _ =>
3974-
if (args.exists(isRange))
3987+
if (args.exists(isRange)) {
39753988
if (variance > 0) tp.derivedAppliedType(tycon, args.map(rangeToBounds))
39763989
else {
39773990
val loBuf, hiBuf = new mutable.ListBuffer[Type]
@@ -3993,6 +4006,7 @@ object Types {
39934006
tp.derivedAppliedType(tycon, hiBuf.toList))
39944007
else range(tp.bottomType, tp.topType)
39954008
}
4009+
}
39964010
else tp.derivedAppliedType(tycon, args)
39974011
}
39984012

0 commit comments

Comments
 (0)