Skip to content

Commit 534ea85

Browse files
committed
Refine derivedRefinedType
1 parent 815f27e commit 534ea85

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

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

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

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

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

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

39473960
override protected def derivedRecType(tp: RecType, parent: Type) =
39483961
parent match {
@@ -3973,7 +3986,7 @@ object Types {
39733986
case Range(tyconLo, tyconHi) =>
39743987
range(derivedAppliedType(tp, tyconLo, args), derivedAppliedType(tp, tyconHi, args))
39753988
case _ =>
3976-
if (args.exists(isRange))
3989+
if (args.exists(isRange)) {
39773990
if (variance > 0) tp.derivedAppliedType(tycon, args.map(rangeToBounds))
39783991
else {
39793992
val loBuf, hiBuf = new mutable.ListBuffer[Type]
@@ -3995,6 +4008,7 @@ object Types {
39954008
tp.derivedAppliedType(tycon, hiBuf.toList))
39964009
else range(tp.bottomType, tp.topType)
39974010
}
4011+
}
39984012
else tp.derivedAppliedType(tycon, args)
39994013
}
40004014

0 commit comments

Comments
 (0)