summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorPaul Phillips <paulp@improving.org>2012-02-13 21:55:15 -0800
committerPaul Phillips <paulp@improving.org>2012-02-13 23:17:31 -0800
commiteb8556ca663de9bf77514eab6e63f0a2f7599413 (patch)
tree478db0a6e25c20961559fffc3f7d562644a8eb98 /src
parent57758b518b2409ea0cc1aa0be7853025aa053ab8 (diff)
downloadscala-eb8556ca663de9bf77514eab6e63f0a2f7599413.tar.gz
scala-eb8556ca663de9bf77514eab6e63f0a2f7599413.tar.bz2
scala-eb8556ca663de9bf77514eab6e63f0a2f7599413.zip
Fix for SI-5444.
Fix for trait/impl renaming in 5cbd7d06eb was incomplete. Looks more complete now.
Diffstat (limited to 'src')
-rw-r--r--src/compiler/scala/reflect/internal/Symbols.scala9
-rw-r--r--src/compiler/scala/tools/nsc/transform/AddInterfaces.scala5
-rw-r--r--src/compiler/scala/tools/nsc/transform/LambdaLift.scala31
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Namers.scala2
4 files changed, 32 insertions, 15 deletions
diff --git a/src/compiler/scala/reflect/internal/Symbols.scala b/src/compiler/scala/reflect/internal/Symbols.scala
index 69d881e8e1..77ed2f6a1b 100644
--- a/src/compiler/scala/reflect/internal/Symbols.scala
+++ b/src/compiler/scala/reflect/internal/Symbols.scala
@@ -1704,6 +1704,7 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
* (which is always the interface, by convention)
* - before erasure, it looks up the interface name in the scope of the owner of the class.
* This only works for implementation classes owned by other classes or traits.
+ * !!! Why?
*/
final def toInterface: Symbol =
if (isImplClass) {
@@ -2080,6 +2081,8 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
def infosString = infos.toString()
+ def debugLocationString = fullLocationString + " " + debugFlagString
+ def debugFlagString = hasFlagsToString(-1L)
def hasFlagsToString(mask: Long): String = flagsToString(
flags & mask,
if (hasAccessBoundary) privateWithin.toString else ""
@@ -2178,7 +2181,7 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
}
def setLazyAccessor(sym: Symbol): TermSymbol = {
- assert(isLazy && (referenced == NoSymbol || referenced == sym), (this, hasFlagsToString(-1L), referenced, sym))
+ assert(isLazy && (referenced == NoSymbol || referenced == sym), (this, debugFlagString, referenced, sym))
referenced = sym
this
}
@@ -2319,7 +2322,7 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
/** Overridden in subclasses for which it makes sense.
*/
- def existentialBound: Type = abort("unexpected type: "+this.getClass+ " "+this.fullLocationString+ " " + hasFlagsToString(-1L))
+ def existentialBound: Type = abort("unexpected type: "+this.getClass+ " "+debugLocationString)
override def name: TypeName = super.name.asInstanceOf[TypeName]
final override def isType = true
@@ -2327,7 +2330,7 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
override def isAbstractType = {
if (settings.debug.value) {
if (isDeferred) {
- println("TypeSymbol claims to be abstract type: " + this.getClass + " " + hasFlagsToString(-1L) + " at ")
+ println("TypeSymbol claims to be abstract type: " + this.getClass + " " + debugFlagString + " at ")
(new Throwable).printStackTrace
}
}
diff --git a/src/compiler/scala/tools/nsc/transform/AddInterfaces.scala b/src/compiler/scala/tools/nsc/transform/AddInterfaces.scala
index e01bbccf13..b4ec8a23ce 100644
--- a/src/compiler/scala/tools/nsc/transform/AddInterfaces.scala
+++ b/src/compiler/scala/tools/nsc/transform/AddInterfaces.scala
@@ -94,7 +94,6 @@ abstract class AddInterfaces extends InfoTransform {
// error: java.lang.AssertionError: assertion failed: (scala.tools.nsc.typechecker.Contexts$NoContext$,scala.tools.nsc.typechecker.Contexts,NoContext$,trait Contexts in package typechecker) / while parsing (/scala/trunk/build/pack/lib/scala-compiler.jar(scala/tools/nsc/interactive/ContextTrees$class.class),Some(class ContextTrees$class))trait Contexts.NoContext$ linkedModule: <none>List()
val originalImpl = impl
- val originalImplString = originalImpl.hasFlagsToString(-1L)
if (impl != NoSymbol) {
// Unlink a pre-existing symbol only if the implementation class is
// visible on the compilation classpath. In general this is true under
@@ -120,8 +119,8 @@ abstract class AddInterfaces extends InfoTransform {
impl setInfo new LazyImplClassType(iface)
implClassMap(iface) = impl
debuglog(
- "generating impl class " + impl + " " + impl.hasFlagsToString(-1L) + " in " + iface.owner + (
- if (originalImpl == NoSymbol) "" else " (cloned from " + originalImpl.fullLocationString + " " + originalImplString + ")"
+ "generating impl class " + impl.debugLocationString + " in " + iface.owner + (
+ if (originalImpl == NoSymbol) "" else " (cloned from " + originalImpl.debugLocationString + ")"
)
)
impl
diff --git a/src/compiler/scala/tools/nsc/transform/LambdaLift.scala b/src/compiler/scala/tools/nsc/transform/LambdaLift.scala
index 712298bd89..4fc7b9f92f 100644
--- a/src/compiler/scala/tools/nsc/transform/LambdaLift.scala
+++ b/src/compiler/scala/tools/nsc/transform/LambdaLift.scala
@@ -65,7 +65,10 @@ abstract class LambdaLift extends InfoTransform {
/** The set of symbols that need to be renamed. */
private val renamable = newSymSet
- private val renamableImplClasses = mutable.HashMap[Name, Symbol]() withDefaultValue NoSymbol
+ // (trait, name) -> owner
+ private val localTraits = mutable.HashMap[(Symbol, Name), Symbol]()
+ // (owner, name) -> implClass
+ private val localImplClasses = mutable.HashMap[(Symbol, Name), Symbol]()
/** A flag to indicate whether new free variables have been found */
private var changedFreeVars: Boolean = _
@@ -167,8 +170,13 @@ abstract class LambdaLift extends InfoTransform {
// arrangements, and then have separate methods which attempt to compensate
// for that failure. There should be exactly one method for any given
// entity which always gives the right answer.
- if (sym.isImplClass) renamableImplClasses(nme.interfaceName(sym.name)) = sym
- else renamable addEntry sym
+ if (sym.isImplClass)
+ localImplClasses((sym.owner, nme.interfaceName(sym.name))) = sym
+ else {
+ renamable addEntry sym
+ if (sym.isTrait)
+ localTraits((sym, sym.name)) = sym.owner
+ }
}
case DefDef(_, _, _, _, _, _) =>
if (sym.isLocal) {
@@ -237,14 +245,21 @@ abstract class LambdaLift extends InfoTransform {
debuglog("renaming impl class in step with %s: %s => %s".format(traitSym, originalImplName, implSym.name))
}
-
+
for (sym <- renamable) {
// If we renamed a trait from Foo to Foo$1, we must rename the implementation
// class from Foo$class to Foo$1$class. (Without special consideration it would
- // become Foo$class$1 instead.)
- val implClass = if (sym.isTrait) renamableImplClasses(sym.name) else NoSymbol
- if ((implClass ne NoSymbol) && (sym.owner == implClass.owner)) renameTrait(sym, implClass)
- else renameSym(sym)
+ // become Foo$class$1 instead.) Since the symbols are being renamed out from
+ // under us, and there's no reliable link between trait symbol and impl symbol,
+ // we have maps from ((trait, name)) -> owner and ((owner, name)) -> impl.
+ localTraits remove ((sym, sym.name)) match {
+ case None => renameSym(sym)
+ case Some(owner) =>
+ localImplClasses remove ((owner, sym.name)) match {
+ case Some(implSym) => renameTrait(sym, implSym)
+ case _ => renameSym(sym) // pure interface, no impl class
+ }
+ }
}
atPhase(phase.next) {
diff --git a/src/compiler/scala/tools/nsc/typechecker/Namers.scala b/src/compiler/scala/tools/nsc/typechecker/Namers.scala
index 0ff2b418f4..51542ec757 100644
--- a/src/compiler/scala/tools/nsc/typechecker/Namers.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/Namers.scala
@@ -282,7 +282,7 @@ trait Namers extends MethodSynthesis {
}
private def logAssignSymbol(tree: Tree, sym: Symbol): Symbol = {
- log("[+symbol] " + sym.hasFlagsToString(-1L) + " " + sym)
+ log("[+symbol] " + sym.debugLocationString)
tree.symbol = sym
sym
}