summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPaul Phillips <paulp@improving.org>2013-08-17 23:42:40 -0700
committerPaul Phillips <paulp@improving.org>2013-08-17 23:42:40 -0700
commita9efda40ee30796d3458604869a87a2c91f3efbf (patch)
tree7d1e685110c50ae37616c00f3c94450af03c4acc
parent22b82a485a53ffad3490673a481fbd79d616ed71 (diff)
parent84a335916556cb0fe939d1c51f27d80d9cf980dc (diff)
downloadscala-a9efda40ee30796d3458604869a87a2c91f3efbf.tar.gz
scala-a9efda40ee30796d3458604869a87a2c91f3efbf.tar.bz2
scala-a9efda40ee30796d3458604869a87a2c91f3efbf.zip
Merge remote-tracking branch 'xeno-by/topic/patmat2' into patmat2
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/ContextErrors.scala3
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/PatternTypers.scala2
-rw-r--r--test/files/neg/t5903a.check7
-rw-r--r--test/files/neg/t5903a/Macros_1.scala28
-rw-r--r--test/files/neg/t5903a/Test_2.scala6
-rw-r--r--test/files/neg/t5903b.check9
-rw-r--r--test/files/neg/t5903b/Macros_1.scala23
-rw-r--r--test/files/neg/t5903b/Test_2.scala6
-rw-r--r--test/files/neg/t5903c.check7
-rw-r--r--test/files/neg/t5903c/Macros_1.scala26
-rw-r--r--test/files/neg/t5903c/Test_2.scala6
-rw-r--r--test/files/neg/t5903d.check7
-rw-r--r--test/files/neg/t5903d/Macros_1.scala23
-rw-r--r--test/files/neg/t5903d/Test_2.scala6
-rw-r--r--test/files/neg/t5903e.check4
-rw-r--r--test/files/neg/t5903e/Macros_1.scala25
-rw-r--r--test/files/neg/t5903e/Test_2.scala6
-rw-r--r--test/files/run/t5903a.check1
-rw-r--r--test/files/run/t5903a.flags1
-rw-r--r--test/files/run/t5903a/Macros_1.scala28
-rw-r--r--test/files/run/t5903a/Test_2.scala6
-rw-r--r--test/files/run/t5903b.check1
-rw-r--r--test/files/run/t5903b.flags1
-rw-r--r--test/files/run/t5903b/Macros_1.scala25
-rw-r--r--test/files/run/t5903b/Test_2.scala6
-rw-r--r--test/files/run/t5903c.check1
-rw-r--r--test/files/run/t5903c.flags1
-rw-r--r--test/files/run/t5903c/Macros_1.scala23
-rw-r--r--test/files/run/t5903c/Test_2.scala6
-rw-r--r--test/files/run/t5903d.check1
-rw-r--r--test/files/run/t5903d.flags1
-rw-r--r--test/files/run/t5903d/Macros_1.scala25
-rw-r--r--test/files/run/t5903d/Test_2.scala6
33 files changed, 327 insertions, 0 deletions
diff --git a/src/compiler/scala/tools/nsc/typechecker/ContextErrors.scala b/src/compiler/scala/tools/nsc/typechecker/ContextErrors.scala
index 7f4bf0dfbc..1f4d5cbac2 100644
--- a/src/compiler/scala/tools/nsc/typechecker/ContextErrors.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/ContextErrors.scala
@@ -517,6 +517,9 @@ trait ContextErrors {
def TooManyArgsPatternError(fun: Tree) =
NormalTypeError(fun, "too many arguments for unapply pattern, maximum = "+definitions.MaxTupleArity)
+ def WrongShapeExtractorExpansion(fun: Tree) =
+ NormalTypeError(fun, "extractor macros can only expand into extractor calls")
+
def WrongNumberOfArgsError(tree: Tree, fun: Tree) =
NormalTypeError(tree, "wrong number of arguments for "+ treeSymTypeMsg(fun))
diff --git a/src/compiler/scala/tools/nsc/typechecker/PatternTypers.scala b/src/compiler/scala/tools/nsc/typechecker/PatternTypers.scala
index 13926ca18b..cc0ffe2ac2 100644
--- a/src/compiler/scala/tools/nsc/typechecker/PatternTypers.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/PatternTypers.scala
@@ -413,6 +413,8 @@ trait PatternTypers {
if (fun1.tpe.isErroneous)
duplErrTree
+ else if (unapplyMethod.isMacro && !fun1.isInstanceOf[Apply])
+ duplErrorTree(WrongShapeExtractorExpansion(tree))
else
makeTypedUnApply()
}
diff --git a/test/files/neg/t5903a.check b/test/files/neg/t5903a.check
new file mode 100644
index 0000000000..cbdcfd1bdd
--- /dev/null
+++ b/test/files/neg/t5903a.check
@@ -0,0 +1,7 @@
+Test_2.scala:4: error: wrong number of patterns for <$anon: AnyRef> offering (SomeTree.type, SomeTree.type): expected 2, found 3
+ case nq"$x + $y + $z" => println((x, y))
+ ^
+Test_2.scala:4: error: not found: value x
+ case nq"$x + $y + $z" => println((x, y))
+ ^
+two errors found
diff --git a/test/files/neg/t5903a/Macros_1.scala b/test/files/neg/t5903a/Macros_1.scala
new file mode 100644
index 0000000000..e82be0fc68
--- /dev/null
+++ b/test/files/neg/t5903a/Macros_1.scala
@@ -0,0 +1,28 @@
+import scala.reflect.macros.Context
+import language.experimental.macros
+
+trait Tree
+case object SomeTree extends Tree
+
+object NewQuasiquotes {
+ implicit class QuasiquoteInterpolation(c: StringContext) {
+ object nq {
+ def unapply(t: Tree) = macro QuasiquoteMacros.unapplyImpl
+ }
+ }
+}
+
+object QuasiquoteMacros {
+ def unapplyImpl(c: Context)(t: c.Tree) = {
+ import c.universe._
+ q"""
+ new {
+ def isEmpty = false
+ def get = this
+ def _1 = SomeTree
+ def _2 = SomeTree
+ def unapply(t: Tree) = this
+ }.unapply($t)
+ """
+ }
+}
diff --git a/test/files/neg/t5903a/Test_2.scala b/test/files/neg/t5903a/Test_2.scala
new file mode 100644
index 0000000000..4d78dfb5e5
--- /dev/null
+++ b/test/files/neg/t5903a/Test_2.scala
@@ -0,0 +1,6 @@
+object Test extends App {
+ import NewQuasiquotes._
+ SomeTree match {
+ case nq"$x + $y + $z" => println((x, y))
+ }
+}
diff --git a/test/files/neg/t5903b.check b/test/files/neg/t5903b.check
new file mode 100644
index 0000000000..faeb73ad03
--- /dev/null
+++ b/test/files/neg/t5903b.check
@@ -0,0 +1,9 @@
+Test_2.scala:4: error: type mismatch;
+ found : Int
+ required: String
+ case t"$x" => println(x)
+ ^
+Test_2.scala:4: error: not found: value x
+ case t"$x" => println(x)
+ ^
+two errors found
diff --git a/test/files/neg/t5903b/Macros_1.scala b/test/files/neg/t5903b/Macros_1.scala
new file mode 100644
index 0000000000..b1b875969d
--- /dev/null
+++ b/test/files/neg/t5903b/Macros_1.scala
@@ -0,0 +1,23 @@
+import scala.reflect.macros.Context
+import language.experimental.macros
+
+object Interpolation {
+ implicit class TestInterpolation(c: StringContext) {
+ object t {
+ def unapply[T](x: T) = macro Macros.unapplyImpl[T]
+ }
+ }
+}
+
+object Macros {
+ def unapplyImpl[T: c.WeakTypeTag](c: Context)(x: c.Tree) = {
+ import c.universe._
+ q"""
+ new {
+ def isEmpty = false
+ def get = "2"
+ def unapply(x: String) = this
+ }.unapply($x)
+ """
+ }
+}
diff --git a/test/files/neg/t5903b/Test_2.scala b/test/files/neg/t5903b/Test_2.scala
new file mode 100644
index 0000000000..0f6f80d327
--- /dev/null
+++ b/test/files/neg/t5903b/Test_2.scala
@@ -0,0 +1,6 @@
+object Test extends App {
+ import Interpolation._
+ 2 match {
+ case t"$x" => println(x)
+ }
+}
diff --git a/test/files/neg/t5903c.check b/test/files/neg/t5903c.check
new file mode 100644
index 0000000000..c9476edd11
--- /dev/null
+++ b/test/files/neg/t5903c.check
@@ -0,0 +1,7 @@
+Test_2.scala:4: error: String is not supported
+ case t"$x" => println(x)
+ ^
+Test_2.scala:4: error: not found: value x
+ case t"$x" => println(x)
+ ^
+two errors found
diff --git a/test/files/neg/t5903c/Macros_1.scala b/test/files/neg/t5903c/Macros_1.scala
new file mode 100644
index 0000000000..70efab3101
--- /dev/null
+++ b/test/files/neg/t5903c/Macros_1.scala
@@ -0,0 +1,26 @@
+import scala.reflect.macros.Context
+import language.experimental.macros
+
+object Interpolation {
+ implicit class TestInterpolation(c: StringContext) {
+ object t {
+ def unapply[T](x: T) = macro Macros.unapplyImpl[T]
+ }
+ }
+}
+
+object Macros {
+ def unapplyImpl[T: c.WeakTypeTag](c: Context)(x: c.Tree) = {
+ import c.universe._
+ if (!(c.weakTypeOf[Int] =:= c.weakTypeOf[T])) c.abort(c.enclosingPosition, s"${c.weakTypeOf[T]} is not supported")
+ else {
+ q"""
+ new {
+ def isEmpty = false
+ def get = 2
+ def unapply(x: Int) = this
+ }.unapply($x)
+ """
+ }
+ }
+}
diff --git a/test/files/neg/t5903c/Test_2.scala b/test/files/neg/t5903c/Test_2.scala
new file mode 100644
index 0000000000..a1fd31dd49
--- /dev/null
+++ b/test/files/neg/t5903c/Test_2.scala
@@ -0,0 +1,6 @@
+object Test extends App {
+ import Interpolation._
+ "2" match {
+ case t"$x" => println(x)
+ }
+}
diff --git a/test/files/neg/t5903d.check b/test/files/neg/t5903d.check
new file mode 100644
index 0000000000..d5d3fdcc28
--- /dev/null
+++ b/test/files/neg/t5903d.check
@@ -0,0 +1,7 @@
+Test_2.scala:4: error: extractor macros can only expand into extractor calls
+ case t"$x" => println(x)
+ ^
+Test_2.scala:4: error: not found: value x
+ case t"$x" => println(x)
+ ^
+two errors found
diff --git a/test/files/neg/t5903d/Macros_1.scala b/test/files/neg/t5903d/Macros_1.scala
new file mode 100644
index 0000000000..15ff226cff
--- /dev/null
+++ b/test/files/neg/t5903d/Macros_1.scala
@@ -0,0 +1,23 @@
+import scala.reflect.macros.Context
+import language.experimental.macros
+
+object Interpolation {
+ implicit class TestInterpolation(c: StringContext) {
+ object t {
+ def unapply(x: Int) = macro Macros.unapplyImpl
+ }
+ }
+}
+
+object Macros {
+ def unapplyImpl(c: Context)(x: c.Tree) = {
+ import c.universe._
+ q"""
+ class Match(x: Int) {
+ def isEmpty = false
+ def get = x
+ }
+ new { def unapply(x: Int) = new Match(x) }.unapply($x)
+ """
+ }
+}
diff --git a/test/files/neg/t5903d/Test_2.scala b/test/files/neg/t5903d/Test_2.scala
new file mode 100644
index 0000000000..95c717a9d8
--- /dev/null
+++ b/test/files/neg/t5903d/Test_2.scala
@@ -0,0 +1,6 @@
+object Test extends App {
+ import Interpolation._
+ 42 match {
+ case t"$x" => println(x)
+ }
+}
diff --git a/test/files/neg/t5903e.check b/test/files/neg/t5903e.check
new file mode 100644
index 0000000000..3bdeb091a0
--- /dev/null
+++ b/test/files/neg/t5903e.check
@@ -0,0 +1,4 @@
+Test_2.scala:4: error: value class may not be a member of another class
+ case t"$x" => println(x)
+ ^
+one error found
diff --git a/test/files/neg/t5903e/Macros_1.scala b/test/files/neg/t5903e/Macros_1.scala
new file mode 100644
index 0000000000..4e1ce89c9f
--- /dev/null
+++ b/test/files/neg/t5903e/Macros_1.scala
@@ -0,0 +1,25 @@
+import scala.reflect.macros.Context
+import language.experimental.macros
+
+object Interpolation {
+ implicit class TestInterpolation(c: StringContext) {
+ object t {
+ def unapply(x: Int) = macro Macros.unapplyImpl
+ }
+ }
+}
+
+object Macros {
+ def unapplyImpl(c: Context)(x: c.Tree) = {
+ import c.universe._
+ q"""
+ new {
+ class Match(x: Int) extends AnyVal {
+ def isEmpty = false
+ def get = x
+ }
+ def unapply(x: Int) = new Match(x)
+ }.unapply($x)
+ """
+ }
+}
diff --git a/test/files/neg/t5903e/Test_2.scala b/test/files/neg/t5903e/Test_2.scala
new file mode 100644
index 0000000000..d69d472436
--- /dev/null
+++ b/test/files/neg/t5903e/Test_2.scala
@@ -0,0 +1,6 @@
+class C {
+ import Interpolation._
+ 42 match {
+ case t"$x" => println(x)
+ }
+}
diff --git a/test/files/run/t5903a.check b/test/files/run/t5903a.check
new file mode 100644
index 0000000000..ce6efd812d
--- /dev/null
+++ b/test/files/run/t5903a.check
@@ -0,0 +1 @@
+(SomeTree,SomeTree)
diff --git a/test/files/run/t5903a.flags b/test/files/run/t5903a.flags
new file mode 100644
index 0000000000..02ecab49e7
--- /dev/null
+++ b/test/files/run/t5903a.flags
@@ -0,0 +1 @@
+-Xlog-reflective-calls \ No newline at end of file
diff --git a/test/files/run/t5903a/Macros_1.scala b/test/files/run/t5903a/Macros_1.scala
new file mode 100644
index 0000000000..e82be0fc68
--- /dev/null
+++ b/test/files/run/t5903a/Macros_1.scala
@@ -0,0 +1,28 @@
+import scala.reflect.macros.Context
+import language.experimental.macros
+
+trait Tree
+case object SomeTree extends Tree
+
+object NewQuasiquotes {
+ implicit class QuasiquoteInterpolation(c: StringContext) {
+ object nq {
+ def unapply(t: Tree) = macro QuasiquoteMacros.unapplyImpl
+ }
+ }
+}
+
+object QuasiquoteMacros {
+ def unapplyImpl(c: Context)(t: c.Tree) = {
+ import c.universe._
+ q"""
+ new {
+ def isEmpty = false
+ def get = this
+ def _1 = SomeTree
+ def _2 = SomeTree
+ def unapply(t: Tree) = this
+ }.unapply($t)
+ """
+ }
+}
diff --git a/test/files/run/t5903a/Test_2.scala b/test/files/run/t5903a/Test_2.scala
new file mode 100644
index 0000000000..3a0b68b568
--- /dev/null
+++ b/test/files/run/t5903a/Test_2.scala
@@ -0,0 +1,6 @@
+object Test extends App {
+ import NewQuasiquotes._
+ SomeTree match {
+ case nq"$x + $y" => println((x, y))
+ }
+}
diff --git a/test/files/run/t5903b.check b/test/files/run/t5903b.check
new file mode 100644
index 0000000000..75891bc672
--- /dev/null
+++ b/test/files/run/t5903b.check
@@ -0,0 +1 @@
+oops
diff --git a/test/files/run/t5903b.flags b/test/files/run/t5903b.flags
new file mode 100644
index 0000000000..02ecab49e7
--- /dev/null
+++ b/test/files/run/t5903b.flags
@@ -0,0 +1 @@
+-Xlog-reflective-calls \ No newline at end of file
diff --git a/test/files/run/t5903b/Macros_1.scala b/test/files/run/t5903b/Macros_1.scala
new file mode 100644
index 0000000000..c0124850b8
--- /dev/null
+++ b/test/files/run/t5903b/Macros_1.scala
@@ -0,0 +1,25 @@
+import scala.reflect.macros.Context
+import language.experimental.macros
+
+object Interpolation {
+ implicit class TestInterpolation(c: StringContext) {
+ object t {
+ def unapply[T](x: T) = macro Macros.unapplyImpl[T]
+ }
+ }
+}
+
+object Macros {
+ def unapplyImpl[T: c.WeakTypeTag](c: Context)(x: c.Tree) = {
+ import c.universe._
+ q"""
+ new {
+ def isEmpty = false
+ def get = this
+ def _1 = 2
+ def unapply(x: Int) = this
+ override def toString = "oops"
+ }.unapply($x)
+ """
+ }
+}
diff --git a/test/files/run/t5903b/Test_2.scala b/test/files/run/t5903b/Test_2.scala
new file mode 100644
index 0000000000..0f6f80d327
--- /dev/null
+++ b/test/files/run/t5903b/Test_2.scala
@@ -0,0 +1,6 @@
+object Test extends App {
+ import Interpolation._
+ 2 match {
+ case t"$x" => println(x)
+ }
+}
diff --git a/test/files/run/t5903c.check b/test/files/run/t5903c.check
new file mode 100644
index 0000000000..0cfbf08886
--- /dev/null
+++ b/test/files/run/t5903c.check
@@ -0,0 +1 @@
+2
diff --git a/test/files/run/t5903c.flags b/test/files/run/t5903c.flags
new file mode 100644
index 0000000000..02ecab49e7
--- /dev/null
+++ b/test/files/run/t5903c.flags
@@ -0,0 +1 @@
+-Xlog-reflective-calls \ No newline at end of file
diff --git a/test/files/run/t5903c/Macros_1.scala b/test/files/run/t5903c/Macros_1.scala
new file mode 100644
index 0000000000..f8baa2275b
--- /dev/null
+++ b/test/files/run/t5903c/Macros_1.scala
@@ -0,0 +1,23 @@
+import scala.reflect.macros.Context
+import language.experimental.macros
+
+object Interpolation {
+ implicit class TestInterpolation(c: StringContext) {
+ object t {
+ def unapply[T](x: T) = macro Macros.unapplyImpl[T]
+ }
+ }
+}
+
+object Macros {
+ def unapplyImpl[T: c.WeakTypeTag](c: Context)(x: c.Tree) = {
+ import c.universe._
+ q"""
+ new {
+ def isEmpty = false
+ def get = 2
+ def unapply(x: Int) = this
+ }.unapply($x)
+ """
+ }
+}
diff --git a/test/files/run/t5903c/Test_2.scala b/test/files/run/t5903c/Test_2.scala
new file mode 100644
index 0000000000..0f6f80d327
--- /dev/null
+++ b/test/files/run/t5903c/Test_2.scala
@@ -0,0 +1,6 @@
+object Test extends App {
+ import Interpolation._
+ 2 match {
+ case t"$x" => println(x)
+ }
+}
diff --git a/test/files/run/t5903d.check b/test/files/run/t5903d.check
new file mode 100644
index 0000000000..d81cc0710e
--- /dev/null
+++ b/test/files/run/t5903d.check
@@ -0,0 +1 @@
+42
diff --git a/test/files/run/t5903d.flags b/test/files/run/t5903d.flags
new file mode 100644
index 0000000000..02ecab49e7
--- /dev/null
+++ b/test/files/run/t5903d.flags
@@ -0,0 +1 @@
+-Xlog-reflective-calls \ No newline at end of file
diff --git a/test/files/run/t5903d/Macros_1.scala b/test/files/run/t5903d/Macros_1.scala
new file mode 100644
index 0000000000..88d714e17b
--- /dev/null
+++ b/test/files/run/t5903d/Macros_1.scala
@@ -0,0 +1,25 @@
+import scala.reflect.macros.Context
+import language.experimental.macros
+
+object Interpolation {
+ implicit class TestInterpolation(c: StringContext) {
+ object t {
+ def unapply(x: Int) = macro Macros.unapplyImpl
+ }
+ }
+}
+
+object Macros {
+ def unapplyImpl(c: Context)(x: c.Tree) = {
+ import c.universe._
+ q"""
+ new {
+ class Match(x: Int) {
+ def isEmpty = false
+ def get = x
+ }
+ def unapply(x: Int) = new Match(x)
+ }.unapply($x)
+ """
+ }
+}
diff --git a/test/files/run/t5903d/Test_2.scala b/test/files/run/t5903d/Test_2.scala
new file mode 100644
index 0000000000..95c717a9d8
--- /dev/null
+++ b/test/files/run/t5903d/Test_2.scala
@@ -0,0 +1,6 @@
+object Test extends App {
+ import Interpolation._
+ 42 match {
+ case t"$x" => println(x)
+ }
+}