From 548a54d708d8aaceea6abe0931aabaa70b2cd925 Mon Sep 17 00:00:00 2001 From: Your Name Date: Thu, 22 Nov 2012 20:45:50 +0100 Subject: SI-6023 reify abstract vals Type trees created by MethodSynthesis for abstract val getters carry symless originals, which are unusable for reification purposes (or the result of reification will be unhygienic). To combat this, type trees for such getters are now created empty, i.e. without any `tpe` set, just having an original assigned. Subsequent `typedTypeTree` invocations fill in the `tpe` and update the original to be symful. --- .../scala/tools/nsc/typechecker/MethodSynthesis.scala | 1 + src/compiler/scala/tools/nsc/typechecker/Typers.scala | 10 ++++++++-- test/files/run/t6023.check | 12 ++++++++++++ test/files/run/t6023.scala | 17 +++++++++++++++++ 4 files changed, 38 insertions(+), 2 deletions(-) create mode 100644 test/files/run/t6023.check create mode 100644 test/files/run/t6023.scala diff --git a/src/compiler/scala/tools/nsc/typechecker/MethodSynthesis.scala b/src/compiler/scala/tools/nsc/typechecker/MethodSynthesis.scala index e8a2c9f43c..acc4f7ff67 100644 --- a/src/compiler/scala/tools/nsc/typechecker/MethodSynthesis.scala +++ b/src/compiler/scala/tools/nsc/typechecker/MethodSynthesis.scala @@ -426,6 +426,7 @@ trait MethodSynthesis { // spot that brand of them. In other words it's an artifact of the implementation. val tpt = derivedSym.tpe.finalResultType match { case ExistentialType(_, _) => TypeTree() + case _ if mods.isDeferred => TypeTree() case tp => TypeTree(tp) } tpt setPos derivedSym.pos.focus diff --git a/src/compiler/scala/tools/nsc/typechecker/Typers.scala b/src/compiler/scala/tools/nsc/typechecker/Typers.scala index 222c9ff8c3..a2aca45e8f 100644 --- a/src/compiler/scala/tools/nsc/typechecker/Typers.scala +++ b/src/compiler/scala/tools/nsc/typechecker/Typers.scala @@ -5368,8 +5368,14 @@ trait Typers extends Modes with Adaptations with Tags { } def typedTypeTree(tree: TypeTree) = { - if (tree.original != null) - tree setType typedType(tree.original, mode).tpe + if (tree.original != null) { + val newTpt = typedType(tree.original, mode) + tree setType newTpt.tpe + newTpt match { + case tt @ TypeTree() => tree setOriginal tt.original + case _ => tree + } + } else // we should get here only when something before failed // and we try again (@see tryTypedApply). In that case we can assign diff --git a/test/files/run/t6023.check b/test/files/run/t6023.check new file mode 100644 index 0000000000..ee93565234 --- /dev/null +++ b/test/files/run/t6023.check @@ -0,0 +1,12 @@ +{ + abstract trait Foo extends AnyRef { + def a: Int + }; + () +} +{ + abstract trait Foo extends AnyRef { + def a: Int + }; + () +} diff --git a/test/files/run/t6023.scala b/test/files/run/t6023.scala new file mode 100644 index 0000000000..07af3685a5 --- /dev/null +++ b/test/files/run/t6023.scala @@ -0,0 +1,17 @@ +import scala.reflect.runtime.universe._ +import scala.reflect.runtime.{currentMirror => cm} +import scala.tools.reflect.ToolBox + +object Test extends App { + // test 1: reify + val tree = reify{ trait Foo { val a: Int } }.tree + println(tree.toString) + + // test 2: import and typecheck + val toolbox = cm.mkToolBox() + val ttree = toolbox.typeCheck(tree) + println(ttree.toString) + + // test 3: import and compile + toolbox.eval(tree) +} -- cgit v1.2.3