summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGrzegorz Kossakowski <grzegorz.kossakowski@gmail.com>2014-09-18 09:25:38 +0200
committerGrzegorz Kossakowski <grzegorz.kossakowski@gmail.com>2014-09-18 09:25:38 +0200
commit2c23a5e70288c4b00c8c06c6ae5b6e65eede6ac0 (patch)
treec4cee58684aee2831dc8b14b73207b83207d8ecf
parent190c6726158f3f7e1ac5d26782437c184cee5872 (diff)
parent3b35177e7620da91e8c77ed5d16ef168b64e58b8 (diff)
downloadscala-2c23a5e70288c4b00c8c06c6ae5b6e65eede6ac0.tar.gz
scala-2c23a5e70288c4b00c8c06c6ae5b6e65eede6ac0.tar.bz2
scala-2c23a5e70288c4b00c8c06c6ae5b6e65eede6ac0.zip
Merge pull request #3974 from xeno-by/topic/buffer-pattern-expander-errors
This ensures that typechecking custom unapplications in silent mode
-rw-r--r--src/compiler/scala/tools/nsc/transform/UnCurry.scala2
-rw-r--r--src/compiler/scala/tools/nsc/transform/patmat/MatchTranslation.scala4
-rw-r--r--src/compiler/scala/tools/nsc/transform/patmat/ScalacPatternExpanders.scala17
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/PatternTypers.scala2
-rw-r--r--test/files/pos/t8719.check0
-rw-r--r--test/files/pos/t8719/Macros_1.scala21
-rw-r--r--test/files/pos/t8719/Test_2.scala10
7 files changed, 44 insertions, 12 deletions
diff --git a/src/compiler/scala/tools/nsc/transform/UnCurry.scala b/src/compiler/scala/tools/nsc/transform/UnCurry.scala
index 9b85f1b36a..3544dc9966 100644
--- a/src/compiler/scala/tools/nsc/transform/UnCurry.scala
+++ b/src/compiler/scala/tools/nsc/transform/UnCurry.scala
@@ -459,7 +459,7 @@ abstract class UnCurry extends InfoTransform
case UnApply(fn, args) =>
val fn1 = transform(fn)
val args1 = fn.symbol.name match {
- case nme.unapplySeq => transformArgs(tree.pos, fn.symbol, args, patmat.alignPatterns(tree).expectedTypes)
+ case nme.unapplySeq => transformArgs(tree.pos, fn.symbol, args, patmat.alignPatterns(global.typer.context, tree).expectedTypes)
case _ => args
}
treeCopy.UnApply(tree, fn1, args1)
diff --git a/src/compiler/scala/tools/nsc/transform/patmat/MatchTranslation.scala b/src/compiler/scala/tools/nsc/transform/patmat/MatchTranslation.scala
index 0eaffe7cee..d862805a07 100644
--- a/src/compiler/scala/tools/nsc/transform/patmat/MatchTranslation.scala
+++ b/src/compiler/scala/tools/nsc/transform/patmat/MatchTranslation.scala
@@ -377,8 +377,8 @@ trait MatchTranslation {
object ExtractorCall {
// TODO: check unargs == args
def apply(tree: Tree): ExtractorCall = tree match {
- case UnApply(unfun, args) => new ExtractorCallRegular(alignPatterns(tree), unfun, args) // extractor
- case Apply(fun, args) => new ExtractorCallProd(alignPatterns(tree), fun, args) // case class
+ case UnApply(unfun, args) => new ExtractorCallRegular(alignPatterns(context, tree), unfun, args) // extractor
+ case Apply(fun, args) => new ExtractorCallProd(alignPatterns(context, tree), fun, args) // case class
}
}
diff --git a/src/compiler/scala/tools/nsc/transform/patmat/ScalacPatternExpanders.scala b/src/compiler/scala/tools/nsc/transform/patmat/ScalacPatternExpanders.scala
index 8f21f4ecfc..79f5e3bee8 100644
--- a/src/compiler/scala/tools/nsc/transform/patmat/ScalacPatternExpanders.scala
+++ b/src/compiler/scala/tools/nsc/transform/patmat/ScalacPatternExpanders.scala
@@ -18,6 +18,7 @@ trait ScalacPatternExpanders {
import global._
import definitions._
import treeInfo._
+ import analyzer._
type PatternAligned = ScalacPatternExpander#Aligned
@@ -94,7 +95,7 @@ trait ScalacPatternExpanders {
def tupleExtractor(extractor: Extractor): Extractor =
extractor.copy(fixed = tupleType(extractor.fixed) :: Nil)
- private def validateAligned(tree: Tree, aligned: Aligned): Aligned = {
+ private def validateAligned(context: Context, tree: Tree, aligned: Aligned): Aligned = {
import aligned._
def owner = tree.symbol.owner
@@ -103,8 +104,8 @@ trait ScalacPatternExpanders {
def offerString = if (extractor.isErroneous) "" else s" offering $offering"
def arityExpected = ( if (extractor.hasSeq) "at least " else "" ) + productArity
- def err(msg: String) = reporter.error(tree.pos, msg)
- def warn(msg: String) = reporter.warning(tree.pos, msg)
+ def err(msg: String) = context.error(tree.pos, msg)
+ def warn(msg: String) = context.warning(tree.pos, msg)
def arityError(what: String) = err(s"$what patterns for $owner$offerString: expected $arityExpected, found $totalArity")
if (isStar && !isSeq)
@@ -117,7 +118,7 @@ trait ScalacPatternExpanders {
aligned
}
- def apply(sel: Tree, args: List[Tree]): Aligned = {
+ def apply(context: Context, sel: Tree, args: List[Tree]): Aligned = {
val fn = sel match {
case Unapplied(fn) => fn
case _ => sel
@@ -145,12 +146,12 @@ trait ScalacPatternExpanders {
}
val normalizedExtractor = if (requiresTupling) tupleExtractor(extractor) else extractor
- validateAligned(fn, Aligned(patterns, normalizedExtractor))
+ validateAligned(context, fn, Aligned(patterns, normalizedExtractor))
}
- def apply(tree: Tree): Aligned = tree match {
- case Apply(fn, args) => apply(fn, args)
- case UnApply(fn, args) => apply(fn, args)
+ def apply(context: Context, tree: Tree): Aligned = tree match {
+ case Apply(fn, args) => apply(context, fn, args)
+ case UnApply(fn, args) => apply(context, fn, args)
}
}
}
diff --git a/src/compiler/scala/tools/nsc/typechecker/PatternTypers.scala b/src/compiler/scala/tools/nsc/typechecker/PatternTypers.scala
index da0e67a2a5..bb8c3c3c6d 100644
--- a/src/compiler/scala/tools/nsc/typechecker/PatternTypers.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/PatternTypers.scala
@@ -309,7 +309,7 @@ trait PatternTypers {
// the union of the expected type and the inferred type of the argument to unapply
val glbType = glb(ensureFullyDefined(pt) :: unapplyArg.tpe_* :: Nil)
val wrapInTypeTest = canRemedy && !(fun1.symbol.owner isNonBottomSubClass ClassTagClass)
- val formals = patmat.alignPatterns(fun1, args).unexpandedFormals
+ val formals = patmat.alignPatterns(context.asInstanceOf[analyzer.Context], fun1, args).unexpandedFormals
val args1 = typedArgsForFormals(args, formals, mode)
val result = UnApply(fun1, args1) setPos tree.pos setType glbType
diff --git a/test/files/pos/t8719.check b/test/files/pos/t8719.check
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/test/files/pos/t8719.check
diff --git a/test/files/pos/t8719/Macros_1.scala b/test/files/pos/t8719/Macros_1.scala
new file mode 100644
index 0000000000..152c92f254
--- /dev/null
+++ b/test/files/pos/t8719/Macros_1.scala
@@ -0,0 +1,21 @@
+import scala.language.experimental.macros
+import scala.reflect.macros.TypecheckException
+import scala.reflect.macros.whitebox.Context
+
+object Macros {
+ def typecheck_impl(c: Context)(code: c.Expr[String]): c.Expr[Option[String]] = {
+ import c.universe._
+
+ val Expr(Literal(Constant(codeStr: String))) = code
+
+ try {
+ c.typecheck(c.parse(codeStr))
+ c.Expr(q"None: Option[String]")
+ } catch {
+ case e: TypecheckException =>
+ c.Expr(q"Some(${ e.toString }): Option[String]")
+ }
+ }
+
+ def typecheck(code: String): Option[String] = macro typecheck_impl
+} \ No newline at end of file
diff --git a/test/files/pos/t8719/Test_2.scala b/test/files/pos/t8719/Test_2.scala
new file mode 100644
index 0000000000..997eb2f236
--- /dev/null
+++ b/test/files/pos/t8719/Test_2.scala
@@ -0,0 +1,10 @@
+case class Foo(i: Int, c: Char)
+
+object Bar {
+ def unapply(foo: Foo): Option[(Int, Char)] = Some((foo.i, foo.c))
+}
+
+object Test extends App {
+ println(Macros.typecheck("val Foo(x, y, z) = Foo(1, 'a')"))
+ println(Macros.typecheck("val Bar(x, y, z) = Foo(1, 'a')"))
+} \ No newline at end of file