From 9f588ad2c0b9f2c50b7d0fbbecfd936ced48c38d Mon Sep 17 00:00:00 2001 From: odersky Date: Tue, 31 May 2022 14:49:57 +0200 Subject: [PATCH] Partial revert of #13780 #13780 caused several regressions and I think it is too restrictive as a fix. I am reverting it an re-opening the original #11982 issue. It would be good to get to the bottom of what the soundness problem hinted at in #11982 is, and what a fix should be. As it stands #11982 is not obviously a soundness problem but a separate compilation problem. --- .../src/dotty/tools/dotc/core/TypeComparer.scala | 9 ++------- compiler/test/dotc/pos-test-pickling.blacklist | 1 + .../test/dotty/tools/dotc/CompilationTests.scala | 1 - tests/neg/11982.scala | 12 ++++++------ tests/neg/6570-1.scala | 16 +--------------- tests/neg/6570.scala | 6 +++--- tests/neg/i15155.check | 11 ----------- tests/{neg => pos}/i15155.scala | 2 +- .../typeclass-derivation1.scala | 12 ------------ 9 files changed, 14 insertions(+), 56 deletions(-) delete mode 100644 tests/neg/i15155.check rename tests/{neg => pos}/i15155.scala (89%) rename tests/{run-custom-args => run}/typeclass-derivation1.scala (89%) diff --git a/compiler/src/dotty/tools/dotc/core/TypeComparer.scala b/compiler/src/dotty/tools/dotc/core/TypeComparer.scala index 2ddf22d8db71..134a5006b887 100644 --- a/compiler/src/dotty/tools/dotc/core/TypeComparer.scala +++ b/compiler/src/dotty/tools/dotc/core/TypeComparer.scala @@ -756,13 +756,8 @@ class TypeComparer(@constructorOnly initctx: Context) extends ConstraintHandling } def tryBaseType(cls2: Symbol) = { - val allowBaseType = !caseLambda.exists || (tp1 match { - case tp: TypeRef if tp.symbol.isClass => true - case AppliedType(tycon: TypeRef, _) if tycon.symbol.isClass => true - case _ => false - }) val base = nonExprBaseType(tp1, cls2) - if (base.exists && base.ne(tp1) && allowBaseType) + if (base.exists && (base `ne` tp1)) isSubType(base, tp2, if (tp1.isRef(cls2)) approx else approx.addLow) || base.isInstanceOf[OrType] && fourthTry // if base is a disjunction, this might have come from a tp1 type that @@ -781,7 +776,7 @@ class TypeComparer(@constructorOnly initctx: Context) extends ConstraintHandling || narrowGADTBounds(tp1, tp2, approx, isUpper = true)) && (tp2.isAny || GADTusage(tp1.symbol)) - !caseLambda.exists && isSubType(hi1, tp2, approx.addLow) || compareGADT || tryLiftedToThis1 + isSubType(hi1, tp2, approx.addLow) || compareGADT || tryLiftedToThis1 case _ => // `Mode.RelaxedOverriding` is only enabled when checking Java overriding // in explicit nulls, and `Null` becomes a bottom type, which allows diff --git a/compiler/test/dotc/pos-test-pickling.blacklist b/compiler/test/dotc/pos-test-pickling.blacklist index e31b370d5b90..7ddceab60aa3 100644 --- a/compiler/test/dotc/pos-test-pickling.blacklist +++ b/compiler/test/dotc/pos-test-pickling.blacklist @@ -43,6 +43,7 @@ i9999.scala 7512.scala i6505.scala i15158.scala +i15155.scala # Opaque type i5720.scala diff --git a/compiler/test/dotty/tools/dotc/CompilationTests.scala b/compiler/test/dotty/tools/dotc/CompilationTests.scala index dd1213514d82..6ad524e07930 100644 --- a/compiler/test/dotty/tools/dotc/CompilationTests.scala +++ b/compiler/test/dotty/tools/dotc/CompilationTests.scala @@ -200,7 +200,6 @@ class CompilationTests { @Test def runAll: Unit = { implicit val testGroup: TestGroup = TestGroup("runAll") aggregateTests( - compileFile("tests/run-custom-args/typeclass-derivation1.scala", defaultOptions.without(yCheckOptions: _*)), compileFile("tests/run-custom-args/tuple-cons.scala", allowDeepSubtypes), compileFile("tests/run-custom-args/i5256.scala", allowDeepSubtypes), compileFile("tests/run-custom-args/no-useless-forwarders.scala", defaultOptions and "-Xmixin-force-forwarders:false"), diff --git a/tests/neg/11982.scala b/tests/neg/11982.scala index dd7a2b9b055e..1f50ab2dfe4f 100644 --- a/tests/neg/11982.scala +++ b/tests/neg/11982.scala @@ -4,8 +4,8 @@ type Head[X] = X match { } object Unpair { - def unpair[X <: Tuple2[Any, Any]]: Head[X] = 1 // error - unpair[Tuple2["msg", 42]]: "msg" + def unpair[X <: Tuple2[Any, Any]]: Head[X] = 1 + unpair[Tuple2["msg", 42]]: "msg" // error } @@ -14,8 +14,8 @@ type Head2[X] = X match { } object Unpair2 { - def unpair[X <: Tuple2[Tuple2[Any, Any], Tuple2[Any, Any]]]: Head2[X] = 1 // error - unpair[Tuple2[Tuple2["msg", 42], Tuple2[41, 40]]]: "msg" + def unpair[X <: Tuple2[Tuple2[Any, Any], Tuple2[Any, Any]]]: Head2[X] = 1 + unpair[Tuple2[Tuple2["msg", 42], Tuple2[41, 40]]]: "msg" // error } @@ -35,6 +35,6 @@ type Head4[X] = X match { } object Unpair4 { - def unpair[X <: Foo[Any, Any]]: Head4[Foo[X, X]] = 1 // error - unpair[Foo["msg", 42]]: "msg" + def unpair[X <: Foo[Any, Any]]: Head4[Foo[X, X]] = 1 + unpair[Foo["msg", 42]]: "msg" // error } diff --git a/tests/neg/6570-1.scala b/tests/neg/6570-1.scala index 417f4e477779..b24d09782039 100644 --- a/tests/neg/6570-1.scala +++ b/tests/neg/6570-1.scala @@ -33,21 +33,7 @@ class Asploder extends Root[Cov[Box[Int & String]]] { } object Main { - def foo[T <: Cov[Box[Int]]](c: Root[T]): Trait2 = c.thing // error - // ^^^^^^^ - // Found: M[T] - // Required: Trait2 - // - // where: T is a type in method foo with bounds <: Cov[Box[Int]] - // - // - // Note: a match type could not be fully reduced: - // - // trying to reduce M[T] - // failed since selector T - // does not match case Cov[x] => N[x] - // and cannot be shown to be disjoint from it either. - + def foo[T <: Cov[Box[Int]]](c: Root[T]): Trait2 = c.thing def explode = foo(new Asploder) def main(args: Array[String]): Unit = diff --git a/tests/neg/6570.scala b/tests/neg/6570.scala index f90c9b65014b..d0b55fe739de 100644 --- a/tests/neg/6570.scala +++ b/tests/neg/6570.scala @@ -21,7 +21,7 @@ object UpperBoundParametricVariant { trait Child[A <: Cov[Int]] extends Root[A] // we reduce `M[T]` to `Trait2`, even though we cannot be certain of that - def foo[T <: Cov[Int]](c: Child[T]): Trait2 = c.thing // error + def foo[T <: Cov[Int]](c: Child[T]): Trait2 = c.thing class Asploder extends Child[Cov[String & Int]] { def thing = new Trait1 {} // error @@ -42,7 +42,7 @@ object InheritanceVariant { trait Child extends Root { type B <: { type A <: Int } } - def foo(c: Child): Trait2 = c.thing // error + def foo(c: Child): Trait2 = c.thing class Asploder extends Child { type B = { type A = String & Int } @@ -98,7 +98,7 @@ object UpperBoundVariant { trait Child extends Root { type A <: Cov[Int] } - def foo(c: Child): Trait2 = c.thing // error + def foo(c: Child): Trait2 = c.thing class Asploder extends Child { type A = Cov[String & Int] diff --git a/tests/neg/i15155.check b/tests/neg/i15155.check deleted file mode 100644 index 5f24a6dc48a1..000000000000 --- a/tests/neg/i15155.check +++ /dev/null @@ -1,11 +0,0 @@ --- [E170] Type Error: tests/neg/i15155.scala:10:33 --------------------------------------------------------------------- -10 | val EnumerationClass = classOf[EnumValue[E]] // error - | ^^^^^^^^^^^^ - | EnumValue[E] is not a class type - | - | Note: a match type could not be fully reduced: - | - | trying to reduce EnumValue[E] - | failed since selector E - | does not match case Aux[a] => a - | and cannot be shown to be disjoint from it either. diff --git a/tests/neg/i15155.scala b/tests/pos/i15155.scala similarity index 89% rename from tests/neg/i15155.scala rename to tests/pos/i15155.scala index 083f199823fb..a00ca742b5d3 100644 --- a/tests/neg/i15155.scala +++ b/tests/pos/i15155.scala @@ -7,5 +7,5 @@ type EnumValue[A <: Enumeration] = A match { // https://github.com/json4s/json4s/blob/355d8751391773e0d79d04402a4f9fb7bfc684ec/ext/src/main/scala/org/json4s/ext/EnumSerializer.scala#L25-L26 class EnumSerializer[E <: Enumeration: ClassTag](enumeration: E) { - val EnumerationClass = classOf[EnumValue[E]] // error + val EnumerationClass = classOf[EnumValue[E]] } \ No newline at end of file diff --git a/tests/run-custom-args/typeclass-derivation1.scala b/tests/run/typeclass-derivation1.scala similarity index 89% rename from tests/run-custom-args/typeclass-derivation1.scala rename to tests/run/typeclass-derivation1.scala index f2fda59bd3de..f6c83c770af2 100644 --- a/tests/run-custom-args/typeclass-derivation1.scala +++ b/tests/run/typeclass-derivation1.scala @@ -96,15 +96,3 @@ object Test extends App { assert(!eq2.equals(yss, xss)) assert(eq2.equals(yss, yss)) } - -// -Ycheck failure minimized to: -// import scala.compiletime.* -// object Eq { -// inline def deriveForProduct[Elems <: Tuple](xs: Elems): Boolean = inline erasedValue[Elems] match { -// case _: (elem *: elems1) => -// val xs1 = xs.asInstanceOf[elem *: elems1] -// deriveForProduct(xs1.tail) -// case _: EmptyTuple => -// true -// } -// }