Skip to content

Commit

Permalink
Also reduce term projections (#19389)
Browse files Browse the repository at this point in the history
We already reduce `R { type A = T } # A` to `T` in most situations when
we create types. We now also reduce `R { val x: S } # x` to `S` if `S`
is a singleton type.

This will simplify types as we go to more term-dependent typing. As a
concrete benefit, it will avoid several test-pickling failures due to
pickling differences when using dependent types.
  • Loading branch information
odersky authored Feb 17, 2024
2 parents 5bd93b1 + daa29e6 commit 9e3ce5e
Showing 1 changed file with 11 additions and 15 deletions.
26 changes: 11 additions & 15 deletions compiler/src/dotty/tools/dotc/core/Types.scala
Original file line number Diff line number Diff line change
Expand Up @@ -1645,6 +1645,8 @@ object Types extends TypeUtils {
pre.refinedInfo match {
case tp: AliasingBounds =>
if (pre.refinedName ne name) loop(pre.parent) else tp.alias
case tp: SingletonType =>
if pre.refinedName ne name then loop(pre.parent) else tp
case _ =>
loop(pre.parent)
}
Expand Down Expand Up @@ -2676,11 +2678,8 @@ object Types extends TypeUtils {
* refinement type `T { X = U; ... }`
*/
def reduceProjection(using Context): Type =
if (isType) {
val reduced = prefix.lookupRefined(name)
if (reduced.exists) reduced else this
}
else this
val reduced = prefix.lookupRefined(name)
if reduced.exists then reduced else this

/** Guard against cycles that can arise if given `op`
* follows info. The problematic cases are a type alias to itself or
Expand Down Expand Up @@ -2765,14 +2764,14 @@ object Types extends TypeUtils {
* (S | T)#A --> S#A | T#A
*/
def derivedSelect(prefix: Type)(using Context): Type =
if (prefix eq this.prefix) this
else if (prefix.isExactlyNothing) prefix
if prefix eq this.prefix then this
else if prefix.isExactlyNothing then prefix
else {
val res =
if (isType && currentValidSymbol.isAllOf(ClassTypeParam)) argForParam(prefix)
else prefix.lookupRefined(name)
if (res.exists) return res
if (isType) {
val res =
if (currentValidSymbol.isAllOf(ClassTypeParam)) argForParam(prefix)
else prefix.lookupRefined(name)
if (res.exists) return res
if (Config.splitProjections)
prefix match {
case prefix: AndType =>
Expand Down Expand Up @@ -6563,7 +6562,7 @@ object Types extends TypeUtils {
record(s"foldOver $getClass")
record(s"foldOver total")
tp match {
case tp: TypeRef =>
case tp: NamedType =>
if stopBecauseStaticOrLocal(tp) then x
else
val tp1 = tp.prefix.lookupRefined(tp.name)
Expand Down Expand Up @@ -6592,9 +6591,6 @@ object Types extends TypeUtils {
variance = saved
this(y, restpe)

case tp: TermRef =>
if stopBecauseStaticOrLocal(tp) then x else applyToPrefix(x, tp)

case tp: TypeVar =>
this(x, tp.underlying)

Expand Down

0 comments on commit 9e3ce5e

Please sign in to comment.