Skip to content

Commit

Permalink
Backport recent exhaustivity fixes (#16578)
Browse files Browse the repository at this point in the history
Backports #16051 and #16168
  • Loading branch information
Kordyjan authored Dec 22, 2022
2 parents 6059da4 + 99ba2a3 commit 7fe6b8b
Show file tree
Hide file tree
Showing 8 changed files with 79 additions and 0 deletions.
4 changes: 4 additions & 0 deletions compiler/src/dotty/tools/dotc/core/TypeOps.scala
Original file line number Diff line number Diff line change
Expand Up @@ -869,6 +869,10 @@ object TypeOps:
}

def instantiate(): Type = {
// if there's a change in variance in type parameters (between subtype tp1 and supertype tp2)
// then we don't want to maximise the type variables in the wrong direction.
// For instance 15967, A[-Z] and B[Y] extends A[Y], we don't want to maximise Y to Any
maximizeType(protoTp1.baseType(tp2.classSymbol), NoSpan)
maximizeType(protoTp1, NoSpan)
wildApprox(protoTp1)
}
Expand Down
1 change: 1 addition & 0 deletions compiler/src/dotty/tools/dotc/transform/patmat/Space.scala
Original file line number Diff line number Diff line change
Expand Up @@ -306,6 +306,7 @@ object SpaceEngine {
val isEmptyTp = extractorMemberType(unappResult, nme.isEmpty, NoSourcePosition)
isEmptyTp <:< ConstantType(Constant(false))
}
|| unappResult.derivesFrom(defn.NonEmptyTupleClass)
}

/** Is the unapply or unapplySeq irrefutable?
Expand Down
20 changes: 20 additions & 0 deletions tests/neg/i15991.abstract.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
object Foo:
def unapply[T <: Tuple](tup: T): String *: String *: T =
"a" *: "b" *: tup

// like {pos,neg}/i15991, but with an abstract tuple tail
class Test:
val tup2: String *: String *: EmptyTuple = ("c", "d")

def test3 =
val Foo(x, y, z) = tup2 // error: Wrong number of argument patterns for Foo; expected: (String, String, String, String)
x + y + z

def test3a =
val x1x = tup2 match
case Foo(x, y, z) => // error: Wrong number of argument patterns for Foo; expected: (String, String, String, String)
(x, y, z)
val x = x1x._1
val y = x1x._2
val z = x1x._3
x + y + z
7 changes: 7 additions & 0 deletions tests/neg/i15991.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
object Foo:
def unapply(x: Any): String *: String *: EmptyTuple = ("a", "b")

class Test:
def test =
val Foo(x, y, z) = 1 // error: Wrong number of argument patterns for Foo; expected: (String, String)
x + y + z
10 changes: 10 additions & 0 deletions tests/pos/i15967.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
// scalac: -Werror
sealed trait A[-Z]
final case class B[Y]() extends A[Y]

class Test:
def t1[X](a: A[X]) = a match // was inexhaustive
case _: B[X] @unchecked =>

//def t2[X](a: A[X]) = a match // was inexhaustive
// case _: B[X] => // expected unchecked warning
20 changes: 20 additions & 0 deletions tests/pos/i15991.abstract.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
object Foo:
def unapply[T <: Tuple](tup: T): String *: String *: T =
"a" *: "b" *: tup

// like {pos,neg}/i15991, but with an abstract tuple tail
class Test:
val tup2: String *: String *: EmptyTuple = ("c", "d")

def test2 =
val Foo(x, y, _, _) = tup2
x + y

// like test2, but as the desugaring of what PatternDef's become
def test2b =
val x1x = tup2 match
case Foo(x, y, _, _) =>
(x, y)
val x = x1x._1
val y = x1x._2
x + y
9 changes: 9 additions & 0 deletions tests/pos/i15991.orig.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
class Foo

object Foo:
// def unapply(f: Foo): (Int, Int) = ??? // does not raise a warning
def unapply(f: Foo): Int *: Int *: EmptyTuple = ???

@main def example =
val Foo(x, y) = new Foo
println(x)
8 changes: 8 additions & 0 deletions tests/pos/i15991.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
object Foo:
def unapply(x: Any): String *: String *: EmptyTuple =
("a", "b")

class Test:
def test =
val Foo(x, y) = 1
x + y

0 comments on commit 7fe6b8b

Please sign in to comment.