diff options
author | Martin Odersky <odersky@gmail.com> | 2015-04-07 21:25:28 +0200 |
---|---|---|
committer | Martin Odersky <odersky@gmail.com> | 2015-04-07 23:53:59 +0200 |
commit | 2d45d5b23983fa20b353fc83ba4e9b8585e5f662 (patch) | |
tree | 4afd64b342070cb621147eaa064225e6e383fc9a /src/dotty/tools/dotc/core/pickling/TreePickler.scala | |
parent | 3b53a8300f09c11a9fc889dbe59061a6941d21cc (diff) | |
download | dotty-2d45d5b23983fa20b353fc83ba4e9b8585e5f662.tar.gz dotty-2d45d5b23983fa20b353fc83ba4e9b8585e5f662.tar.bz2 dotty-2d45d5b23983fa20b353fc83ba4e9b8585e5f662.zip |
Change of TERMREFsymbol/TYPEREFsymbol semantics
Used to be "with fixed sym". Now it is: With initial symbol
as given in the serialized info.
It turns out the only previous uses of (TERM|TYPE)REFsymbol were
types that were made symbolic in self types. But exactly that caused
that problems in unpickling which we tried to workaround by changing
WithFixedSym#newLikeThis. And these fixes became less and less intuitive and
still could not solve the problem for good. Last hurdle was pickle-testing
all files in ast together.
It's much simpler to reserve (TERM|TYPE)REFsymbol for NamedTypes that have
an initial symbol. Like the previous "WithFixedSym" pickling, this avoids
inifinite recursions in pickling/extmethods.scala. But it also avoids problens
with unpickling ast/*.scala. The reason it is better is that it more accurately
models that types that exist before pickling.
This change also undoes previous changes to WithFixedSym#newlikeThis. Better to keep
the more restrictive contract for these.
Diffstat (limited to 'src/dotty/tools/dotc/core/pickling/TreePickler.scala')
-rw-r--r-- | src/dotty/tools/dotc/core/pickling/TreePickler.scala | 49 |
1 files changed, 18 insertions, 31 deletions
diff --git a/src/dotty/tools/dotc/core/pickling/TreePickler.scala b/src/dotty/tools/dotc/core/pickling/TreePickler.scala index 14a92e8e6..85addc563 100644 --- a/src/dotty/tools/dotc/core/pickling/TreePickler.scala +++ b/src/dotty/tools/dotc/core/pickling/TreePickler.scala @@ -32,20 +32,6 @@ class TreePickler(pickler: TastyPickler) { symRefs.get(sym) } - private var makeSymbolicRefsTo: Symbol = NoSymbol - - /** All references to members of class `sym` are pickled - * as symbolic references. Used to pickle the self info of a class. - * Without this precaution we get an infinite cycle when unpickling pos/extmethods.scala - * The problem arises when a self type of a trait is a type parameter of the same trait. - */ - private def withSymbolicRefsTo[T](sym: Symbol)(op: => T): T = { - val saved = makeSymbolicRefsTo - makeSymbolicRefsTo = sym - try op - finally makeSymbolicRefsTo = saved - } - def preRegister(tree: Tree)(implicit ctx: Context): Unit = tree match { case tree: MemberDef => if (!symRefs.contains(tree.symbol)) symRefs(tree.symbol) = NoAddr @@ -88,6 +74,11 @@ class TreePickler(pickler: TastyPickler) { assert(!sym.is(Flags.Package), sym) forwardSymRefs(sym) = ref :: forwardSymRefs.getOrElse(sym, Nil) } + + private def isLocallyDefined(sym: Symbol)(implicit ctx: Context) = symRefs.get(sym) match { + case Some(label) => assert(sym.exists); label != NoAddr + case None => false + } def pickle(trees: List[Tree])(implicit ctx: Context) = { @@ -162,7 +153,8 @@ class TreePickler(pickler: TastyPickler) { writeByte(if (tpe.isType) TYPEREFpkg else TERMREFpkg) pickleName(qualifiedName(sym)) } - else if (tpe.prefix == NoPrefix) { + else { + assert(tpe.prefix == NoPrefix) def pickleRef() = { writeByte(if (tpe.isType) TYPEREFdirect else TERMREFdirect) pickleSymRef(sym) @@ -178,10 +170,6 @@ class TreePickler(pickler: TastyPickler) { } else pickleRef() } - else { - writeByte(if (tpe.isType) TYPEREFsymbol else TERMREFsymbol) - pickleSymRef(sym); pickleType(tpe.prefix) - } case tpe: TermRefWithSignature => writeByte(TERMREF) pickleNameAndSig(tpe.name, tpe.signature); pickleType(tpe.prefix) @@ -190,12 +178,13 @@ class TreePickler(pickler: TastyPickler) { // instantiated lambdas are pickled as APPLIEDTYPE; #Apply will // be reconstituted when unpickling. pickleType(tpe.prefix) - else tpe.prefix match { - case prefix: ThisType if prefix.cls == makeSymbolicRefsTo => - pickleType(NamedType.withFixedSym(tpe.prefix, tpe.symbol)) - case _ => - writeByte(if (tpe.isType) TYPEREF else TERMREF) - pickleName(tpe.name); pickleType(tpe.prefix) + else if (isLocallyDefined(tpe.symbol)) { + writeByte(if (tpe.isType) TYPEREFsymbol else TERMREFsymbol) + pickleSymRef(tpe.symbol); pickleType(tpe.prefix) + } + else { + writeByte(if (tpe.isType) TYPEREF else TERMREF) + pickleName(tpe.name); pickleType(tpe.prefix) } case tpe: ThisType => writeByte(THIS) @@ -432,12 +421,10 @@ class TreePickler(pickler: TastyPickler) { if ((selfInfo ne NoType) || !tree.self.isEmpty) { writeByte(SELFDEF) pickleName(tree.self.name) - withSymbolicRefsTo(tree.symbol.owner) { - pickleType { - cinfo.selfInfo match { - case sym: Symbol => sym.info - case tp: Type => tp - } + pickleType { + cinfo.selfInfo match { + case sym: Symbol => sym.info + case tp: Type => tp } } } |