From f83296552aa80faf8a9350131c0448bc05b34c96 Mon Sep 17 00:00:00 2001 From: Eugene Burmako Date: Wed, 2 Oct 2013 17:22:17 +0200 Subject: blackbox restriction #4: can't customize pattern matching When an application of a blackbox macro is used as an extractor in a pattern match, it triggers an unconditional compiler error, preventing customizations of pattern matching implemented with macros. --- .../scala/tools/nsc/typechecker/PatternTypers.scala | 7 ++++--- test/files/neg/macro-blackbox-extractor.check | 4 ++++ .../neg/macro-blackbox-extractor/Macros_1.scala | 21 +++++++++++++++++++++ .../files/neg/macro-blackbox-extractor/Test_2.scala | 5 +++++ test/files/neg/t5903d.check | 2 +- test/files/run/macro-whitebox-extractor.check | 1 + .../run/macro-whitebox-extractor/Macros_1.scala | 21 +++++++++++++++++++++ .../files/run/macro-whitebox-extractor/Test_2.scala | 5 +++++ 8 files changed, 62 insertions(+), 4 deletions(-) create mode 100644 test/files/neg/macro-blackbox-extractor.check create mode 100644 test/files/neg/macro-blackbox-extractor/Macros_1.scala create mode 100644 test/files/neg/macro-blackbox-extractor/Test_2.scala create mode 100644 test/files/run/macro-whitebox-extractor.check create mode 100644 test/files/run/macro-whitebox-extractor/Macros_1.scala create mode 100644 test/files/run/macro-whitebox-extractor/Test_2.scala diff --git a/src/compiler/scala/tools/nsc/typechecker/PatternTypers.scala b/src/compiler/scala/tools/nsc/typechecker/PatternTypers.scala index f69b8a9697..ba135d7d25 100644 --- a/src/compiler/scala/tools/nsc/typechecker/PatternTypers.scala +++ b/src/compiler/scala/tools/nsc/typechecker/PatternTypers.scala @@ -409,9 +409,10 @@ trait PatternTypers { if (fun1.tpe.isErroneous) duplErrTree - else if (unapplyMethod.isMacro && !fun1.isInstanceOf[Apply]) - duplErrorTree(WrongShapeExtractorExpansion(tree)) - else + else if (unapplyMethod.isMacro && !fun1.isInstanceOf[Apply]) { + if (isBlackbox(unapplyMethod)) duplErrorTree(BlackboxExtractorExpansion(tree)) + else duplErrorTree(WrongShapeExtractorExpansion(tree)) + } else makeTypedUnApply() } diff --git a/test/files/neg/macro-blackbox-extractor.check b/test/files/neg/macro-blackbox-extractor.check new file mode 100644 index 0000000000..4c53ff19b8 --- /dev/null +++ b/test/files/neg/macro-blackbox-extractor.check @@ -0,0 +1,4 @@ +Test_2.scala:3: error: extractor macros can only be whitebox + case Extractor(x) => println(x) + ^ +one error found diff --git a/test/files/neg/macro-blackbox-extractor/Macros_1.scala b/test/files/neg/macro-blackbox-extractor/Macros_1.scala new file mode 100644 index 0000000000..5c7748bec9 --- /dev/null +++ b/test/files/neg/macro-blackbox-extractor/Macros_1.scala @@ -0,0 +1,21 @@ +import scala.reflect.macros.BlackboxContext +import language.experimental.macros + +object Extractor { + def unapply(x: Int) = macro Macros.unapplyImpl +} + +object Macros { + def unapplyImpl(c: BlackboxContext)(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/neg/macro-blackbox-extractor/Test_2.scala b/test/files/neg/macro-blackbox-extractor/Test_2.scala new file mode 100644 index 0000000000..41be6f9767 --- /dev/null +++ b/test/files/neg/macro-blackbox-extractor/Test_2.scala @@ -0,0 +1,5 @@ +object Test extends App { + 42 match { + case Extractor(x) => println(x) + } +} diff --git a/test/files/neg/t5903d.check b/test/files/neg/t5903d.check index 9b8526b7f5..54a91a7ba6 100644 --- a/test/files/neg/t5903d.check +++ b/test/files/neg/t5903d.check @@ -1,4 +1,4 @@ -Test_2.scala:4: error: extractor macros can only expand into extractor calls +Test_2.scala:4: error: extractor macros can only be whitebox case t"$x" => println(x) ^ one error found diff --git a/test/files/run/macro-whitebox-extractor.check b/test/files/run/macro-whitebox-extractor.check new file mode 100644 index 0000000000..d81cc0710e --- /dev/null +++ b/test/files/run/macro-whitebox-extractor.check @@ -0,0 +1 @@ +42 diff --git a/test/files/run/macro-whitebox-extractor/Macros_1.scala b/test/files/run/macro-whitebox-extractor/Macros_1.scala new file mode 100644 index 0000000000..4a1138fc9d --- /dev/null +++ b/test/files/run/macro-whitebox-extractor/Macros_1.scala @@ -0,0 +1,21 @@ +import scala.reflect.macros.WhiteboxContext +import language.experimental.macros + +object Extractor { + def unapply(x: Int) = macro Macros.unapplyImpl +} + +object Macros { + def unapplyImpl(c: WhiteboxContext)(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/macro-whitebox-extractor/Test_2.scala b/test/files/run/macro-whitebox-extractor/Test_2.scala new file mode 100644 index 0000000000..41be6f9767 --- /dev/null +++ b/test/files/run/macro-whitebox-extractor/Test_2.scala @@ -0,0 +1,5 @@ +object Test extends App { + 42 match { + case Extractor(x) => println(x) + } +} -- cgit v1.2.3