Skip to content

Commit 9642fb2

Browse files
authored
Detail UnapplyInvalidReturnType error message (#17167)
2 parents c720e5a + 8f044bf commit 9642fb2

File tree

3 files changed

+39
-1
lines changed

3 files changed

+39
-1
lines changed

compiler/src/dotty/tools/dotc/reporting/messages.scala

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1981,7 +1981,11 @@ class UnapplyInvalidReturnType(unapplyResult: Type, unapplyName: Name)(using Con
19811981
|To be used as an extractor, an unapply method has to return a type that either:
19821982
| - has members ${Magenta("isEmpty: Boolean")} and ${Magenta("get: S")} (usually an ${Green("Option[S]")})
19831983
| - is a ${Green("Boolean")}
1984-
| - is a ${Green("Product")} (like a ${Magenta("Tuple2[T1, T2]")})
1984+
| - is a ${Green("Product")} (like a ${Magenta("Tuple2[T1, T2]")}) of arity i with i >= 1, and has members _1 to _i
1985+
|
1986+
|See: https://docs.scala-lang.org/scala3/reference/changed-features/pattern-matching.html#fixed-arity-extractors
1987+
|
1988+
|Examples:
19851989
|
19861990
|class A(val i: Int)
19871991
|

tests/neg/17077.scala

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
case class IsIntResult()
2+
3+
object IsInt:
4+
def unapply(x: Int): IsIntResult = IsIntResult()
5+
6+
@main def test =
7+
val v: String | Int = "Blop"
8+
val res =
9+
v match
10+
case IsInt() => 43 // error: cannot use a product of arity zero as a return type for unapply
11+
// see UnapplyInvalidReturnType in messages.scala
12+
// and https://docs.scala-lang.org/scala3/reference/changed-features/pattern-matching.html#fixed-arity-extractors
13+
case _ => 42
14+
println(res)

tests/pos/17077.scala

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
class MyProduct extends Product:
2+
def foo = ???
3+
override def productArity: Int = 1
4+
override def productElement(n: Int): Any = 42
5+
override def canEqual(that: Any): Boolean = that.isInstanceOf[MyProduct]
6+
def _1 = 42
7+
8+
object MyProductUnapply:
9+
def unapply(x: Int): MyProduct = MyProduct()
10+
11+
@main def test =
12+
val v: String | Int = "Blop"
13+
val res =
14+
v match
15+
case MyProductUnapply(y) => y // works: a product of arity 1 is accepted as the return type of unapply
16+
// see UnapplyInvalidReturnType in messages.scala
17+
// and https://docs.scala-lang.org/scala3/reference/changed-features/pattern-matching.html#fixed-arity-extractors
18+
case _ => 42
19+
println(res)
20+

0 commit comments

Comments
 (0)