diff options
author | Paul Phillips <paulp@improving.org> | 2013-08-17 23:42:40 -0700 |
---|---|---|
committer | Paul Phillips <paulp@improving.org> | 2013-08-17 23:42:40 -0700 |
commit | a9efda40ee30796d3458604869a87a2c91f3efbf (patch) | |
tree | 7d1e685110c50ae37616c00f3c94450af03c4acc | |
parent | 22b82a485a53ffad3490673a481fbd79d616ed71 (diff) | |
parent | 84a335916556cb0fe939d1c51f27d80d9cf980dc (diff) | |
download | scala-a9efda40ee30796d3458604869a87a2c91f3efbf.tar.gz scala-a9efda40ee30796d3458604869a87a2c91f3efbf.tar.bz2 scala-a9efda40ee30796d3458604869a87a2c91f3efbf.zip |
Merge remote-tracking branch 'xeno-by/topic/patmat2' into patmat2
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) + } +} |