From a2685577fbe748bd5f47b0acc3cc30a19b2e716a Mon Sep 17 00:00:00 2001 From: Martin Odersky Date: Tue, 20 Apr 2021 11:05:37 +0200 Subject: [PATCH 1/3] Make transluctentSuperType handle match types This fixes several erasure related things, such as signature, or erasure itself. Fixes #8666 --- compiler/src/dotty/tools/dotc/core/Types.scala | 2 +- tests/pos/i8666.scala | 10 ++++++++++ 2 files changed, 11 insertions(+), 1 deletion(-) create mode 100644 tests/pos/i8666.scala diff --git a/compiler/src/dotty/tools/dotc/core/Types.scala b/compiler/src/dotty/tools/dotc/core/Types.scala index 878220cd85d5..9955abad4bf9 100644 --- a/compiler/src/dotty/tools/dotc/core/Types.scala +++ b/compiler/src/dotty/tools/dotc/core/Types.scala @@ -4011,7 +4011,7 @@ object Types { case tycon: TypeRef if tycon.symbol.isOpaqueAlias => tycon.translucentSuperType.applyIfParameterized(args) case _ => - superType + tryNormalize.orElse(superType) } inline def map(inline op: Type => Type)(using Context) = diff --git a/tests/pos/i8666.scala b/tests/pos/i8666.scala new file mode 100644 index 000000000000..307a4617b172 --- /dev/null +++ b/tests/pos/i8666.scala @@ -0,0 +1,10 @@ +class Foo[A, B]() + +type FooSnd[X] = X match + case Foo[_, b] => b + +trait Bar[A]: + def bar(h: FooSnd[A]): Int + +val foo: Bar[Foo[String, Int]] = new Bar[Foo[String, Int]]: + def bar(h: FooSnd[Foo[String, Int]]) = h From 351e909bb894026c99d2d2ff237010fb16285c8c Mon Sep 17 00:00:00 2001 From: Martin Odersky Date: Tue, 20 Apr 2021 11:29:26 +0200 Subject: [PATCH 2/3] Additional test case --- tests/pos/i7894.scala | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) create mode 100644 tests/pos/i7894.scala diff --git a/tests/pos/i7894.scala b/tests/pos/i7894.scala new file mode 100644 index 000000000000..74cd3e3cb247 --- /dev/null +++ b/tests/pos/i7894.scala @@ -0,0 +1,16 @@ +case class Box[T](t: T) + +type Boxed[T <: Tuple] <: Tuple = T match { + case EmptyTuple => EmptyTuple + case h *: t => Box[h] *: Boxed[t] +} + +trait Cmp[T <: Tuple] { def cmp(t: T, b: Boxed[T]): Boolean } + +object UnitCmp extends Cmp[EmptyTuple] { + def cmp(t: EmptyTuple, b: EmptyTuple): Boolean = true +} + +object UnitCmp2 extends Cmp[EmptyTuple] { + def cmp(t: EmptyTuple, b: Boxed[EmptyTuple]): Boolean = true +} From 71bac46255857a16f75af3904c700b0bf92e9af5 Mon Sep 17 00:00:00 2001 From: Martin Odersky Date: Tue, 20 Apr 2021 13:04:40 +0200 Subject: [PATCH 3/3] Improve comments --- compiler/src/dotty/tools/dotc/core/Types.scala | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/compiler/src/dotty/tools/dotc/core/Types.scala b/compiler/src/dotty/tools/dotc/core/Types.scala index 9955abad4bf9..ad0f07a5ac50 100644 --- a/compiler/src/dotty/tools/dotc/core/Types.scala +++ b/compiler/src/dotty/tools/dotc/core/Types.scala @@ -1888,7 +1888,15 @@ object Types { case st => st } - /** Same as superType, except that opaque types are treated as transparent aliases */ + /** Same as superType, except for two differences: + * - opaque types are treated as transparent aliases + * - applied type are matchtype-reduced if possible + * + * Note: the reason to reduce match type aliases here and not in `superType` + * is that `superType` is context-independent and cached, whereas matchtype + * reduction depends on context and should not be cached (at least not without + * the very specific cache invalidation condition for matchtypes). + */ def translucentSuperType(using Context): Type = superType }