summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/compiler/scala/tools/nsc/transform/patmat/ScalacPatternExpanders.scala11
-rw-r--r--test/files/neg/t4425b.check22
-rw-r--r--test/files/neg/t8127a.check4
-rw-r--r--test/files/neg/t8127a.scala12
-rw-r--r--test/files/neg/t8989.check4
-rw-r--r--test/files/neg/t8989.scala14
6 files changed, 59 insertions, 8 deletions
diff --git a/src/compiler/scala/tools/nsc/transform/patmat/ScalacPatternExpanders.scala b/src/compiler/scala/tools/nsc/transform/patmat/ScalacPatternExpanders.scala
index 55d4366a46..5678c53e78 100644
--- a/src/compiler/scala/tools/nsc/transform/patmat/ScalacPatternExpanders.scala
+++ b/src/compiler/scala/tools/nsc/transform/patmat/ScalacPatternExpanders.scala
@@ -74,11 +74,16 @@ trait ScalacPatternExpanders {
* Unfortunately the MethodType does not carry the information of whether
* it was unapplySeq, so we have to funnel that information in separately.
*/
- def unapplyMethodTypes(whole: Type, result: Type, isSeq: Boolean): Extractor = {
+ def unapplyMethodTypes(context: Context, whole: Type, result: Type, isSeq: Boolean): Extractor = {
if (result =:= BooleanTpe) newExtractor(whole, Nil, NoRepeated)
else {
val getResult = typeOfMemberNamedGet(result)
+ def noGetError() = {
+ val name = "unapply" + (if (isSeq) "Seq" else "")
+ context.error(context.tree.pos, s"The result type of an $name method must contain a member `get` to be used as an extractor pattern, no such member exists in ${result}")
+ }
val expanded = getResult match {
+ case global.NoType => noGetError(); Nil
case rawGet if !hasSelectors(rawGet) => rawGet :: Nil
case rawGet => typesOfSelectors(rawGet)
}
@@ -131,8 +136,8 @@ trait ScalacPatternExpanders {
val isUnapply = sel.symbol.name == nme.unapply
val extractor = sel.symbol.name match {
- case nme.unapply => unapplyMethodTypes(firstParamType(fn.tpe), sel.tpe, isSeq = false)
- case nme.unapplySeq => unapplyMethodTypes(firstParamType(fn.tpe), sel.tpe, isSeq = true)
+ case nme.unapply => unapplyMethodTypes(context, firstParamType(fn.tpe), sel.tpe, isSeq = false)
+ case nme.unapplySeq => unapplyMethodTypes(context, firstParamType(fn.tpe), sel.tpe, isSeq = true)
case _ => applyMethodTypes(fn.tpe)
}
diff --git a/test/files/neg/t4425b.check b/test/files/neg/t4425b.check
index 8418b4fd12..a204467586 100644
--- a/test/files/neg/t4425b.check
+++ b/test/files/neg/t4425b.check
@@ -22,16 +22,28 @@ t4425b.scala:10: error: object X is not a case class, nor does it have an unappl
Note: def unapply(x: String)(y: String): Nothing exists in object X, but it cannot be used as an extractor due to its second non-implicit parameter list
println((X: Any) match { case X(_, _) => "ok" ; case _ => "fail" })
^
-t4425b.scala:18: error: too many patterns for object X: expected 1, found 2
+t4425b.scala:18: error: The result type of an unapply method must contain a member `get` to be used as an extractor pattern, no such member exists in Nothing
+ println( "" match { case _ X _ => "ok" ; case _ => "fail" })
+ ^
+t4425b.scala:18: error: too many patterns for object X offering Boolean: expected 0, found 2
println( "" match { case _ X _ => "ok" ; case _ => "fail" })
^
-t4425b.scala:19: error: too many patterns for object X: expected 1, found 2
+t4425b.scala:19: error: The result type of an unapply method must contain a member `get` to be used as an extractor pattern, no such member exists in Nothing
+ println((X: Any) match { case _ X _ => "ok" ; case _ => "fail" })
+ ^
+t4425b.scala:19: error: too many patterns for object X offering Boolean: expected 0, found 2
println((X: Any) match { case _ X _ => "ok" ; case _ => "fail" })
^
-t4425b.scala:22: error: too many patterns for object X: expected 1, found 2
+t4425b.scala:20: error: The result type of an unapply method must contain a member `get` to be used as an extractor pattern, no such member exists in Nothing
+ println( "" match { case X(_) => "ok" ; case _ => "fail" })
+ ^
+t4425b.scala:21: error: The result type of an unapply method must contain a member `get` to be used as an extractor pattern, no such member exists in Nothing
+ println((X: Any) match { case X(_) => "ok" ; case _ => "fail" })
+ ^
+t4425b.scala:22: error: The result type of an unapply method must contain a member `get` to be used as an extractor pattern, no such member exists in Nothing
println( "" match { case X(_, _) => "ok" ; case _ => "fail" })
^
-t4425b.scala:23: error: too many patterns for object X: expected 1, found 2
+t4425b.scala:23: error: The result type of an unapply method must contain a member `get` to be used as an extractor pattern, no such member exists in Nothing
println((X: Any) match { case X(_, _) => "ok" ; case _ => "fail" })
^
t4425b.scala:31: error: too many patterns for object X offering Nothing: expected 1, found 2
@@ -46,4 +58,4 @@ t4425b.scala:35: error: too many patterns for object X offering Nothing: expecte
t4425b.scala:36: error: too many patterns for object X offering Nothing: expected 1, found 2
println((X: Any) match { case X(_, _) => "ok" ; case _ => "fail" })
^
-14 errors found
+18 errors found
diff --git a/test/files/neg/t8127a.check b/test/files/neg/t8127a.check
new file mode 100644
index 0000000000..5a30574861
--- /dev/null
+++ b/test/files/neg/t8127a.check
@@ -0,0 +1,4 @@
+t8127a.scala:7: error: The result type of an unapplySeq method must contain a member `get` to be used as an extractor pattern, no such member exists in Seq[_$1]
+ case H(v) =>
+ ^
+one error found
diff --git a/test/files/neg/t8127a.scala b/test/files/neg/t8127a.scala
new file mode 100644
index 0000000000..c05facdac1
--- /dev/null
+++ b/test/files/neg/t8127a.scala
@@ -0,0 +1,12 @@
+object H {
+ def unapplySeq(m: Any): Seq[_] = List("")
+}
+
+object Test {
+ def unapply(m: Any) = m match {
+ case H(v) =>
+ case _ =>
+ }
+ // now: too many patterns for object H offering Boolean: expected 0, found 1
+ // was: result type Seq[_$2] of unapplySeq defined in method unapplySeq in object H does not conform to Option[_]
+}
diff --git a/test/files/neg/t8989.check b/test/files/neg/t8989.check
new file mode 100644
index 0000000000..4e89b862bd
--- /dev/null
+++ b/test/files/neg/t8989.check
@@ -0,0 +1,4 @@
+t8989.scala:11: error: The result type of an unapply method must contain a member `get` to be used as an extractor pattern, no such member exists in A
+ val f = p match {case d(1) => true; case _ => false}
+ ^
+one error found
diff --git a/test/files/neg/t8989.scala b/test/files/neg/t8989.scala
new file mode 100644
index 0000000000..8ed6a901cd
--- /dev/null
+++ b/test/files/neg/t8989.scala
@@ -0,0 +1,14 @@
+class A extends Product1[Int] {
+ def _1 = 1
+ def isEmpty = false // used by scalac
+ def isDefined = !isEmpty // used by dotty
+ def canEqual(a: Any) = true
+}
+
+object d{
+ def unapply(a: Any) = new A
+ val p: Any = ???
+ val f = p match {case d(1) => true; case _ => false}
+}
+
+