diff options
author | Paul Phillips <paulp@improving.org> | 2012-12-15 16:38:10 -0800 |
---|---|---|
committer | Paul Phillips <paulp@improving.org> | 2012-12-15 19:40:05 -0800 |
commit | 8aae61180c3edab97c653dbc7096a439f5c3da12 (patch) | |
tree | 83e392fdefa9de398f42b0aedb57376423ff0332 /src/compiler/scala/tools/nsc/symtab/classfile/Pickler.scala | |
parent | e14917528e1c080a7f10785e21de36f3a7769718 (diff) | |
download | scala-8aae61180c3edab97c653dbc7096a439f5c3da12.tar.gz scala-8aae61180c3edab97c653dbc7096a439f5c3da12.tar.bz2 scala-8aae61180c3edab97c653dbc7096a439f5c3da12.zip |
Deskolemize type skolems before pickling.
Lex Spoon noticed what appeared to be duplicate symbols
in methods read from classfiles. The duplicates turned out
to be type skolems, which because they're not supposed to
be pickled in the first place (right?) are unpickled
without turning back into skolems. Now pickler is careful
to deskolemize before writing anything down.
The effort implied by test case is more than can possibly
be justified for this obscure compiler corner, but I'll
chalk it up to reflection exploration.
Diffstat (limited to 'src/compiler/scala/tools/nsc/symtab/classfile/Pickler.scala')
-rw-r--r-- | src/compiler/scala/tools/nsc/symtab/classfile/Pickler.scala | 35 |
1 files changed, 33 insertions, 2 deletions
diff --git a/src/compiler/scala/tools/nsc/symtab/classfile/Pickler.scala b/src/compiler/scala/tools/nsc/symtab/classfile/Pickler.scala index caa45ea6db..efe7519d5e 100644 --- a/src/compiler/scala/tools/nsc/symtab/classfile/Pickler.scala +++ b/src/compiler/scala/tools/nsc/symtab/classfile/Pickler.scala @@ -148,9 +148,34 @@ abstract class Pickler extends SubComponent { true } + /** If the symbol is a type skolem, deskolemize and log it. + * If we fail to deskolemize, in a method like + * trait Trait[+A] { def f[CC[X]] : CC[A] } + * the applied type CC[A] will hold a different CC symbol + * than the type-constructor type-parameter CC. + */ + private def deskolemize(sym: Symbol) = { + if (sym.isTypeSkolem) { + val sym1 = sym.deSkolemize + log({ + val what0 = sym.defString + val what = sym1.defString match { + case `what0` => what0 + case other => what0 + "->" + other + } + val where = sym.enclMethod.fullLocationString + s"deskolemizing $what in $where" + }) + sym1 + } + else sym + } + /** Store symbol in index. If symbol is local, also store everything it references. */ - def putSymbol(sym: Symbol) { + def putSymbol(sym0: Symbol) { + val sym = deskolemize(sym0) + if (putEntry(sym)) { if (isLocal(sym)) { putEntry(sym.name) @@ -503,7 +528,13 @@ abstract class Pickler extends SubComponent { /** Write a reference to object, i.e., the object's number in the map index. */ - private def writeRef(ref: AnyRef) { writeNat(index(ref)) } + private def writeRef(ref0: AnyRef) { + val ref = ref0 match { + case sym: Symbol => deskolemize(sym) + case _ => ref0 + } + writeNat(index(ref)) + } private def writeRefs(refs: List[AnyRef]) { refs foreach writeRef } private def writeRefsWithLength(refs: List[AnyRef]) { writeNat(refs.length) |