diff options
author | Lukas Rytz <lukas.rytz@gmail.com> | 2016-10-26 17:41:42 +0200 |
---|---|---|
committer | Lukas Rytz <lukas.rytz@gmail.com> | 2016-10-27 10:42:03 +0200 |
commit | 69fc725abf7690ea73a02f44f285d192491468b4 (patch) | |
tree | 165d9cf351288249854a2913eee2b97deac32fb4 /src/reflect | |
parent | 5751763261312bfadabb91b15b3ed826648023af (diff) | |
download | scala-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`).
Diffstat (limited to 'src/reflect')
-rw-r--r-- | src/reflect/scala/reflect/internal/pickling/UnPickler.scala | 22 |
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 |