Skip to content

Commit

Permalink
Partial revert of scala#13780
Browse files Browse the repository at this point in the history
scala#13780 caused several regressions and I think it is too restrictive as a fix.
I am reverting it an re-opening the original scala#11982 issue.

It would be good to get to the bottom of what the soundness problem hinted at
in scala#11982 is, and what a fix should be. As it stands scala#11982 is not obviously
a soundness problem but a separate compilation problem.
  • Loading branch information
odersky committed May 31, 2022
1 parent 77bcd0d commit 427310b
Show file tree
Hide file tree
Showing 9 changed files with 14 additions and 56 deletions.
9 changes: 2 additions & 7 deletions compiler/src/dotty/tools/dotc/core/TypeComparer.scala
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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
Expand Down
1 change: 1 addition & 0 deletions compiler/test/dotc/pos-test-pickling.blacklist
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ i9999.scala
13491.scala
7512.scala
i6505.scala
i15155.scala

# Opaque type
i5720.scala
Expand Down
1 change: 0 additions & 1 deletion compiler/test/dotty/tools/dotc/CompilationTests.scala
Original file line number Diff line number Diff line change
Expand Up @@ -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"),
Expand Down
12 changes: 6 additions & 6 deletions tests/neg/11982.scala
Original file line number Diff line number Diff line change
Expand Up @@ -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
}


Expand All @@ -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
}


Expand All @@ -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
}
16 changes: 1 addition & 15 deletions tests/neg/6570-1.scala
Original file line number Diff line number Diff line change
Expand Up @@ -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 =
Expand Down
6 changes: 3 additions & 3 deletions tests/neg/6570.scala
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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 }
Expand Down Expand Up @@ -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]
Expand Down
11 changes: 0 additions & 11 deletions tests/neg/i15155.check

This file was deleted.

2 changes: 1 addition & 1 deletion tests/neg/i15155.scala → tests/pos/i15155.scala
Original file line number Diff line number Diff line change
Expand Up @@ -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]]
}
Original file line number Diff line number Diff line change
Expand Up @@ -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
// }
// }

0 comments on commit 427310b

Please sign in to comment.