Skip to content

Commit 3922954

Browse files
committed
Refine derivedRefinedType
1 parent 135be6b commit 3922954

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
@@ -3885,19 +3885,19 @@ object Types {
38853885
else if (variance < 0) lo
38863886
else Range(lower(lo), upper(hi))
38873887

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

3890-
private def lower(tp: Type) = tp match {
3890+
protected def lower(tp: Type) = tp match {
38913891
case tp: Range => tp.lo
38923892
case _ => tp
38933893
}
38943894

3895-
private def upper(tp: Type) = tp match {
3895+
protected def upper(tp: Type) = tp match {
38963896
case tp: Range => tp.hi
38973897
case _ => tp
38983898
}
38993899

3900-
private def rangeToBounds(tp: Type) = tp match {
3900+
protected def rangeToBounds(tp: Type) = tp match {
39013901
case Range(lo, hi) => TypeBounds(lo, hi)
39023902
case _ => tp
39033903
}
@@ -3908,11 +3908,14 @@ object Types {
39083908
try op finally variance = saved
39093909
}
39103910

3911+
/** Derived selection.
3912+
* @pre the (upper bound of) prefix `pre` has a member named `tp.name`.
3913+
*/
39113914
override protected def derivedSelect(tp: NamedType, pre: Type) =
39123915
if (pre eq tp.prefix) tp
39133916
else pre match {
39143917
case Range(preLo, preHi) =>
3915-
preHi.member(tp.name).info match {
3918+
preHi.member(tp.name).info.widenExpr match {
39163919
case TypeAlias(alias) =>
39173920
// if H#T = U, then for any x in L..H, x.T =:= U,
39183921
// hence we can replace with U under all variances
@@ -3938,12 +3941,22 @@ object Types {
39383941
case _ =>
39393942
if (parent.isBottomType) parent
39403943
else info match {
3941-
case Range(infoLo, infoHi) if tp.refinedName.isTermName || variance <= 0 =>
3942-
range(derivedRefinedType(tp, parent, infoLo), derivedRefinedType(tp, parent, infoHi))
3944+
case Range(infoLo, infoHi) =>
3945+
def propagate(lo: Type, hi: Type) =
3946+
range(derivedRefinedType(tp, parent, lo), derivedRefinedType(tp, parent, hi))
3947+
tp.refinedInfo match {
3948+
case rinfo: TypeBounds =>
3949+
val v = if (rinfo.isAlias) rinfo.variance * variance else variance
3950+
if (v > 0) tp.derivedRefinedType(parent, tp.refinedName, rangeToBounds(info))
3951+
else if (v < 0) propagate(infoHi, infoLo)
3952+
else range(tp.bottomType, tp.topType)
3953+
case _ =>
3954+
propagate(infoLo, infoHi)
3955+
}
39433956
case _ =>
3944-
tp.derivedRefinedType(parent, tp.refinedName, rangeToBounds(info))
3957+
tp.derivedRefinedType(parent, tp.refinedName, info)
39453958
}
3946-
}
3959+
}
39473960

39483961
override protected def derivedRecType(tp: RecType, parent: Type) =
39493962
parent match {
@@ -3974,7 +3987,7 @@ object Types {
39743987
case Range(tyconLo, tyconHi) =>
39753988
range(derivedAppliedType(tp, tyconLo, args), derivedAppliedType(tp, tyconHi, args))
39763989
case _ =>
3977-
if (args.exists(isRange))
3990+
if (args.exists(isRange)) {
39783991
if (variance > 0) tp.derivedAppliedType(tycon, args.map(rangeToBounds))
39793992
else {
39803993
val loBuf, hiBuf = new mutable.ListBuffer[Type]
@@ -3996,6 +4009,7 @@ object Types {
39964009
tp.derivedAppliedType(tycon, hiBuf.toList))
39974010
else range(tp.bottomType, tp.topType)
39984011
}
4012+
}
39994013
else tp.derivedAppliedType(tycon, args)
40004014
}
40014015

0 commit comments

Comments
 (0)