diff --git a/src/dotty/tools/dotc/core/TypeComparer.scala b/src/dotty/tools/dotc/core/TypeComparer.scala index 0737249221f5..165b43479f9d 100644 --- a/src/dotty/tools/dotc/core/TypeComparer.scala +++ b/src/dotty/tools/dotc/core/TypeComparer.scala @@ -736,8 +736,12 @@ class TypeComparer(initctx: Context) extends DotClass { def fourthTry(tp1: Type, tp2: Type): Boolean = tp1 match { case tp1: TypeRef => tp1.info match { - case TypeBounds(lo1, hi1) => - isSubType(hi1, tp2) + case TypeBounds(lo1, hi1) => tp2 match { + case tp2: NamedType if tp1.name == tp2.name => + isSubType(tp1.info, tp2.info) + case _ => + isSubType(hi1, tp2) + } case _ => (tp1.symbol eq NothingClass) && tp2.isInstanceOf[ValueType] || (tp1.symbol eq NullClass) && tp2.dealias.typeSymbol.isNullableClass diff --git a/test/dotc/tests.scala b/test/dotc/tests.scala index c4b34e0e90b0..cca67d77ce47 100644 --- a/test/dotc/tests.scala +++ b/test/dotc/tests.scala @@ -52,6 +52,7 @@ class tests extends CompilerTest { @Test def pos_approximateUnion = compileFile(posDir, "approximateUnion", doErase) @Test def pos_tailcall = compileDir(posDir + "tailcall/", doErase) @Test def pos_nullarify = compileFile(posDir, "nullarify", "-Ycheck:nullarify" :: doErase) + @Test def pos_subtyping = compileFile(posDir, "subtyping", doErase) @Test def pos_all = compileFiles(posDir, twice) @Test def new_all = compileFiles(newDir, twice) diff --git a/tests/pos/subtyping.scala b/tests/pos/subtyping.scala new file mode 100644 index 000000000000..b78c029342d6 --- /dev/null +++ b/tests/pos/subtyping.scala @@ -0,0 +1,38 @@ +class C1 +class C2 extends C1 +class C3 extends C2 +class C4 extends C3 + +object Test { + val c11 : { type T >: C1 <: C1 } = ??? + val c21 : { type T >: C2 <: C1 } = ??? + val c22 : { type T >: C2 <: C2 } = ??? + val c31 : { type T >: C3 <: C1 } = ??? + val c32 : { type T >: C3 <: C2 } = ??? + val c33 : { type T >: C3 <: C3 } = ??? + val c41 : { type T >: C4 <: C1 } = ??? + val c42 : { type T >: C4 <: C2 } = ??? + val c43 : { type T >: C4 <: C3 } = ??? + val c44 : { type T >: C4 <: C4 } = ??? + + // Test DOT rule TDECL-<: + // This is different from scalac + def test_tdecl_lt_colon(): Unit = { + implicitly[c31.T <:< c41.T] + implicitly[c42.T <:< c41.T] + } + + // Test DOT rule TSEL-<: + def test_tsel_lt_colon(): Unit = { + implicitly[c42.T <:< c11.T] + implicitly[c42.T <:< c21.T] + implicitly[c42.T <:< c22.T] + } + + // Test DOT rule <:-TSEL + def test_lt_colon_tsel(): Unit = { + implicitly[c33.T <:< c32.T] + implicitly[c43.T <:< c32.T] + implicitly[c44.T <:< c32.T] + } +}