summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLukas Rytz <lukas.rytz@gmail.com>2016-10-26 17:41:42 +0200
committerLukas Rytz <lukas.rytz@gmail.com>2016-10-27 10:42:03 +0200
commit69fc725abf7690ea73a02f44f285d192491468b4 (patch)
tree165d9cf351288249854a2913eee2b97deac32fb4
parent5751763261312bfadabb91b15b3ed826648023af (diff)
downloadscala-69fc725abf7690ea73a02f44f285d192491468b4.tar.gz
scala-69fc725abf7690ea73a02f44f285d192491468b4.tar.bz2
scala-69fc725abf7690ea73a02f44f285d192491468b4.zip
Robustly identify unpickling the current module class
When unpickling a class, if the name and owner matches the current `classRoot` of the unpickling Scan, that `classRoot` symbol is used instead of creating a new symbol. If, in addition, the class being unpickled has the MODULE flag, the unpickler should use the `moduleRoot.moduleClass` symbol (instead of creating a new one). To identify the module class, the current implementation compares the name and owner to the `classRoot`. This fails in case the `classRoot` is `NoSymbol`, which can happen in corner cases (when a type alias shadows a class symbol, scala-dev#248). In this patch we identify the module class by comparing the name and owner to the `moduleRoot` symbol directly (using a `toTypeName`).
-rw-r--r--src/reflect/scala/reflect/internal/pickling/UnPickler.scala22
1 files changed, 11 insertions, 11 deletions
diff --git a/src/reflect/scala/reflect/internal/pickling/UnPickler.scala b/src/reflect/scala/reflect/internal/pickling/UnPickler.scala
index 3a80ee2ccf..c335bf0f47 100644
--- a/src/reflect/scala/reflect/internal/pickling/UnPickler.scala
+++ b/src/reflect/scala/reflect/internal/pickling/UnPickler.scala
@@ -294,10 +294,11 @@ abstract class UnPickler {
case Right(sym) => sym -> readNat()
}
- def isModuleFlag = (flags & MODULE) != 0L
- def isClassRoot = (name == classRoot.name) && (owner == classRoot.owner)
- def isModuleRoot = (name == moduleRoot.name) && (owner == moduleRoot.owner)
- def pflags = flags & PickledFlags
+ def isModuleFlag = (flags & MODULE) != 0L
+ def isClassRoot = (name == classRoot.name) && (owner == classRoot.owner)
+ def isModuleRoot = (name == moduleRoot.name) && (owner == moduleRoot.owner)
+ def isModuleClassRoot = (name == moduleRoot.name.toTypeName) && (owner == moduleRoot.owner)
+ def pflags = flags & PickledFlags
def finishSym(sym: Symbol): Symbol = {
/**
@@ -342,18 +343,17 @@ abstract class UnPickler {
finishSym(tag match {
case TYPEsym | ALIASsym =>
owner.newNonClassSymbol(name.toTypeName, NoPosition, pflags)
+
case CLASSsym =>
- val sym = (
- if (isClassRoot) {
- if (isModuleFlag) moduleRoot.moduleClass setFlag pflags
- else classRoot setFlag pflags
- }
+ val sym = {
+ if (isModuleFlag && isModuleClassRoot) moduleRoot.moduleClass setFlag pflags
+ else if (!isModuleFlag && isClassRoot) classRoot setFlag pflags
else owner.newClassSymbol(name.toTypeName, NoPosition, pflags)
- )
+ }
if (!atEnd)
sym.typeOfThis = newLazyTypeRef(readNat())
-
sym
+
case MODULEsym =>
val clazz = at(inforef, () => readType()).typeSymbol // after NMT_TRANSITION, we can leave off the () => ... ()
if (isModuleRoot) moduleRoot setFlag pflags