summaryrefslogtreecommitdiff
path: root/src/reflect
diff options
context:
space:
mode:
authorLukas Rytz <lukas.rytz@typesafe.com>2014-07-09 16:33:54 +0200
committerLukas Rytz <lukas.rytz@typesafe.com>2014-07-09 16:33:54 +0200
commitaea6519685561ee076e7fdaac48c2bf970389b83 (patch)
treed8e37b54a6cc5196a555a05df7ce2ddc0200dfe4 /src/reflect
parent4d3ede90b599a344b6d88316a7f62472ef8520e2 (diff)
parent14fa7bef120cbb996d042daba6095530167c49ed (diff)
downloadscala-aea6519685561ee076e7fdaac48c2bf970389b83.tar.gz
scala-aea6519685561ee076e7fdaac48c2bf970389b83.tar.bz2
scala-aea6519685561ee076e7fdaac48c2bf970389b83.zip
Merge pull request #3867 from lrytz/t8708
SI-8708 Fix pickling of LOCAL_CHILD child of sealed classes
Diffstat (limited to 'src/reflect')
-rw-r--r--src/reflect/scala/reflect/internal/pickling/UnPickler.scala42
1 files changed, 37 insertions, 5 deletions
diff --git a/src/reflect/scala/reflect/internal/pickling/UnPickler.scala b/src/reflect/scala/reflect/internal/pickling/UnPickler.scala
index 64a1a44722..b808666360 100644
--- a/src/reflect/scala/reflect/internal/pickling/UnPickler.scala
+++ b/src/reflect/scala/reflect/internal/pickling/UnPickler.scala
@@ -290,6 +290,25 @@ abstract class UnPickler {
def pflags = flags & PickledFlags
def finishSym(sym: Symbol): Symbol = {
+ /**
+ * member symbols (symbols owned by a class) are added to the class's scope, with a number
+ * of exceptions:
+ *
+ * (.) ...
+ * (1) `local child` represents local child classes, see comment in Pickler.putSymbol.
+ * Since it is not a member, it should not be entered in the owner's scope.
+ */
+ def shouldEnterInOwnerScope = {
+ sym.owner.isClass &&
+ sym != classRoot &&
+ sym != moduleRoot &&
+ !sym.isModuleClass &&
+ !sym.isRefinementClass &&
+ !sym.isTypeParameter &&
+ !sym.isExistentiallyBound &&
+ sym.rawname != tpnme.LOCAL_CHILD // (1)
+ }
+
markFlagsCompleted(sym)(mask = AllFlags)
sym.privateWithin = privateWithin
sym.info = (
@@ -302,8 +321,7 @@ abstract class UnPickler {
newLazyTypeRefAndAlias(inforef, readNat())
}
)
- if (sym.owner.isClass && sym != classRoot && sym != moduleRoot &&
- !sym.isModuleClass && !sym.isRefinementClass && !sym.isTypeParameter && !sym.isExistentiallyBound)
+ if (shouldEnterInOwnerScope)
symScope(sym.owner) enter sym
sym
@@ -681,10 +699,24 @@ abstract class UnPickler {
private val p = phase
protected def completeInternal(sym: Symbol) : Unit = try {
val tp = at(i, () => readType(sym.isTerm)) // after NMT_TRANSITION, revert `() => readType(sym.isTerm)` to `readType`
- if (p ne null)
- slowButSafeEnteringPhase(p) (sym setInfo tp)
+
+ // This is a temporary fix allowing to read classes generated by an older, buggy pickler.
+ // See the generation of the LOCAL_CHILD class in Pickler.scala. In an earlier version, the
+ // pickler did not add the ObjectTpe superclass, it used a trait as the first parent. This
+ // tripped an assertion in AddInterfaces which checks that the first parent is not a trait.
+ // This workaround can probably be removed in 2.12, because the 2.12 compiler is supposed
+ // to only read classfiles generated by 2.12.
+ val fixLocalChildTp = if (sym.rawname == tpnme.LOCAL_CHILD) tp match {
+ case ClassInfoType(superClass :: traits, decls, typeSymbol) if superClass.typeSymbol.isTrait =>
+ ClassInfoType(definitions.ObjectTpe :: superClass :: traits, decls, typeSymbol)
+ case _ => tp
+ } else tp
+
+ if (p ne null) {
+ slowButSafeEnteringPhase(p)(sym setInfo fixLocalChildTp)
+ }
if (currentRunId != definedAtRunId)
- sym.setInfo(adaptToNewRunMap(tp))
+ sym.setInfo(adaptToNewRunMap(fixLocalChildTp))
}
catch {
case e: MissingRequirementError => throw toTypeError(e)