summaryrefslogtreecommitdiff
path: root/test/files/run
diff options
context:
space:
mode:
authorLukas Rytz <lukas.rytz@epfl.ch>2013-02-12 12:32:20 +0100
committerJason Zaugg <jzaugg@gmail.com>2013-02-21 11:22:14 +0100
commitdafebd040e938208e26a27dbd1e14c0307021cf0 (patch)
tree67cd2823fa35d229e405e1c2bf924faf53357a50 /test/files/run
parentcc89bd71edfd4c88ca1099891e6c20b77379122a (diff)
downloadscala-dafebd040e938208e26a27dbd1e14c0307021cf0.tar.gz
scala-dafebd040e938208e26a27dbd1e14c0307021cf0.tar.bz2
scala-dafebd040e938208e26a27dbd1e14c0307021cf0.zip
Fix typing idempotency bug with Annotated trees
typedAnnotated transforms an Annotated tree into a Typed tree. The original field of the result is set to the Annotated tree. The bug was that typedAnnotated was using the untyped Annotated tree as original, but also set its type. When re-typing later on the same Annotated tree, the typer would consider it as alreadyTyped. This is incorrect, the typer needs to convert Annotated trees to Typed. Also, the Annotated tree only had its type field set, but its children were still untyped. This crashed the compiler lateron, non-typed trees would get out of the typing phase.
Diffstat (limited to 'test/files/run')
-rw-r--r--test/files/run/annotatedRetyping.check6
-rw-r--r--test/files/run/annotatedRetyping.scala62
2 files changed, 68 insertions, 0 deletions
diff --git a/test/files/run/annotatedRetyping.check b/test/files/run/annotatedRetyping.check
new file mode 100644
index 0000000000..b296a80526
--- /dev/null
+++ b/test/files/run/annotatedRetyping.check
@@ -0,0 +1,6 @@
+typing List(1, 2).map(((x) => {
+ val another = scala.Tuple2(t.nt, t.tr): @testAnn match {
+ case scala.Tuple2(_, _) => 1
+ };
+ x
+}))
diff --git a/test/files/run/annotatedRetyping.scala b/test/files/run/annotatedRetyping.scala
new file mode 100644
index 0000000000..cf1b0f27b5
--- /dev/null
+++ b/test/files/run/annotatedRetyping.scala
@@ -0,0 +1,62 @@
+import scala.tools.partest._
+import scala.tools.nsc._
+
+object Test extends DirectTest {
+
+ override def extraSettings: String = "-usejavacp"
+
+ def code = """
+ class testAnn extends annotation.Annotation
+
+ object t {
+ def nt = 1
+ def tr = "a"
+ }
+
+ class Test {
+ List(1,2).map(x => {
+ val another = ((t.nt, t.tr): @testAnn) match { case (_, _) => 1 }
+ x
+ })
+ }
+ """.trim
+
+
+ // point of this test: type-check the "Annotated" tree twice. first time the analyzer plugin types it,
+ // second time the typer.
+
+ // bug was that typedAnnotated assigned a type to the Annotated tree. The second type check would consider
+ // the tree as alreadyTyped, which is not cool, the Annotated needs to be transformed into a Typed tree.
+
+ def show() {
+ val global = newCompiler()
+ import global._
+ import analyzer._
+ import collection.{mutable => m}
+
+ object analyzerPlugin extends AnalyzerPlugin {
+ val templates: m.Map[Symbol, (Template, Typer)] = m.Map()
+ override def pluginsTypeSig(tpe: Type, typer: Typer, defTree: Tree, pt: Type): Type = {
+ defTree match {
+ case impl: Template =>
+ templates += typer.context.owner -> (impl, typer)
+
+ case dd: DefDef if dd.symbol.isPrimaryConstructor && templates.contains(dd.symbol.owner) =>
+ val (impl, templTyper) = templates(dd.symbol.owner)
+ for (stat <- impl.body.filterNot(_.isDef)) {
+ println("typing "+ stat)
+ val statsOwner = impl.symbol orElse templTyper.context.owner.newLocalDummy(impl.pos)
+ val tpr = analyzer.newTyper(templTyper.context.make(stat, statsOwner))
+ tpr.typed(stat)
+ }
+
+ case _ =>
+ }
+ tpe
+ }
+ }
+
+ addAnalyzerPlugin(analyzerPlugin)
+ compileString(global)(code)
+ }
+}