summaryrefslogtreecommitdiff
path: root/src/compiler/scala/tools/nsc/transform/LambdaLift.scala
diff options
context:
space:
mode:
authorPaul Phillips <paulp@improving.org>2013-01-25 16:39:39 -0800
committerPaul Phillips <paulp@improving.org>2013-01-25 18:16:40 -0800
commitcc067e6508546d3b830422d57034210489a54151 (patch)
treeb5dd29c21822f4dd6d3064dc1a734a45ca3a712c /src/compiler/scala/tools/nsc/transform/LambdaLift.scala
parent5abf901ea347fc0319c6a191454211f704d04961 (diff)
parent2fa859e1b3eb2ac57058feaba87d96adfbac9209 (diff)
downloadscala-cc067e6508546d3b830422d57034210489a54151.tar.gz
scala-cc067e6508546d3b830422d57034210489a54151.tar.bz2
scala-cc067e6508546d3b830422d57034210489a54151.zip
Merge remote-tracking branch 'origin/2.10.x' into pr/merge-2.10
* origin/2.10.x: SI-6969, mishandling of SoftReferences in method cache. SI-7011 Fix finding constructor type in captured var definitions SI-6987 Tests fsc verbose output SI-6987 Fixes fsc compile server verbose output SI-6231 Report unsupported free var capture by a trait. SI-6666 Restrict hidden `this` access in self/super calls. SI-6902 Check unreachability under @unchecked SI-6976 Fix value class separate compilation crasher. Closes SI-6952: add correct error positions for Dynamic feature check. Conflicts: src/compiler/scala/tools/nsc/CompileServer.scala src/compiler/scala/tools/nsc/transform/ExtensionMethods.scala
Diffstat (limited to 'src/compiler/scala/tools/nsc/transform/LambdaLift.scala')
-rw-r--r--src/compiler/scala/tools/nsc/transform/LambdaLift.scala45
1 files changed, 35 insertions, 10 deletions
diff --git a/src/compiler/scala/tools/nsc/transform/LambdaLift.scala b/src/compiler/scala/tools/nsc/transform/LambdaLift.scala
index b081fb7e3f..f8172743b5 100644
--- a/src/compiler/scala/tools/nsc/transform/LambdaLift.scala
+++ b/src/compiler/scala/tools/nsc/transform/LambdaLift.scala
@@ -320,12 +320,24 @@ abstract class LambdaLift extends InfoTransform {
private def memberRef(sym: Symbol) = {
val clazz = sym.owner.enclClass
//Console.println("memberRef from "+currentClass+" to "+sym+" in "+clazz)
- val qual = if (clazz == currentClass) gen.mkAttributedThis(clazz)
- else {
- sym resetFlag(LOCAL | PRIVATE)
- if (clazz.isStaticOwner) gen.mkAttributedQualifier(clazz.thisType)
- else outerPath(outerValue, currentClass.outerClass, clazz)
- }
+ def prematureSelfReference() {
+ val what =
+ if (clazz.isStaticOwner) clazz.fullLocationString
+ else s"the unconstructed `this` of ${clazz.fullLocationString}"
+ val msg = s"Implementation restriction: access of ${sym.fullLocationString} from ${currentClass.fullLocationString}, would require illegal premature access to $what"
+ currentUnit.error(curTree.pos, msg)
+ }
+ val qual =
+ if (clazz == currentClass) gen.mkAttributedThis(clazz)
+ else {
+ sym resetFlag (LOCAL | PRIVATE)
+ if (selfOrSuperCalls exists (_.owner == clazz)) {
+ prematureSelfReference()
+ EmptyTree
+ }
+ else if (clazz.isStaticOwner) gen.mkAttributedQualifier(clazz.thisType)
+ else outerPath(outerValue, currentClass.outerClass, clazz)
+ }
Select(qual, sym) setType sym.tpe
}
@@ -352,6 +364,7 @@ abstract class LambdaLift extends InfoTransform {
copyDefDef(tree)(vparamss = List(vparams ++ freeParams))
case ClassDef(_, _, _, _) =>
+ // SI-6231
// Disabled attempt to to add getters to freeParams
// this does not work yet. Problem is that local symbols need local names
// and references to local symbols need to be transformed into
@@ -369,7 +382,7 @@ abstract class LambdaLift extends InfoTransform {
tree
}
-/* Something like this will be necessary to eliminate the implementation
+/* SI-6231: Something like this will be necessary to eliminate the implementation
* restiction from paramGetter above:
* We need to pass getters to the interface of an implementation class.
private def fixTraitGetters(lifted: List[Tree]): List[Tree] =
@@ -430,10 +443,10 @@ abstract class LambdaLift extends InfoTransform {
/* Creating a constructor argument if one isn't present. */
val constructorArg = rhs match {
case EmptyTree =>
- sym.primaryConstructor.info.paramTypes match {
+ sym.tpe.typeSymbol.primaryConstructor.info.paramTypes match {
case List(tp) => gen.mkZero(tp)
case _ =>
- log("Couldn't determine how to properly construct " + sym)
+ debugwarn("Couldn't determine how to properly construct " + sym)
rhs
}
case arg => arg
@@ -495,13 +508,25 @@ abstract class LambdaLift extends InfoTransform {
private def preTransform(tree: Tree) = super.transform(tree) setType lifted(tree.tpe)
+ /** The stack of constructor symbols in which a call to this() or to the super
+ * constructor is active.
+ */
+ private val selfOrSuperCalls = mutable.Stack[Symbol]()
+ @inline private def inSelfOrSuperCall[A](sym: Symbol)(a: => A) = try {
+ selfOrSuperCalls push sym
+ a
+ } finally selfOrSuperCalls.pop()
+
override def transform(tree: Tree): Tree = tree match {
case Select(ReferenceToBoxed(idt), elem) if elem == nme.elem =>
postTransform(preTransform(idt), isBoxedRef = false)
case ReferenceToBoxed(idt) =>
postTransform(preTransform(idt), isBoxedRef = true)
case _ =>
- postTransform(preTransform(tree))
+ def transformTree = postTransform(preTransform(tree))
+ if (treeInfo isSelfOrSuperConstrCall tree)
+ inSelfOrSuperCall(currentOwner)(transformTree)
+ else transformTree
}
/** Transform statements and add lifted definitions to them. */