Skip to content

Commit

Permalink
Detail UnapplyInvalidReturnType error message (#17167)
Browse files Browse the repository at this point in the history
  • Loading branch information
mbovel authored May 11, 2023
2 parents c720e5a + 8f044bf commit 9642fb2
Show file tree
Hide file tree
Showing 3 changed files with 39 additions and 1 deletion.
6 changes: 5 additions & 1 deletion compiler/src/dotty/tools/dotc/reporting/messages.scala
Original file line number Diff line number Diff line change
Expand Up @@ -1981,7 +1981,11 @@ class UnapplyInvalidReturnType(unapplyResult: Type, unapplyName: Name)(using Con
|To be used as an extractor, an unapply method has to return a type that either:
| - has members ${Magenta("isEmpty: Boolean")} and ${Magenta("get: S")} (usually an ${Green("Option[S]")})
| - is a ${Green("Boolean")}
| - is a ${Green("Product")} (like a ${Magenta("Tuple2[T1, T2]")})
| - is a ${Green("Product")} (like a ${Magenta("Tuple2[T1, T2]")}) of arity i with i >= 1, and has members _1 to _i
|
|See: https://docs.scala-lang.org/scala3/reference/changed-features/pattern-matching.html#fixed-arity-extractors
|
|Examples:
|
|class A(val i: Int)
|
Expand Down
14 changes: 14 additions & 0 deletions tests/neg/17077.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
case class IsIntResult()

object IsInt:
def unapply(x: Int): IsIntResult = IsIntResult()

@main def test =
val v: String | Int = "Blop"
val res =
v match
case IsInt() => 43 // error: cannot use a product of arity zero as a return type for unapply
// see UnapplyInvalidReturnType in messages.scala
// and https://docs.scala-lang.org/scala3/reference/changed-features/pattern-matching.html#fixed-arity-extractors
case _ => 42
println(res)
20 changes: 20 additions & 0 deletions tests/pos/17077.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
class MyProduct extends Product:
def foo = ???
override def productArity: Int = 1
override def productElement(n: Int): Any = 42
override def canEqual(that: Any): Boolean = that.isInstanceOf[MyProduct]
def _1 = 42

object MyProductUnapply:
def unapply(x: Int): MyProduct = MyProduct()

@main def test =
val v: String | Int = "Blop"
val res =
v match
case MyProductUnapply(y) => y // works: a product of arity 1 is accepted as the return type of unapply
// see UnapplyInvalidReturnType in messages.scala
// and https://docs.scala-lang.org/scala3/reference/changed-features/pattern-matching.html#fixed-arity-extractors
case _ => 42
println(res)

0 comments on commit 9642fb2

Please sign in to comment.