aboutsummaryrefslogtreecommitdiff
path: root/src/dotty/tools/dotc/core/pickling/TreePickler.scala
diff options
context:
space:
mode:
authorMartin Odersky <odersky@gmail.com>2015-04-07 21:25:28 +0200
committerMartin Odersky <odersky@gmail.com>2015-04-07 23:53:59 +0200
commit2d45d5b23983fa20b353fc83ba4e9b8585e5f662 (patch)
tree4afd64b342070cb621147eaa064225e6e383fc9a /src/dotty/tools/dotc/core/pickling/TreePickler.scala
parent3b53a8300f09c11a9fc889dbe59061a6941d21cc (diff)
downloaddotty-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.scala49
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
}
}
}