Skip to content

Commit 008c824

Browse files
committed
Teach SpaceEngine that generic tuples are irrefutable
1 parent 684ae79 commit 008c824

File tree

5 files changed

+60
-0
lines changed

5 files changed

+60
-0
lines changed

compiler/src/dotty/tools/dotc/transform/patmat/Space.scala

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -306,6 +306,7 @@ object SpaceEngine {
306306
val isEmptyTp = extractorMemberType(unappResult, nme.isEmpty, NoSourcePosition)
307307
isEmptyTp <:< ConstantType(Constant(false))
308308
}
309+
|| unappResult.derivesFrom(defn.NonEmptyTupleClass)
309310
}
310311

311312
/** Is the unapply or unapplySeq irrefutable?

tests/neg/i15991.abstract.scala

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
object Foo:
2+
def unapply[T <: Tuple](tup: T): String *: String *: T =
3+
"a" *: "b" *: tup
4+
5+
// like {pos,neg}/i15991, but with an abstract tuple tail
6+
class Test:
7+
val tup2: String *: String *: EmptyTuple = ("c", "d")
8+
9+
def test2 =
10+
val Foo(x, y, _, _) = tup2 // error: Wrong number of argument patterns for Foo; expected: (String, String)
11+
// but really it should work
12+
x + y
13+
14+
// like test2, but as the desugaring of what PatternDef's become
15+
def test2b =
16+
val x1x = tup2 match
17+
case Foo(x, y, _, _) => // error: Wrong number of argument patterns for Foo; expected: (String, String)
18+
// but really it should work
19+
(x, y)
20+
val x = x1x._1
21+
val y = x1x._2
22+
x + y
23+
24+
def test3 =
25+
val Foo(x, y, z) = tup2 // error: Wrong number of argument patterns for Foo; expected: (String, String)
26+
x + y + z
27+
28+
def test3a =
29+
val x1x = tup2 match
30+
case Foo(x, y, z) => // error: Wrong number of argument patterns for Foo; expected: (String, String)
31+
(x, y)
32+
val x = x1x._1
33+
val y = x1x._2
34+
val z = x1x._3
35+
x + y + z

tests/neg/i15991.scala

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
object Foo:
2+
def unapply(x: Any): String *: String *: EmptyTuple = ("a", "b")
3+
4+
class Test:
5+
def test =
6+
val Foo(x, y, z) = 1 // error: Wrong number of argument patterns for Foo; expected: (String, String)
7+
x + y + z

tests/pos/i15991.orig.scala

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
class Foo
2+
3+
object Foo:
4+
// def unapply(f: Foo): (Int, Int) = ??? // does not raise a warning
5+
def unapply(f: Foo): Int *: Int *: EmptyTuple = ???
6+
7+
@main def example =
8+
val Foo(x, y) = new Foo
9+
println(x)

tests/pos/i15991.scala

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
object Foo:
2+
def unapply(x: Any): String *: String *: EmptyTuple =
3+
("a", "b")
4+
5+
class Test:
6+
def test =
7+
val Foo(x, y) = 1
8+
x + y

0 commit comments

Comments
 (0)