From 0a2d995c9ac88ac045fd0f08cbddfd01f81f7150 Mon Sep 17 00:00:00 2001 From: odersky Date: Sat, 6 Jan 2024 13:12:56 +0100 Subject: [PATCH 1/2] Also reduce term projections 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. --- .../src/dotty/tools/dotc/core/Types.scala | 22 ++++++++++--------- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/compiler/src/dotty/tools/dotc/core/Types.scala b/compiler/src/dotty/tools/dotc/core/Types.scala index 78e22b7b76b9..5dede9080ecc 100644 --- a/compiler/src/dotty/tools/dotc/core/Types.scala +++ b/compiler/src/dotty/tools/dotc/core/Types.scala @@ -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) } @@ -2676,7 +2678,7 @@ object Types extends TypeUtils { * refinement type `T { X = U; ... }` */ def reduceProjection(using Context): Type = - if (isType) { + if (isType || true) { val reduced = prefix.lookupRefined(name) if (reduced.exists) reduced else this } @@ -2765,14 +2767,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 => @@ -6563,7 +6565,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) @@ -6592,8 +6594,8 @@ object Types extends TypeUtils { variance = saved this(y, restpe) - case tp: TermRef => - if stopBecauseStaticOrLocal(tp) then x else applyToPrefix(x, tp) + //case tp: TermRef => + // if stopBecauseStaticOrLocal(tp) then x else applyToPrefix(x, tp) case tp: TypeVar => this(x, tp.underlying) From daa29e6c5750b93baa602b48eba555a88ac5ba0f Mon Sep 17 00:00:00 2001 From: odersky Date: Fri, 16 Feb 2024 19:41:20 +0100 Subject: [PATCH 2/2] Simplifty code, addressing review comments --- compiler/src/dotty/tools/dotc/core/Types.scala | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/compiler/src/dotty/tools/dotc/core/Types.scala b/compiler/src/dotty/tools/dotc/core/Types.scala index 5dede9080ecc..2b1f6394acdc 100644 --- a/compiler/src/dotty/tools/dotc/core/Types.scala +++ b/compiler/src/dotty/tools/dotc/core/Types.scala @@ -2678,11 +2678,8 @@ object Types extends TypeUtils { * refinement type `T { X = U; ... }` */ def reduceProjection(using Context): Type = - if (isType || true) { - 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 @@ -6594,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)