diff options
author | Lukas Rytz <lukas.rytz@gmail.com> | 2016-10-26 17:21:02 +0200 |
---|---|---|
committer | Lukas Rytz <lukas.rytz@gmail.com> | 2016-10-27 10:42:00 +0200 |
commit | 5751763261312bfadabb91b15b3ed826648023af (patch) | |
tree | 4191dce74832537fb22c17d295f800c5809d6d2b /src/reflect | |
parent | 762bcdcd7fcdf75d7645b4d8a3d14a2d60ed1fd0 (diff) | |
download | scala-5751763261312bfadabb91b15b3ed826648023af.tar.gz scala-5751763261312bfadabb91b15b3ed826648023af.tar.bz2 scala-5751763261312bfadabb91b15b3ed826648023af.zip |
Classfile parser and unpickler require class and module symbol arguments
In SymbolLoaders, when seeing a classfile `Foo.class`, we always
(unconditionally) create 3 symbols: a class, a module and a module
class. Some symbols get invalidated later (`.exists`).
Until now, the classfile parser (and unpickler) received the "root"
symbol as argument, which is the symbol whose type is being completed.
This is either the class symbol or the module symbol.
The classfile parser would then try to lookup the other symbol through
`root.companionClass` or `root.companionModule`. Howver, this lookup can
fail. One example is scala-dev#248: when a type alias (in a package
object) shadows a class symbol, `companionClass` will fail.
The implementations of the classfile parser / unpickler assume that
both the `clazz` and the `staticModule` symbols are available. This
change makes sure that they are always passed in explicitly.
Before this patch, in the example of scala-dev#248, the `classRoot` of
the unpickler was NoSymbol. This caused a bug when unpickling the
module class symbol, causing a second module class symbol to be created
mistakingly. The next commit cleans up this logic, more details there.
This second symbol would then cause the crash in the backend because it
doesn't have an `associatedFile`, therefore `isCoDefinedWith` would
spuriously return `true`.
Diffstat (limited to 'src/reflect')
-rw-r--r-- | src/reflect/scala/reflect/internal/pickling/UnPickler.scala | 5 |
1 files changed, 3 insertions, 2 deletions
diff --git a/src/reflect/scala/reflect/internal/pickling/UnPickler.scala b/src/reflect/scala/reflect/internal/pickling/UnPickler.scala index c6cb0d0223..3a80ee2ccf 100644 --- a/src/reflect/scala/reflect/internal/pickling/UnPickler.scala +++ b/src/reflect/scala/reflect/internal/pickling/UnPickler.scala @@ -29,12 +29,13 @@ abstract class UnPickler { * from an array of bytes. * @param bytes bytearray from which we unpickle * @param offset offset from which unpickling starts - * @param classRoot the top-level class which is unpickled, or NoSymbol if inapplicable - * @param moduleRoot the top-level module which is unpickled, or NoSymbol if inapplicable + * @param classRoot the top-level class which is unpickled + * @param moduleRoot the top-level module which is unpickled * @param filename filename associated with bytearray, only used for error messages */ def unpickle(bytes: Array[Byte], offset: Int, classRoot: Symbol, moduleRoot: Symbol, filename: String) { try { + assert(classRoot != NoSymbol && moduleRoot != NoSymbol, s"The Unpickler expects a class and module symbol: $classRoot - $moduleRoot") new Scan(bytes, offset, classRoot, moduleRoot, filename).run() } catch { case ex: IOException => |