From 1445481bbd0a8d171d44aced80e746a758926d23 Mon Sep 17 00:00:00 2001 From: Martin Odersky Date: Wed, 1 Nov 2017 18:24:50 +0100 Subject: [PATCH] Fix #3422: Add missing case to TypeComparer We missed the case where we compare two hk tpes A <: B, where both A and B refer to classes with type parameters. It seems this case usually does not arise when we compile from source because A or B or both are eta expanded. But it can arise after unpickling. --- .../dotty/tools/dotc/core/TypeComparer.scala | 18 +++++++++++------- tests/pos/i3422/a_1.scala | 9 +++++++++ tests/pos/i3422/b_2.scala | 3 +++ 3 files changed, 23 insertions(+), 7 deletions(-) create mode 100644 tests/pos/i3422/a_1.scala create mode 100644 tests/pos/i3422/b_2.scala diff --git a/compiler/src/dotty/tools/dotc/core/TypeComparer.scala b/compiler/src/dotty/tools/dotc/core/TypeComparer.scala index 7ce696d5412c..7df64bab906a 100644 --- a/compiler/src/dotty/tools/dotc/core/TypeComparer.scala +++ b/compiler/src/dotty/tools/dotc/core/TypeComparer.scala @@ -369,14 +369,18 @@ class TypeComparer(initctx: Context) extends DotClass with ConstraintHandling { case _ => val cls2 = tp2.symbol if (cls2.isClass) { - val base = tp1.baseType(cls2) - if (base.exists) { - if (cls2.is(JavaDefined)) - // If `cls2` is parameterized, we are seeing a raw type, so we need to compare only the symbol - return base.typeSymbol == cls2 - if (base ne tp1) return isSubType(base, tp2) + if (cls2.typeParams.nonEmpty && tp1.isHK) + isSubType(tp1, EtaExpansion(cls2.typeRef)) + else { + val base = tp1.baseType(cls2) + if (base.exists) { + if (cls2.is(JavaDefined)) + // If `cls2` is parameterized, we are seeing a raw type, so we need to compare only the symbol + return base.typeSymbol == cls2 + if (base ne tp1) return isSubType(base, tp2) + } + if (cls2 == defn.SingletonClass && tp1.isStable) return true } - if (cls2 == defn.SingletonClass && tp1.isStable) return true } fourthTry(tp1, tp2) } diff --git a/tests/pos/i3422/a_1.scala b/tests/pos/i3422/a_1.scala new file mode 100644 index 000000000000..6d3de22b2fee --- /dev/null +++ b/tests/pos/i3422/a_1.scala @@ -0,0 +1,9 @@ +trait Fun[L[_]] + +object O1 { + trait N[X] +} + +object O2 { + def bar: Fun[O1.N] = ??? +} diff --git a/tests/pos/i3422/b_2.scala b/tests/pos/i3422/b_2.scala new file mode 100644 index 000000000000..9123a643121a --- /dev/null +++ b/tests/pos/i3422/b_2.scala @@ -0,0 +1,3 @@ +object Test { + def c: Fun[O1.N] = O2.bar +}