Skip to content

Commit 67314a6

Browse files
committed
Detail UnapplyInvalidReturnType error message
1 parent d640193 commit 67314a6

File tree

3 files changed

+41
-1
lines changed

3 files changed

+41
-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
@@ -1962,7 +1962,11 @@ class UnapplyInvalidReturnType(unapplyResult: Type, unapplyName: Name)(using Con
19621962
|To be used as an extractor, an unapply method has to return a type that either:
19631963
| - has members ${Magenta("isEmpty: Boolean")} and ${Magenta("get: S")} (usually an ${Green("Option[S]")})
19641964
| - is a ${Green("Boolean")}
1965-
| - is a ${Green("Product")} (like a ${Magenta("Tuple2[T1, T2]")})
1965+
| - is a ${Green("Product")} (like a ${Magenta("Tuple2[T1, T2]")}) of arity i with i >= 1, and has members _1 to _i
1966+
|
1967+
|See: https://docs.scala-lang.org/scala3/reference/changed-features/pattern-matching.html#fixed-arity-extractors
1968+
|
1969+
|Examples:
19661970
|
19671971
|class A(val i: Int)
19681972
|

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

0 commit comments

Comments
 (0)