summaryrefslogtreecommitdiff
path: root/test/files
diff options
context:
space:
mode:
authorPaul Phillips <paulp@improving.org>2013-08-17 09:58:54 -0700
committerPaul Phillips <paulp@improving.org>2013-08-17 10:58:14 -0700
commit1cd7a9e840158dab17a3aafc0ce849605706a561 (patch)
tree3777a5c8bdfe0edcdcd45aa453d28704242a8702 /test/files
parent8f05647ca53da781b420be0723faf1cdbf14b2ff (diff)
downloadscala-1cd7a9e840158dab17a3aafc0ce849605706a561.tar.gz
scala-1cd7a9e840158dab17a3aafc0ce849605706a561.tar.bz2
scala-1cd7a9e840158dab17a3aafc0ce849605706a561.zip
New tests for name-based pattern matcher.
Diffstat (limited to 'test/files')
-rw-r--r--test/files/jvm/opt_value_class.check2
-rw-r--r--test/files/jvm/opt_value_class/Value_1.scala28
-rw-r--r--test/files/jvm/opt_value_class/test.scala16
-rw-r--r--test/files/neg/t7214neg.check7
-rw-r--r--test/files/neg/t7214neg.scala57
-rw-r--r--test/files/neg/t7721.check21
-rw-r--r--test/files/neg/t7721.flags1
-rw-r--r--test/files/neg/t7721.scala140
-rw-r--r--test/files/pos/extractor-types.scala30
-rw-r--r--test/files/pos/optmatch.scala33
-rw-r--r--test/files/pos/overloaded-unapply.scala8
-rw-r--r--test/files/run/name-based-patmat.check10
-rw-r--r--test/files/run/name-based-patmat.scala75
-rw-r--r--test/files/run/patmat-behavior-2.check24
-rw-r--r--test/files/run/patmat-behavior-2.scala50
-rw-r--r--test/files/run/patmat-behavior.check90
-rw-r--r--test/files/run/patmat-behavior.scala95
-rw-r--r--test/files/run/value-class-extractor-2.check8
-rw-r--r--test/files/run/value-class-extractor-2.scala108
-rw-r--r--test/files/run/value-class-extractor-seq.check3
-rw-r--r--test/files/run/value-class-extractor-seq.scala59
-rw-r--r--test/files/run/value-class-extractor.check9
-rw-r--r--test/files/run/value-class-extractor.scala91
23 files changed, 965 insertions, 0 deletions
diff --git a/test/files/jvm/opt_value_class.check b/test/files/jvm/opt_value_class.check
new file mode 100644
index 0000000000..a0c18c5ca0
--- /dev/null
+++ b/test/files/jvm/opt_value_class.check
@@ -0,0 +1,2 @@
+[ok] <init> ()V public
+[ok] unapply (Ljava/lang/Object;)Ljava/lang/String; public (Ljava/lang/Object;)Ljava/lang/String;
diff --git a/test/files/jvm/opt_value_class/Value_1.scala b/test/files/jvm/opt_value_class/Value_1.scala
new file mode 100644
index 0000000000..2440609b9e
--- /dev/null
+++ b/test/files/jvm/opt_value_class/Value_1.scala
@@ -0,0 +1,28 @@
+final class Opt[+A >: Null](val value: A) extends AnyVal {
+ def get: A = value
+ def isEmpty = value == null
+}
+object Opt {
+ final val None = new Opt[Null](null)
+ def unapply[A >: Null](x: A): Opt[A] = if (x == null) None else Opt(x)
+ def empty[A >: Null] = None
+ def apply[A >: Null](value: A): Opt[A] = if (value == null) None else new Opt[A](value)
+}
+
+class ValueExtract {
+ def unapply(x: Any): Opt[String] = x match {
+ case _: String => Opt("String")
+ case _: List[_] => Opt("List")
+ case _: Int => Opt("Int")
+ case _ => Opt.None
+ }
+}
+
+class Direct {
+ def unapply(x: Any): String = x match {
+ case _: String => "String"
+ case _: List[_] => "List"
+ case _: Int => "Int"
+ case _ => null
+ }
+}
diff --git a/test/files/jvm/opt_value_class/test.scala b/test/files/jvm/opt_value_class/test.scala
new file mode 100644
index 0000000000..7aea7deb99
--- /dev/null
+++ b/test/files/jvm/opt_value_class/test.scala
@@ -0,0 +1,16 @@
+import scala.tools.partest.BytecodeTest
+
+// import scala.tools.nsc.util.JavaClassPath
+// import java.io.InputStream
+// import scala.tools.asm
+// import asm.ClassReader
+// import asm.tree.{ClassNode, InsnList}
+// import scala.collection.JavaConverters._
+
+object Test extends BytecodeTest {
+ def show: Unit = {
+ val classNode1 = loadClassNode("ValueExtract")
+ val classNode2 = loadClassNode("Direct")
+ sameMethodAndFieldDescriptors(classNode1, classNode2)
+ }
+}
diff --git a/test/files/neg/t7214neg.check b/test/files/neg/t7214neg.check
new file mode 100644
index 0000000000..0660cccd02
--- /dev/null
+++ b/test/files/neg/t7214neg.check
@@ -0,0 +1,7 @@
+t7214neg.scala:28: error: wrong number of patterns for object Extractor offering Any: expected 1, found 0
+ case Extractor() =>
+ ^
+t7214neg.scala:28: error: wrong number of patterns for object Extractor offering Any: expected 1, found 0
+ case Extractor() =>
+ ^
+two errors found
diff --git a/test/files/neg/t7214neg.scala b/test/files/neg/t7214neg.scala
new file mode 100644
index 0000000000..ff1ea8082d
--- /dev/null
+++ b/test/files/neg/t7214neg.scala
@@ -0,0 +1,57 @@
+// pattern matcher crashes here trying to synthesize an uneeded outer test.
+// no-symbol does not have an owner
+// at scala.reflect.internal.SymbolTable.abort(SymbolTable.scala:49)
+// at scala.tools.nsc.Global.abort(Global.scala:253)
+// at scala.reflect.internal.Symbols$NoSymbol.owner(Symbols.scala:3248)
+// at scala.reflect.internal.Symbols$Symbol.effectiveOwner(Symbols.scala:678)
+// at scala.reflect.internal.Symbols$Symbol.isDefinedInPackage(Symbols.scala:664)
+// at scala.reflect.internal.TreeGen.mkAttributedSelect(TreeGen.scala:188)
+// at scala.reflect.internal.TreeGen.mkAttributedRef(TreeGen.scala:124)
+// at scala.tools.nsc.ast.TreeDSL$CODE$.REF(TreeDSL.scala:308)
+// at scala.tools.nsc.typechecker.PatternMatching$TreeMakers$TypeTestTreeMaker$treeCondStrategy$.outerTest(PatternMatching.scala:1209)
+class Crash {
+ type Alias = C#T
+
+ val c = new C
+ val t = new c.T
+
+ // Crash via a Typed Pattern...
+ (t: Any) match {
+ case e: Alias =>
+ }
+
+ // ... or via a Typed Extractor Pattern.
+ object Extractor {
+ def unapply(a: Alias): Option[Any] = None
+ }
+ (t: Any) match {
+ case Extractor() =>
+ case _ =>
+ }
+
+ // checking that correct outer tests are applied when
+ // aliases for path dependent types are involved.
+ val c2 = new C
+ type CdotT = c.T
+ type C2dotT = c2.T
+
+ val outerField = t.getClass.getDeclaredFields.find(_.getName contains ("outer")).get
+ outerField.setAccessible(true)
+
+ (t: Any) match {
+ case _: C2dotT =>
+ println(s"!!! wrong match. t.outer=${outerField.get(t)} / c2 = $c2") // this matches on 2.10.0
+ case _: CdotT =>
+ case _ =>
+ println(s"!!! wrong match. t.outer=${outerField.get(t)} / c = $c")
+ }
+}
+
+class C {
+ class T
+}
+
+object Test extends App {
+ new Crash
+}
+
diff --git a/test/files/neg/t7721.check b/test/files/neg/t7721.check
new file mode 100644
index 0000000000..e056b9a293
--- /dev/null
+++ b/test/files/neg/t7721.check
@@ -0,0 +1,21 @@
+t7721.scala:11: warning: abstract type pattern A.this.Foo is unchecked since it is eliminated by erasure
+ case x: Foo with Concrete => x.bippy + x.conco
+ ^
+t7721.scala:15: warning: abstract type pattern A.this.Foo is unchecked since it is eliminated by erasure
+ case x: Concrete with Foo => x.bippy + x.conco
+ ^
+t7721.scala:19: warning: abstract type pattern A.this.Foo is unchecked since it is eliminated by erasure
+ case x: Foo with Bar => x.bippy + x.barry
+ ^
+t7721.scala:39: warning: abstract type pattern B.this.Foo is unchecked since it is eliminated by erasure
+ case x: Foo with Concrete => x.bippy + x.dingo + x.conco
+ ^
+t7721.scala:43: warning: abstract type pattern B.this.Foo is unchecked since it is eliminated by erasure
+ case x: Concrete with Foo => x.bippy + x.dingo + x.conco
+ ^
+t7721.scala:47: warning: abstract type pattern B.this.Foo is unchecked since it is eliminated by erasure
+ case x: Foo with Bar with Concrete => x.bippy + x.barry + x.dingo + x.conco + x.bongo
+ ^
+error: No warnings can be incurred under -Xfatal-warnings.
+6 warnings found
+one error found
diff --git a/test/files/neg/t7721.flags b/test/files/neg/t7721.flags
new file mode 100644
index 0000000000..e8fb65d50c
--- /dev/null
+++ b/test/files/neg/t7721.flags
@@ -0,0 +1 @@
+-Xfatal-warnings \ No newline at end of file
diff --git a/test/files/neg/t7721.scala b/test/files/neg/t7721.scala
new file mode 100644
index 0000000000..27884c9e35
--- /dev/null
+++ b/test/files/neg/t7721.scala
@@ -0,0 +1,140 @@
+import scala.language.reflectiveCalls
+
+trait A {
+ trait Concrete { def conco: Int = 1 }
+ type Foo <: { def bippy: Int }
+ type Bar <: { def barry: Int }
+
+ implicit def barTag: scala.reflect.ClassTag[Bar]
+
+ def f1(x: Any) = x match {
+ case x: Foo with Concrete => x.bippy + x.conco
+ case _ => -1
+ }
+ def f2(x: Any) = x match {
+ case x: Concrete with Foo => x.bippy + x.conco
+ case _ => -1
+ }
+ def f3(x: Any) = x match {
+ case x: Foo with Bar => x.bippy + x.barry
+ case _ => -1
+ }
+ def f4(x: Any) = x match {
+ case x: (Foo @unchecked) => x.bippy // warns, suppressed
+ case _ => -1
+ }
+ def f5(x: Any) = x match {
+ case x: (Bar @unchecked) => x.barry // warns (but about the "outer reference"), suppressed
+ case _ => -1
+ }
+}
+
+trait B extends A {
+ type Foo <: { def bippy: Int ; def dingo: Int }
+ type Bar <: { def barry: Int ; def bongo: Int }
+
+ override implicit def barTag: scala.reflect.ClassTag[Bar]
+
+ override def f1(x: Any) = x match {
+ case x: Foo with Concrete => x.bippy + x.dingo + x.conco
+ case _ => -1
+ }
+ override def f2(x: Any) = x match {
+ case x: Concrete with Foo => x.bippy + x.dingo + x.conco
+ case _ => -1
+ }
+ override def f3(x: Any) = x match {
+ case x: Foo with Bar with Concrete => x.bippy + x.barry + x.dingo + x.conco + x.bongo
+ case _ => -1
+ }
+ override def f4(x: Any) = x match {
+ case x: (Foo @unchecked) => x.bippy + x.dingo // warns, suppressed
+ case _ => -1
+ }
+ override def f5(x: Any) = x match {
+ case x: (Bar @unchecked) => x.barry + x.bongo // warns (but about the "outer reference"), suppressed
+ case _ => -1
+ }
+}
+
+object Test {
+ abstract class Base extends A {
+ trait Foo {
+ def bippy = 2
+ def dingo = 3
+ }
+ trait Bar {
+ def barry = 2
+ def bongo = 3
+ }
+ implicit def barTag: scala.reflect.ClassTag[Bar] = scala.reflect.ClassTag(classOf[Bar])
+
+ def run() {
+ println("f1")
+ wrap(f1(new Concrete {}))
+ wrap(f1(new Foo {}))
+ wrap(f1(new Bar {}))
+ wrap(f1(new Foo with Concrete {}))
+ wrap(f1(new Concrete with Foo {}))
+
+ println("\nf2")
+ wrap(f2(new Concrete {}))
+ wrap(f2(new Foo {}))
+ wrap(f2(new Bar {}))
+ wrap(f2(new Foo with Concrete {}))
+ wrap(f2(new Concrete with Foo {}))
+ wrap(f2(new Bar with Concrete {}))
+ wrap(f2(new Concrete with Bar {}))
+ wrap(f2(new Concrete with Foo with Bar {}))
+ wrap(f2(new Foo with Bar with Concrete {}))
+
+ println("\nf3")
+ wrap(f3(new Concrete {}))
+ wrap(f3(new Foo {}))
+ wrap(f3(new Bar {}))
+ wrap(f3(new Foo with Concrete {}))
+ wrap(f3(new Concrete with Foo {}))
+ wrap(f3(new Bar with Concrete {}))
+ wrap(f3(new Concrete with Bar {}))
+ wrap(f3(new Concrete with Foo with Bar {}))
+ wrap(f3(new Foo with Bar with Concrete {}))
+
+ println("\nf4")
+ wrap(f4(new Concrete {}))
+ wrap(f4(new Foo {}))
+ wrap(f4(new Bar {}))
+ wrap(f4(new Foo with Concrete {}))
+ wrap(f4(new Concrete with Foo {}))
+ wrap(f4(new Bar with Concrete {}))
+ wrap(f4(new Concrete with Bar {}))
+ wrap(f4(new Concrete with Foo with Bar {}))
+ wrap(f4(new Foo with Bar with Concrete {}))
+
+ println("\nf5")
+ wrap(f5(new Concrete {}))
+ wrap(f5(new Foo {}))
+ wrap(f5(new Bar {}))
+ wrap(f5(new Foo with Concrete {}))
+ wrap(f5(new Concrete with Foo {}))
+ wrap(f5(new Bar with Concrete {}))
+ wrap(f5(new Concrete with Bar {}))
+ wrap(f5(new Concrete with Foo with Bar {}))
+ wrap(f5(new Foo with Bar with Concrete {}))
+ }
+ }
+
+ object ao extends Base
+ object bo extends Base with B
+
+ private def wrap(body: => Any) {
+ try println(body)
+ catch { case ex: NoSuchMethodException => println(ex) }
+ }
+
+ def main(args: Array[String]) {
+ ao.run()
+ bo.run()
+ }
+}
+
+// java.lang.NoSuchMethodException: Test$$anon$1.bippy() \ No newline at end of file
diff --git a/test/files/pos/extractor-types.scala b/test/files/pos/extractor-types.scala
new file mode 100644
index 0000000000..bb9659a13c
--- /dev/null
+++ b/test/files/pos/extractor-types.scala
@@ -0,0 +1,30 @@
+package p1 {
+ object Ex { def unapply(p: Any): Option[_ <: Int] = null }
+ object Foo { val Ex(_) = null }
+}
+// a.scala:2: error: error during expansion of this match (this is a scalac bug).
+// The underlying error was: type mismatch;
+// found : Some[_$1(in value x$1)] where type _$1(in value x$1)
+// required: Some[_$1(in method unapply)]
+// object Foo { val Ex(_) = null }
+// ^
+// one error found
+
+package p2 {
+ trait Other {
+ class Quux
+ object Baz { def unapply(x: Any): Option[Quux] = None }
+ }
+ trait Reifiers {
+ def f() {
+ val u2: Other = null
+ (null: Any) match { case u2.Baz(x) => println(x) } //: u2.Quux) }
+ // The underlying error was: type mismatch;
+ // found : Other#Quux
+ // required: u2.Quux
+ // x match { case u2.Baz(x) => println(x: u2.Quux) }
+ // ^
+ // one error found
+ }
+ }
+}
diff --git a/test/files/pos/optmatch.scala b/test/files/pos/optmatch.scala
new file mode 100644
index 0000000000..354be65da7
--- /dev/null
+++ b/test/files/pos/optmatch.scala
@@ -0,0 +1,33 @@
+// final case class NonZeroLong(value: Long) extends AnyVal {
+// def get: Long = value
+// def isEmpty: Boolean = get == 0l
+// }
+
+class NonZeroLong(val value: Long) extends AnyVal {
+ def get: Long = value
+ def isEmpty: Boolean = get == 0l
+}
+object NonZeroLong {
+ def unapply(value: Long): NonZeroLong = new NonZeroLong(value)
+}
+
+
+object Foo {
+ def unapply(x: Int): NonZeroLong = new NonZeroLong(1L << x)
+ // public long unapply(int);
+ // 0: lconst_1
+ // 1: iload_1
+ // 2: lshl
+ // 3: lreturn
+}
+
+object Test {
+ def f(x: Int): Int = x match {
+ case Foo(1024l) => 1
+ case _ => 2
+ }
+ def main(args: Array[String]): Unit = {
+ println(f(10))
+ println(f(11))
+ }
+}
diff --git a/test/files/pos/overloaded-unapply.scala b/test/files/pos/overloaded-unapply.scala
new file mode 100644
index 0000000000..4105a25f10
--- /dev/null
+++ b/test/files/pos/overloaded-unapply.scala
@@ -0,0 +1,8 @@
+trait Baz {
+ type Type >: Null
+
+ case class HoleType(a: String, b: String, c: String)
+ object HoleType { def unapply(tpe: Type): Option[HoleType] = ??? }
+
+ (null: Type) match { case HoleType(holeTpe) => holeTpe }
+}
diff --git a/test/files/run/name-based-patmat.check b/test/files/run/name-based-patmat.check
new file mode 100644
index 0000000000..1cc605ea3d
--- /dev/null
+++ b/test/files/run/name-based-patmat.check
@@ -0,0 +1,10 @@
+catdog
+2 catdogs! A ha ha!
+3 catdogs! A ha ha!
+catdog
+2 catdogs! A ha ha!
+3 catdogs! A ha ha!
+1
+1
+2
+3
diff --git a/test/files/run/name-based-patmat.scala b/test/files/run/name-based-patmat.scala
new file mode 100644
index 0000000000..2c429c141f
--- /dev/null
+++ b/test/files/run/name-based-patmat.scala
@@ -0,0 +1,75 @@
+final class MiniSome[T](val get: T) extends AnyVal { def isEmpty = false }
+
+package p1 {
+ class Triple(val x: Any) extends AnyRef with Product3[String, String, String] {
+ private def s = "" + x
+ override def canEqual(x: Any) = this eq x.asInstanceOf[AnyRef]
+ def isEmpty = false
+ def get = this
+ def _1 = s
+ def _2 = "2 " + s + "s! A ha ha!"
+ def _3 = "3 " + s + "s! A ha ha!"
+
+ override def toString = s"Triple(${_1}, ${_2}, ${_3})"
+ }
+
+ object Triple {
+ def unapply(x: Any): Triple = new Triple(x)
+ }
+}
+
+package p2 {
+ class Triple(val x: Any) {
+ private def s = "" + x
+ def isEmpty = false
+ def get = this
+ def _1 = s
+ def _2 = "2 " + s + "s! A ha ha!"
+ def _3 = "3 " + s + "s! A ha ha!"
+ override def toString = s"Triple(${_1}, ${_2}, ${_3})"
+ }
+
+ object Triple {
+ def unapply(x: Any): Triple = new Triple(x)
+ }
+}
+
+package p3 {
+ case class Foo(x: Int, y: Int, zs: Int*)
+
+ object Bar {
+ def f(x: Foo) = x match {
+ case Foo(5, 10, 15, 20, _*) => 1
+ case Foo(5, 10, 15, _*) => 2
+ case Foo(5, 10, _*) => 3
+ case Foo(5, 10) => 4 // should warn unreachable
+ case _ => 5
+ }
+ }
+}
+
+object Test {
+
+ // def f(x: Any) = x match {
+ // case p1.Foo(x, y, z) => println((x, y, z))
+ // case x => println(x)
+ // }
+
+ def main(args: Array[String]): Unit = {
+ "catdog" match {
+ case p1.Triple(x, y, z) => List(x, y, z) foreach println
+ case x => println("fail: " + x)
+ }
+ // TODO
+ "catdog" match {
+ case p2.Triple(x, y, z) => List(x, y, z) foreach println
+ case x => println("fail: " + x)
+ }
+
+ println(p3.Bar.f(p3.Foo(5, 10, 15, 20, 25)))
+ println(p3.Bar.f(p3.Foo(5, 10, 15, 20)))
+ println(p3.Bar.f(p3.Foo(5, 10, 15)))
+ println(p3.Bar.f(p3.Foo(5, 10)))
+ // println(p3.Bar.f(p3.Foo(5)))
+ }
+}
diff --git a/test/files/run/patmat-behavior-2.check b/test/files/run/patmat-behavior-2.check
new file mode 100644
index 0000000000..a928fe7918
--- /dev/null
+++ b/test/files/run/patmat-behavior-2.check
@@ -0,0 +1,24 @@
+f1(Foo(1)) == true
+f1(Foo(1, 2)) == false
+f1(Foo(1, 2, 3)) == false
+
+f2(Foo(1)) == false
+f2(Foo(1, 2)) == true
+f2(Foo(1, 2, 3)) == false
+
+f3(Foo(1)) == false
+f3(Foo(1, 2)) == false
+f3(Foo(1, 2, 3)) == true
+
+f1seq(Foo(1)) == true
+f1seq(Foo(1, 2)) == true
+f1seq(Foo(1, 2, 3)) == true
+
+f2seq(Foo(1)) == false
+f2seq(Foo(1, 2)) == true
+f2seq(Foo(1, 2, 3)) == true
+
+f3seq(Foo(1)) == false
+f3seq(Foo(1, 2)) == false
+f3seq(Foo(1, 2, 3)) == true
+
diff --git a/test/files/run/patmat-behavior-2.scala b/test/files/run/patmat-behavior-2.scala
new file mode 100644
index 0000000000..b31f773772
--- /dev/null
+++ b/test/files/run/patmat-behavior-2.scala
@@ -0,0 +1,50 @@
+case class Foo(x: Int, ys: Int*) {
+ // We write our own toString because of SI-7735
+ override def toString = (x +: ys).mkString("Foo(", ", ", ")")
+}
+
+object Test {
+ def f1(x: Any) = x match {
+ case Foo(x) => true
+ case _ => false
+ }
+ def f2(x: Any) = x match {
+ case Foo(x, y) => true
+ case _ => false
+ }
+ def f3(x: Any) = x match {
+ case Foo(x, y, z) => true
+ case _ => false
+ }
+ def f1seq(x: Any) = x match {
+ case Foo(x, ys @ _*) => true
+ case _ => false
+ }
+ def f2seq(x: Any) = x match {
+ case Foo(x, y, zs @ _*) => true
+ case _ => false
+ }
+ def f3seq(x: Any) = x match {
+ case Foo(x, y, z, qs @ _*) => true
+ case _ => false
+ }
+
+ val x1 = Foo(1)
+ val x2 = Foo(1, 2)
+ val x3 = Foo(1, 2, 3)
+
+ val fs = List[Any => Boolean](f1, f2, f3)
+ val fseqs = List[Any => Boolean](f1seq, f2seq, f3seq)
+ val xs = List[Foo](x1, x2, x3)
+
+ def main(args: Array[String]): Unit = {
+ for ((f, i) <- fs.zipWithIndex) {
+ xs foreach (x => println(s"f${i+1}($x) == ${f(x)}"))
+ println("")
+ }
+ for ((f, i) <- fseqs.zipWithIndex) {
+ xs foreach (x => println(s"f${i+1}seq($x) == ${f(x)}"))
+ println("")
+ }
+ }
+}
diff --git a/test/files/run/patmat-behavior.check b/test/files/run/patmat-behavior.check
new file mode 100644
index 0000000000..273a1434fb
--- /dev/null
+++ b/test/files/run/patmat-behavior.check
@@ -0,0 +1,90 @@
+patmat-behavior.scala:82: warning: fruitless type test: a value of type s.C00[A] cannot also be a s.C10[A]
+ def gd1[A](x: C00[A]) = x match { case G00() => ??? ; case G10(x) => x ; case G20(x, y) => x ; case G01(xs @ _*) => xs.head ; case G11(x, ys @ _*) => x ; case G21(x, y, zs @ _*) => x }
+ ^
+patmat-behavior.scala:82: warning: fruitless type test: a value of type s.C00[A] cannot also be a s.C20[A]
+ def gd1[A](x: C00[A]) = x match { case G00() => ??? ; case G10(x) => x ; case G20(x, y) => x ; case G01(xs @ _*) => xs.head ; case G11(x, ys @ _*) => x ; case G21(x, y, zs @ _*) => x }
+ ^
+patmat-behavior.scala:82: warning: fruitless type test: a value of type s.C00[A] cannot also be a s.C01[A]
+ def gd1[A](x: C00[A]) = x match { case G00() => ??? ; case G10(x) => x ; case G20(x, y) => x ; case G01(xs @ _*) => xs.head ; case G11(x, ys @ _*) => x ; case G21(x, y, zs @ _*) => x }
+ ^
+patmat-behavior.scala:82: warning: fruitless type test: a value of type s.C00[A] cannot also be a s.C11[A]
+ def gd1[A](x: C00[A]) = x match { case G00() => ??? ; case G10(x) => x ; case G20(x, y) => x ; case G01(xs @ _*) => xs.head ; case G11(x, ys @ _*) => x ; case G21(x, y, zs @ _*) => x }
+ ^
+patmat-behavior.scala:82: warning: fruitless type test: a value of type s.C00[A] cannot also be a s.C21[A]
+ def gd1[A](x: C00[A]) = x match { case G00() => ??? ; case G10(x) => x ; case G20(x, y) => x ; case G01(xs @ _*) => xs.head ; case G11(x, ys @ _*) => x ; case G21(x, y, zs @ _*) => x }
+ ^
+patmat-behavior.scala:83: warning: fruitless type test: a value of type s.C10[A] cannot also be a s.C00[A]
+ def gd2[A](x: C10[A]) = x match { case G00() => ??? ; case G10(x) => x ; case G20(x, y) => x ; case G01(xs @ _*) => xs.head ; case G11(x, ys @ _*) => x ; case G21(x, y, zs @ _*) => x }
+ ^
+patmat-behavior.scala:83: warning: fruitless type test: a value of type s.C10[A] cannot also be a s.C20[A]
+ def gd2[A](x: C10[A]) = x match { case G00() => ??? ; case G10(x) => x ; case G20(x, y) => x ; case G01(xs @ _*) => xs.head ; case G11(x, ys @ _*) => x ; case G21(x, y, zs @ _*) => x }
+ ^
+patmat-behavior.scala:83: warning: fruitless type test: a value of type s.C10[A] cannot also be a s.C01[A]
+ def gd2[A](x: C10[A]) = x match { case G00() => ??? ; case G10(x) => x ; case G20(x, y) => x ; case G01(xs @ _*) => xs.head ; case G11(x, ys @ _*) => x ; case G21(x, y, zs @ _*) => x }
+ ^
+patmat-behavior.scala:83: warning: fruitless type test: a value of type s.C10[A] cannot also be a s.C11[A]
+ def gd2[A](x: C10[A]) = x match { case G00() => ??? ; case G10(x) => x ; case G20(x, y) => x ; case G01(xs @ _*) => xs.head ; case G11(x, ys @ _*) => x ; case G21(x, y, zs @ _*) => x }
+ ^
+patmat-behavior.scala:83: warning: fruitless type test: a value of type s.C10[A] cannot also be a s.C21[A]
+ def gd2[A](x: C10[A]) = x match { case G00() => ??? ; case G10(x) => x ; case G20(x, y) => x ; case G01(xs @ _*) => xs.head ; case G11(x, ys @ _*) => x ; case G21(x, y, zs @ _*) => x }
+ ^
+patmat-behavior.scala:84: warning: fruitless type test: a value of type s.C20[A] cannot also be a s.C00[A]
+ def gd3[A](x: C20[A]) = x match { case G00() => ??? ; case G10(x) => x ; case G20(x, y) => x ; case G01(xs @ _*) => xs.head ; case G11(x, ys @ _*) => x ; case G21(x, y, zs @ _*) => x }
+ ^
+patmat-behavior.scala:84: warning: fruitless type test: a value of type s.C20[A] cannot also be a s.C10[A]
+ def gd3[A](x: C20[A]) = x match { case G00() => ??? ; case G10(x) => x ; case G20(x, y) => x ; case G01(xs @ _*) => xs.head ; case G11(x, ys @ _*) => x ; case G21(x, y, zs @ _*) => x }
+ ^
+patmat-behavior.scala:84: warning: fruitless type test: a value of type s.C20[A] cannot also be a s.C01[A]
+ def gd3[A](x: C20[A]) = x match { case G00() => ??? ; case G10(x) => x ; case G20(x, y) => x ; case G01(xs @ _*) => xs.head ; case G11(x, ys @ _*) => x ; case G21(x, y, zs @ _*) => x }
+ ^
+patmat-behavior.scala:84: warning: fruitless type test: a value of type s.C20[A] cannot also be a s.C11[A]
+ def gd3[A](x: C20[A]) = x match { case G00() => ??? ; case G10(x) => x ; case G20(x, y) => x ; case G01(xs @ _*) => xs.head ; case G11(x, ys @ _*) => x ; case G21(x, y, zs @ _*) => x }
+ ^
+patmat-behavior.scala:84: warning: fruitless type test: a value of type s.C20[A] cannot also be a s.C21[A]
+ def gd3[A](x: C20[A]) = x match { case G00() => ??? ; case G10(x) => x ; case G20(x, y) => x ; case G01(xs @ _*) => xs.head ; case G11(x, ys @ _*) => x ; case G21(x, y, zs @ _*) => x }
+ ^
+patmat-behavior.scala:85: warning: fruitless type test: a value of type s.C01[A] cannot also be a s.C00[A]
+ def gd4[A](x: C01[A]) = x match { case G00() => ??? ; case G10(x) => x ; case G20(x, y) => x ; case G01(xs @ _*) => xs.head ; case G11(x, ys @ _*) => x ; case G21(x, y, zs @ _*) => x }
+ ^
+patmat-behavior.scala:85: warning: fruitless type test: a value of type s.C01[A] cannot also be a s.C10[A]
+ def gd4[A](x: C01[A]) = x match { case G00() => ??? ; case G10(x) => x ; case G20(x, y) => x ; case G01(xs @ _*) => xs.head ; case G11(x, ys @ _*) => x ; case G21(x, y, zs @ _*) => x }
+ ^
+patmat-behavior.scala:85: warning: fruitless type test: a value of type s.C01[A] cannot also be a s.C20[A]
+ def gd4[A](x: C01[A]) = x match { case G00() => ??? ; case G10(x) => x ; case G20(x, y) => x ; case G01(xs @ _*) => xs.head ; case G11(x, ys @ _*) => x ; case G21(x, y, zs @ _*) => x }
+ ^
+patmat-behavior.scala:85: warning: fruitless type test: a value of type s.C01[A] cannot also be a s.C11[A]
+ def gd4[A](x: C01[A]) = x match { case G00() => ??? ; case G10(x) => x ; case G20(x, y) => x ; case G01(xs @ _*) => xs.head ; case G11(x, ys @ _*) => x ; case G21(x, y, zs @ _*) => x }
+ ^
+patmat-behavior.scala:85: warning: fruitless type test: a value of type s.C01[A] cannot also be a s.C21[A]
+ def gd4[A](x: C01[A]) = x match { case G00() => ??? ; case G10(x) => x ; case G20(x, y) => x ; case G01(xs @ _*) => xs.head ; case G11(x, ys @ _*) => x ; case G21(x, y, zs @ _*) => x }
+ ^
+patmat-behavior.scala:86: warning: fruitless type test: a value of type s.C11[A] cannot also be a s.C00[A]
+ def gd5[A](x: C11[A]) = x match { case G00() => ??? ; case G10(x) => x ; case G20(x, y) => x ; case G01(xs @ _*) => xs.head ; case G11(x, ys @ _*) => x ; case G21(x, y, zs @ _*) => x }
+ ^
+patmat-behavior.scala:86: warning: fruitless type test: a value of type s.C11[A] cannot also be a s.C10[A]
+ def gd5[A](x: C11[A]) = x match { case G00() => ??? ; case G10(x) => x ; case G20(x, y) => x ; case G01(xs @ _*) => xs.head ; case G11(x, ys @ _*) => x ; case G21(x, y, zs @ _*) => x }
+ ^
+patmat-behavior.scala:86: warning: fruitless type test: a value of type s.C11[A] cannot also be a s.C20[A]
+ def gd5[A](x: C11[A]) = x match { case G00() => ??? ; case G10(x) => x ; case G20(x, y) => x ; case G01(xs @ _*) => xs.head ; case G11(x, ys @ _*) => x ; case G21(x, y, zs @ _*) => x }
+ ^
+patmat-behavior.scala:86: warning: fruitless type test: a value of type s.C11[A] cannot also be a s.C01[A]
+ def gd5[A](x: C11[A]) = x match { case G00() => ??? ; case G10(x) => x ; case G20(x, y) => x ; case G01(xs @ _*) => xs.head ; case G11(x, ys @ _*) => x ; case G21(x, y, zs @ _*) => x }
+ ^
+patmat-behavior.scala:86: warning: fruitless type test: a value of type s.C11[A] cannot also be a s.C21[A]
+ def gd5[A](x: C11[A]) = x match { case G00() => ??? ; case G10(x) => x ; case G20(x, y) => x ; case G01(xs @ _*) => xs.head ; case G11(x, ys @ _*) => x ; case G21(x, y, zs @ _*) => x }
+ ^
+patmat-behavior.scala:87: warning: fruitless type test: a value of type s.C21[A] cannot also be a s.C00[A]
+ def gd6[A](x: C21[A]) = x match { case G00() => ??? ; case G10(x) => x ; case G20(x, y) => x ; case G01(xs @ _*) => xs.head ; case G11(x, ys @ _*) => x ; case G21(x, y, zs @ _*) => x }
+ ^
+patmat-behavior.scala:87: warning: fruitless type test: a value of type s.C21[A] cannot also be a s.C10[A]
+ def gd6[A](x: C21[A]) = x match { case G00() => ??? ; case G10(x) => x ; case G20(x, y) => x ; case G01(xs @ _*) => xs.head ; case G11(x, ys @ _*) => x ; case G21(x, y, zs @ _*) => x }
+ ^
+patmat-behavior.scala:87: warning: fruitless type test: a value of type s.C21[A] cannot also be a s.C20[A]
+ def gd6[A](x: C21[A]) = x match { case G00() => ??? ; case G10(x) => x ; case G20(x, y) => x ; case G01(xs @ _*) => xs.head ; case G11(x, ys @ _*) => x ; case G21(x, y, zs @ _*) => x }
+ ^
+patmat-behavior.scala:87: warning: fruitless type test: a value of type s.C21[A] cannot also be a s.C01[A]
+ def gd6[A](x: C21[A]) = x match { case G00() => ??? ; case G10(x) => x ; case G20(x, y) => x ; case G01(xs @ _*) => xs.head ; case G11(x, ys @ _*) => x ; case G21(x, y, zs @ _*) => x }
+ ^
+patmat-behavior.scala:87: warning: fruitless type test: a value of type s.C21[A] cannot also be a s.C11[A]
+ def gd6[A](x: C21[A]) = x match { case G00() => ??? ; case G10(x) => x ; case G20(x, y) => x ; case G01(xs @ _*) => xs.head ; case G11(x, ys @ _*) => x ; case G21(x, y, zs @ _*) => x }
+ ^
diff --git a/test/files/run/patmat-behavior.scala b/test/files/run/patmat-behavior.scala
new file mode 100644
index 0000000000..8b6370d796
--- /dev/null
+++ b/test/files/run/patmat-behavior.scala
@@ -0,0 +1,95 @@
+package s {
+ sealed trait C[+A]
+
+ case class C00[+A]() extends C[A]
+ case class C10[+A](x: A) extends C[A]
+ case class C20[+A](x: A, y: A) extends C[A]
+ case class C01[+A](xs: A*) extends C[A]
+ case class C11[+A](x: A, ys: A*) extends C[A]
+ case class C21[+A](x: A, y: A, zs: A*) extends C[A]
+
+ object E00 { def unapply[A](x: Any): Boolean = ??? }
+ object E10 { def unapply[A](x: Any): Option[A] = ??? }
+ object E20 { def unapply[A](x: Any): Option[(A, A)] = ??? }
+ object E01 { def unapplySeq[A](x: Any): Option[Seq[A]] = ??? }
+ object E11 { def unapplySeq[A](x: Any): Option[(A, Seq[A])] = ??? }
+ object E21 { def unapplySeq[A](x: Any): Option[(A, A, Seq[A])] = ??? }
+
+ object F00 { def unapply[A](x: C[A]): Boolean = ??? }
+ object F10 { def unapply[A](x: C[A]): Option[A] = ??? }
+ object F20 { def unapply[A](x: C[A]): Option[(A, A)] = ??? }
+ object F01 { def unapplySeq[A](x: C[A]): Option[Seq[A]] = ??? }
+ object F11 { def unapplySeq[A](x: C[A]): Option[(A, Seq[A])] = ??? }
+ object F21 { def unapplySeq[A](x: C[A]): Option[(A, A, Seq[A])] = ??? }
+
+ object G00 { def unapply[A](x: C00[A]): Boolean = ??? }
+ object G10 { def unapply[A](x: C10[A]): Option[A] = ??? }
+ object G20 { def unapply[A](x: C20[A]): Option[(A, A)] = ??? }
+ object G01 { def unapplySeq[A](x: C01[A]): Option[Seq[A]] = ??? }
+ object G11 { def unapplySeq[A](x: C11[A]): Option[(A, Seq[A])] = ??? }
+ object G21 { def unapplySeq[A](x: C21[A]): Option[(A, A, Seq[A])] = ??? }
+}
+import s._
+
+package pos {
+ object Test {
+ def ga1(x: Any) = x match { case C00() => 1 ; case C10(x) => 2 ; case C20(x, y) => 3 ; case C01(xs) => 4 ; case C11(x, ys) => 5 ; case C21(x, y, zs) => 6 }
+ def ga2(x: Any) = x match { case C00() => 1 ; case C10(x) => 2 ; case C20(x, y) => 3 ; case C01(xs) => 4 ; case C11(x, ys) => 5 ; case C21(x, y, zs) => 6 }
+ def ga3(x: Any) = x match { case C00() => 1 ; case C10(x) => 2 ; case C20(x, y) => 3 ; case C01(xs) => 4 ; case C11(x, ys) => 5 ; case C21(x, y, zs) => 6 }
+ def ga4(x: Any) = x match { case C00() => 1 ; case C10(x) => 2 ; case C20(x, y) => 3 ; case C01(xs) => 4 ; case C11(x, ys) => 5 ; case C21(x, y, zs) => 6 }
+ def ga5(x: Any) = x match { case C00() => 1 ; case C10(x) => 2 ; case C20(x, y) => 3 ; case C01(xs) => 4 ; case C11(x, ys) => 5 ; case C21(x, y, zs) => 6 }
+ def ga6(x: Any) = x match { case C00() => 1 ; case C10(x) => 2 ; case C20(x, y) => 3 ; case C01(xs) => 4 ; case C11(x, ys) => 5 ; case C21(x, y, zs) => 6 }
+
+ def gb1[A](x: C[A]) = x match { case E00() => ??? ; case E10(x) => x ; case E20(x, y) => x ; case E01(xs @ _*) => xs.head ; case E11(x, ys @ _*) => x ; case E21(x, y, zs @ _*) => x }
+ def gb2[A](x: C[A]) = x match { case E00() => ??? ; case E10(x) => x ; case E20(x, y) => x ; case E01(xs @ _*) => xs.head ; case E11(x, ys @ _*) => x ; case E21(x, y, zs @ _*) => x }
+ def gb3[A](x: C[A]) = x match { case E00() => ??? ; case E10(x) => x ; case E20(x, y) => x ; case E01(xs @ _*) => xs.head ; case E11(x, ys @ _*) => x ; case E21(x, y, zs @ _*) => x }
+ def gb4[A](x: C[A]) = x match { case E00() => ??? ; case E10(x) => x ; case E20(x, y) => x ; case E01(xs @ _*) => xs.head ; case E11(x, ys @ _*) => x ; case E21(x, y, zs @ _*) => x }
+ def gb5[A](x: C[A]) = x match { case E00() => ??? ; case E10(x) => x ; case E20(x, y) => x ; case E01(xs @ _*) => xs.head ; case E11(x, ys @ _*) => x ; case E21(x, y, zs @ _*) => x }
+ def gb6[A](x: C[A]) = x match { case E00() => ??? ; case E10(x) => x ; case E20(x, y) => x ; case E01(xs @ _*) => xs.head ; case E11(x, ys @ _*) => x ; case E21(x, y, zs @ _*) => x }
+
+ def gc1[A](x: C[A]) = x match { case F00() => ??? ; case F10(x) => x ; case F20(x, y) => x ; case F01(xs @ _*) => xs.head ; case F11(x, ys @ _*) => x ; case F21(x, y, zs @ _*) => x }
+ def gc2[A](x: C[A]) = x match { case F00() => ??? ; case F10(x) => x ; case F20(x, y) => x ; case F01(xs @ _*) => xs.head ; case F11(x, ys @ _*) => x ; case F21(x, y, zs @ _*) => x }
+ def gc3[A](x: C[A]) = x match { case F00() => ??? ; case F10(x) => x ; case F20(x, y) => x ; case F01(xs @ _*) => xs.head ; case F11(x, ys @ _*) => x ; case F21(x, y, zs @ _*) => x }
+ def gc4[A](x: C[A]) = x match { case F00() => ??? ; case F10(x) => x ; case F20(x, y) => x ; case F01(xs @ _*) => xs.head ; case F11(x, ys @ _*) => x ; case F21(x, y, zs @ _*) => x }
+ def gc5[A](x: C[A]) = x match { case F00() => ??? ; case F10(x) => x ; case F20(x, y) => x ; case F01(xs @ _*) => xs.head ; case F11(x, ys @ _*) => x ; case F21(x, y, zs @ _*) => x }
+ def gc6[A](x: C[A]) = x match { case F00() => ??? ; case F10(x) => x ; case F20(x, y) => x ; case F01(xs @ _*) => xs.head ; case F11(x, ys @ _*) => x ; case F21(x, y, zs @ _*) => x }
+
+ def gd1[A, B <: C[A]](x: B) = x match { case F00() => ??? ; case F10(x) => x ; case F20(x, y) => x ; case F01(xs @ _*) => xs.head ; case F11(x, ys @ _*) => x ; case F21(x, y, zs @ _*) => x }
+ def gd2[A, B <: C[A]](x: B) = x match { case F00() => ??? ; case F10(x) => x ; case F20(x, y) => x ; case F01(xs @ _*) => xs.head ; case F11(x, ys @ _*) => x ; case F21(x, y, zs @ _*) => x }
+ def gd3[A, B <: C[A]](x: B) = x match { case F00() => ??? ; case F10(x) => x ; case F20(x, y) => x ; case F01(xs @ _*) => xs.head ; case F11(x, ys @ _*) => x ; case F21(x, y, zs @ _*) => x }
+ def gd4[A, B <: C[A]](x: B) = x match { case F00() => ??? ; case F10(x) => x ; case F20(x, y) => x ; case F01(xs @ _*) => xs.head ; case F11(x, ys @ _*) => x ; case F21(x, y, zs @ _*) => x }
+ def gd5[A, B <: C[A]](x: B) = x match { case F00() => ??? ; case F10(x) => x ; case F20(x, y) => x ; case F01(xs @ _*) => xs.head ; case F11(x, ys @ _*) => x ; case F21(x, y, zs @ _*) => x }
+ def gd6[A, B <: C[A]](x: B) = x match { case F00() => ??? ; case F10(x) => x ; case F20(x, y) => x ; case F01(xs @ _*) => xs.head ; case F11(x, ys @ _*) => x ; case F21(x, y, zs @ _*) => x }
+ }
+}
+
+package neg {
+ object Fail {
+ def gb1[A](x: C00[A]) = x match { case E00() => ??? ; case E10(x) => x ; case E20(x, y) => x ; case E01(xs @ _*) => xs.head ; case E11(x, ys @ _*) => x ; case E21(x, y, zs @ _*) => x }
+ def gb2[A](x: C10[A]) = x match { case E00() => ??? ; case E10(x) => x ; case E20(x, y) => x ; case E01(xs @ _*) => xs.head ; case E11(x, ys @ _*) => x ; case E21(x, y, zs @ _*) => x }
+ def gb3[A](x: C20[A]) = x match { case E00() => ??? ; case E10(x) => x ; case E20(x, y) => x ; case E01(xs @ _*) => xs.head ; case E11(x, ys @ _*) => x ; case E21(x, y, zs @ _*) => x }
+ def gb4[A](x: C01[A]) = x match { case E00() => ??? ; case E10(x) => x ; case E20(x, y) => x ; case E01(xs @ _*) => xs.head ; case E11(x, ys @ _*) => x ; case E21(x, y, zs @ _*) => x }
+ def gb5[A](x: C11[A]) = x match { case E00() => ??? ; case E10(x) => x ; case E20(x, y) => x ; case E01(xs @ _*) => xs.head ; case E11(x, ys @ _*) => x ; case E21(x, y, zs @ _*) => x }
+ def gb6[A](x: C21[A]) = x match { case E00() => ??? ; case E10(x) => x ; case E20(x, y) => x ; case E01(xs @ _*) => xs.head ; case E11(x, ys @ _*) => x ; case E21(x, y, zs @ _*) => x }
+
+ def gc1[A](x: C00[A]) = x match { case F00() => ??? ; case F10(x) => x ; case F20(x, y) => x ; case F01(xs @ _*) => xs.head ; case F11(x, ys @ _*) => x ; case F21(x, y, zs @ _*) => x }
+ def gc2[A](x: C10[A]) = x match { case F00() => ??? ; case F10(x) => x ; case F20(x, y) => x ; case F01(xs @ _*) => xs.head ; case F11(x, ys @ _*) => x ; case F21(x, y, zs @ _*) => x }
+ def gc3[A](x: C20[A]) = x match { case F00() => ??? ; case F10(x) => x ; case F20(x, y) => x ; case F01(xs @ _*) => xs.head ; case F11(x, ys @ _*) => x ; case F21(x, y, zs @ _*) => x }
+ def gc4[A](x: C01[A]) = x match { case F00() => ??? ; case F10(x) => x ; case F20(x, y) => x ; case F01(xs @ _*) => xs.head ; case F11(x, ys @ _*) => x ; case F21(x, y, zs @ _*) => x }
+ def gc5[A](x: C11[A]) = x match { case F00() => ??? ; case F10(x) => x ; case F20(x, y) => x ; case F01(xs @ _*) => xs.head ; case F11(x, ys @ _*) => x ; case F21(x, y, zs @ _*) => x }
+ def gc6[A](x: C21[A]) = x match { case F00() => ??? ; case F10(x) => x ; case F20(x, y) => x ; case F01(xs @ _*) => xs.head ; case F11(x, ys @ _*) => x ; case F21(x, y, zs @ _*) => x }
+
+ def gd1[A](x: C00[A]) = x match { case G00() => ??? ; case G10(x) => x ; case G20(x, y) => x ; case G01(xs @ _*) => xs.head ; case G11(x, ys @ _*) => x ; case G21(x, y, zs @ _*) => x }
+ def gd2[A](x: C10[A]) = x match { case G00() => ??? ; case G10(x) => x ; case G20(x, y) => x ; case G01(xs @ _*) => xs.head ; case G11(x, ys @ _*) => x ; case G21(x, y, zs @ _*) => x }
+ def gd3[A](x: C20[A]) = x match { case G00() => ??? ; case G10(x) => x ; case G20(x, y) => x ; case G01(xs @ _*) => xs.head ; case G11(x, ys @ _*) => x ; case G21(x, y, zs @ _*) => x }
+ def gd4[A](x: C01[A]) = x match { case G00() => ??? ; case G10(x) => x ; case G20(x, y) => x ; case G01(xs @ _*) => xs.head ; case G11(x, ys @ _*) => x ; case G21(x, y, zs @ _*) => x }
+ def gd5[A](x: C11[A]) = x match { case G00() => ??? ; case G10(x) => x ; case G20(x, y) => x ; case G01(xs @ _*) => xs.head ; case G11(x, ys @ _*) => x ; case G21(x, y, zs @ _*) => x }
+ def gd6[A](x: C21[A]) = x match { case G00() => ??? ; case G10(x) => x ; case G20(x, y) => x ; case G01(xs @ _*) => xs.head ; case G11(x, ys @ _*) => x ; case G21(x, y, zs @ _*) => x }
+ }
+}
+
+object Test {
+ def main(args: Array[String]): Unit = {
+
+ }
+}
diff --git a/test/files/run/value-class-extractor-2.check b/test/files/run/value-class-extractor-2.check
new file mode 100644
index 0000000000..5903b996b6
--- /dev/null
+++ b/test/files/run/value-class-extractor-2.check
@@ -0,0 +1,8 @@
+String
+List
+Int
+Something else
+String
+List
+Int
+Something else
diff --git a/test/files/run/value-class-extractor-2.scala b/test/files/run/value-class-extractor-2.scala
new file mode 100644
index 0000000000..d776c35eda
--- /dev/null
+++ b/test/files/run/value-class-extractor-2.scala
@@ -0,0 +1,108 @@
+final class Opt[+A >: Null](val value: A) extends AnyVal {
+ def get: A = value
+ def isEmpty = value == null
+}
+object Opt {
+ final val None = new Opt[Null](null)
+ def apply[A >: Null](value: A): Opt[A] = if (value == null) None else new Opt[A](value)
+}
+
+object ValueOpt {
+ // public java.lang.String unapply(java.lang.Object);
+ // 0: aload_1
+ // 1: instanceof #16 // class java/lang/String
+ // 4: ifeq 21
+ // 7: getstatic #21 // Field Opt$.MODULE$:LOpt$;
+ // 10: astore_2
+ // 11: ldc #23 // String String
+ // 13: checkcast #16 // class java/lang/String
+ // 16: astore 5
+ // 18: goto 71
+ // 21: aload_1
+ // 22: instanceof #25 // class scala/collection/immutable/List
+ // 25: ifeq 42
+ // 28: getstatic #21 // Field Opt$.MODULE$:LOpt$;
+ // 31: astore_3
+ // 32: ldc #27 // String List
+ // 34: checkcast #16 // class java/lang/String
+ // 37: astore 5
+ // 39: goto 71
+ // 42: aload_1
+ // 43: instanceof #29 // class java/lang/Integer
+ // 46: ifeq 64
+ // 49: getstatic #21 // Field Opt$.MODULE$:LOpt$;
+ // 52: astore 4
+ // 54: ldc #31 // String Int
+ // 56: checkcast #16 // class java/lang/String
+ // 59: astore 5
+ // 61: goto 71
+ // 64: getstatic #21 // Field Opt$.MODULE$:LOpt$;
+ // 67: pop
+ // 68: aconst_null
+ // 69: astore 5
+ // 71: aload 5
+ // 73: areturn
+ def unapply(x: Any): Opt[String] = x match {
+ case _: String => Opt("String")
+ case _: List[_] => Opt("List")
+ case _: Int => Opt("Int")
+ case _ => Opt.None
+ }
+}
+object RegularOpt {
+ // public scala.Option<java.lang.String> unapply(java.lang.Object);
+ // 0: aload_1
+ // 1: instanceof #16 // class java/lang/String
+ // 4: ifeq 20
+ // 7: new #18 // class scala/Some
+ // 10: dup
+ // 11: ldc #20 // String String
+ // 13: invokespecial #23 // Method scala/Some."<init>":(Ljava/lang/Object;)V
+ // 16: astore_2
+ // 17: goto 64
+ // 20: aload_1
+ // 21: instanceof #25 // class scala/collection/immutable/List
+ // 24: ifeq 40
+ // 27: new #18 // class scala/Some
+ // 30: dup
+ // 31: ldc #27 // String List
+ // 33: invokespecial #23 // Method scala/Some."<init>":(Ljava/lang/Object;)V
+ // 36: astore_2
+ // 37: goto 64
+ // 40: aload_1
+ // 41: instanceof #29 // class java/lang/Integer
+ // 44: ifeq 60
+ // 47: new #18 // class scala/Some
+ // 50: dup
+ // 51: ldc #31 // String Int
+ // 53: invokespecial #23 // Method scala/Some."<init>":(Ljava/lang/Object;)V
+ // 56: astore_2
+ // 57: goto 64
+ // 60: getstatic #36 // Field scala/None$.MODULE$:Lscala/None$;
+ // 63: astore_2
+ // 64: aload_2
+ // 65: areturn
+ def unapply(x: Any): Option[String] = x match {
+ case _: String => Some("String")
+ case _: List[_] => Some("List")
+ case _: Int => Some("Int")
+ case _ => None
+ }
+}
+
+object Test {
+ def f(x: Any) = x match {
+ case ValueOpt(s) => s
+ case _ => "Something else"
+ }
+ def g(x: Any) = x match {
+ case RegularOpt(s) => s
+ case _ => "Something else"
+ }
+ val xs = List("abc", Nil, 5, Test)
+
+ def main(args: Array[String]): Unit = {
+ xs map f foreach println
+ xs map g foreach println
+ }
+}
diff --git a/test/files/run/value-class-extractor-seq.check b/test/files/run/value-class-extractor-seq.check
new file mode 100644
index 0000000000..84552a7aa5
--- /dev/null
+++ b/test/files/run/value-class-extractor-seq.check
@@ -0,0 +1,3 @@
+Bip(1, 2, 3)
+Bip(1, 2, c @ Array(3, 4, 5): _*)
+class [I
diff --git a/test/files/run/value-class-extractor-seq.scala b/test/files/run/value-class-extractor-seq.scala
new file mode 100644
index 0000000000..f17a5314f2
--- /dev/null
+++ b/test/files/run/value-class-extractor-seq.scala
@@ -0,0 +1,59 @@
+import scala.runtime.ScalaRunTime.stringOf
+
+final class ArrayOpt[T](val xs: Array[T]) extends AnyVal {
+ def isEmpty = xs == null
+ def get = xs
+}
+
+object Bip {
+ def mkInts(xs: Array[Short]) = xs map (_.toInt)
+ def unapplySeq(x: Any): ArrayOpt[Int] = x match {
+ case xs: Array[Int] => new ArrayOpt(xs)
+ case xs: Array[Short] => new ArrayOpt(mkInts(xs))
+ case _ => new ArrayOpt(null)
+ }
+ // public int[] unapplySeq(java.lang.Object);
+ // 0: aload_1
+ // 1: astore_2
+ // 2: aload_2
+ // 3: instanceof #52 // class "[I"
+ // 6: ifeq 20
+ // 9: aload_2
+ // 10: checkcast #52 // class "[I"
+ // 13: astore_3
+ // 14: aload_3
+ // 15: astore 4
+ // 17: goto 47
+ // 20: aload_2
+ // 21: instanceof #58 // class "[S"
+ // 24: ifeq 44
+ // 27: aload_2
+ // 28: checkcast #58 // class "[S"
+ // 31: astore 5
+ // 33: aload_0
+ // 34: aload 5
+ // 36: invokevirtual #60 // Method mkInts:([S)[I
+ // 39: astore 4
+ // 41: goto 47
+ // 44: aconst_null
+ // 45: astore 4
+ // 47: aload 4
+ // 49: areturn
+}
+
+object Test {
+ def f(x: Any) = x match {
+ case Bip(a, b, c) => s"Bip($a, $b, $c)"
+ case Bip(a, b, c @ _*) => s"Bip($a, $b, c @ ${stringOf(c)}: _*)"
+ case _ => "" + x.getClass
+ }
+
+ def main(args: Array[String]): Unit = {
+ println(f(Array[Int](1,2,3)))
+ println(f(Array[Int](1,2,3,4,5)))
+ println(f(Array[Int](1)))
+ }
+ // Bip(1, 2, 3)
+ // Bip(1, 2, c @ [I@782be20e: _*)
+ // class [I
+}
diff --git a/test/files/run/value-class-extractor.check b/test/files/run/value-class-extractor.check
new file mode 100644
index 0000000000..e16447118c
--- /dev/null
+++ b/test/files/run/value-class-extractor.check
@@ -0,0 +1,9 @@
+'a'
+'b'
+'c'
+NoChar
+Some(a)
+Some(b)
+Some(c)
+None
+9
diff --git a/test/files/run/value-class-extractor.scala b/test/files/run/value-class-extractor.scala
new file mode 100644
index 0000000000..3eaffa0c23
--- /dev/null
+++ b/test/files/run/value-class-extractor.scala
@@ -0,0 +1,91 @@
+final class NonNullChar(val get: Char) extends AnyVal {
+ def isEmpty = get == 0.toChar
+ override def toString = if (isEmpty) "NoChar" else s"'$get'"
+}
+object NonNullChar {
+ @inline final val None = new NonNullChar(0.toChar)
+}
+
+final class SomeProduct extends Product3[String, Int, List[String]] {
+ def canEqual(x: Any) = x.isInstanceOf[SomeProduct]
+ def _1 = "abc"
+ def _2 = 5
+ def _3 = List("bippy")
+ def isEmpty = false
+ def get = this
+}
+object SomeProduct {
+ def unapply(x: SomeProduct) = x
+}
+
+object Test {
+ def prod(x: SomeProduct): Int = x match {
+ case SomeProduct(x, y, z) => x.length + y + z.length
+ case _ => -1
+ }
+
+ def f(x: Char): NonNullChar = x match {
+ case 'a' => new NonNullChar('a')
+ case 'b' => new NonNullChar('b')
+ case 'c' => new NonNullChar('c')
+ case _ => NonNullChar.None
+ }
+ // public char f(char);
+ // 0: iload_1
+ // 1: tableswitch { // 97 to 99
+ // 97: 47
+ // 98: 42
+ // 99: 37
+ // default: 28
+ // }
+ // 28: getstatic #19 // Field NonNullChar$.MODULE$:LNonNullChar$;
+ // 31: invokevirtual #23 // Method NonNullChar$.None:()C
+ // 34: goto 49
+ // 37: bipush 99
+ // 39: goto 49
+ // 42: bipush 98
+ // 44: goto 49
+ // 47: bipush 97
+ // 49: ireturn
+ def g(x: Char): Option[Char] = x match {
+ case 'a' => Some('a')
+ case 'b' => Some('b')
+ case 'c' => Some('c')
+ case _ => None
+ }
+ // public scala.Option<java.lang.Object> g(char);
+ // 0: iload_1
+ // 1: tableswitch { // 97 to 99
+ // 97: 64
+ // 98: 49
+ // 99: 34
+ // default: 28
+ // }
+ // 28: getstatic #33 // Field scala/None$.MODULE$:Lscala/None$;
+ // 31: goto 76
+ // 34: new #35 // class scala/Some
+ // 37: dup
+ // 38: bipush 99
+ // 40: invokestatic #41 // Method scala/runtime/BoxesRunTime.boxToCharacter:(C)Ljava/lang/Character;
+ // 43: invokespecial #44 // Method scala/Some."<init>":(Ljava/lang/Object;)V
+ // 46: goto 76
+ // 49: new #35 // class scala/Some
+ // 52: dup
+ // 53: bipush 98
+ // 55: invokestatic #41 // Method scala/runtime/BoxesRunTime.boxToCharacter:(C)Ljava/lang/Character;
+ // 58: invokespecial #44 // Method scala/Some."<init>":(Ljava/lang/Object;)V
+ // 61: goto 76
+ // 64: new #35 // class scala/Some
+ // 67: dup
+ // 68: bipush 97
+ // 70: invokestatic #41 // Method scala/runtime/BoxesRunTime.boxToCharacter:(C)Ljava/lang/Character;
+ // 73: invokespecial #44 // Method scala/Some."<init>":(Ljava/lang/Object;)V
+ // 76: areturn
+ def main(args: Array[String]): Unit = {
+ "abcd" foreach (ch => println(f(ch)))
+ "abcd" foreach (ch => println(g(ch)))
+ println(prod(new SomeProduct))
+ }
+}
+
+