diff options
author | Paul Phillips <paulp@improving.org> | 2013-01-25 16:39:39 -0800 |
---|---|---|
committer | Paul Phillips <paulp@improving.org> | 2013-01-25 18:16:40 -0800 |
commit | cc067e6508546d3b830422d57034210489a54151 (patch) | |
tree | b5dd29c21822f4dd6d3064dc1a734a45ca3a712c /src/compiler/scala/tools/nsc/transform/LambdaLift.scala | |
parent | 5abf901ea347fc0319c6a191454211f704d04961 (diff) | |
parent | 2fa859e1b3eb2ac57058feaba87d96adfbac9209 (diff) | |
download | scala-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.scala | 45 |
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. */ |