diff options
author | Martin Odersky <odersky@gmail.com> | 2014-08-27 08:55:21 +0200 |
---|---|---|
committer | Martin Odersky <odersky@gmail.com> | 2014-08-27 08:55:21 +0200 |
commit | 292ce6844a212b47defc671c91396d7cec86833b (patch) | |
tree | 43c4576fc6b2e05e4f7552106bbdb57e13fdf06b /src/dotty/tools/dotc/core/Types.scala | |
parent | 08c6eacaf59386ed26aeead472e1df2c5944a3fb (diff) | |
download | dotty-292ce6844a212b47defc671c91396d7cec86833b.tar.gz dotty-292ce6844a212b47defc671c91396d7cec86833b.tar.bz2 dotty-292ce6844a212b47defc671c91396d7cec86833b.zip |
Rebinding ThisTypes
ThisTypes do escape. It seems that Scala 2 pickling produces ThisTypes that refer to base
classes of the class being compiled. If the base class is in a separate compilation unit,
this can lead to a stale class symbol in the ThisType. We solve this here by rebinding the
class symbol in the ThisType. We should also explore the alternative:
class ThisType(tref: TypeRef) ...
That would do the rebinding as part of the generation denotation resolution mechanism.
Diffstat (limited to 'src/dotty/tools/dotc/core/Types.scala')
-rw-r--r-- | src/dotty/tools/dotc/core/Types.scala | 23 |
1 files changed, 19 insertions, 4 deletions
diff --git a/src/dotty/tools/dotc/core/Types.scala b/src/dotty/tools/dotc/core/Types.scala index a6ba7d9a0..787c7c4e9 100644 --- a/src/dotty/tools/dotc/core/Types.scala +++ b/src/dotty/tools/dotc/core/Types.scala @@ -1535,16 +1535,31 @@ object Types { // --- Other SingletonTypes: ThisType/SuperType/ConstantType --------------------------- /** The type cls.this */ - abstract case class ThisType(cls: ClassSymbol) extends CachedProxyType with SingletonType { - override def underlying(implicit ctx: Context) = cls.classInfo.selfType - override def computeHash = doHash(cls) + abstract case class ThisType(private var myCls: ClassSymbol) extends CachedProxyType with SingletonType { + def cls(implicit ctx: Context): ClassSymbol = + try myCls.denot.symbol.asClass + catch { + case ex: StaleSymbol => + def prevDenot(implicit ctx: Context) = myCls.denot + val prev = prevDenot(ctx.fresh.setPeriod(Period(myCls.defRunId, ctx.phaseId))) + myCls = prev.owner.info.member(prev.name).symbol.asClass + cls + } + override def underlying(implicit ctx: Context) = + try cls.classInfo.selfType + catch { + case ex: StaleSymbol => + println(i"stale symbol when deref ${cls.id}") + throw ex + } + override def computeHash = doHash(myCls) } final class CachedThisType(cls: ClassSymbol) extends ThisType(cls) // TODO: consider hash before constructing types? object ThisType { - def apply(cls: ClassSymbol)(implicit ctx: Context) = + def raw(cls: ClassSymbol)(implicit ctx: Context) = unique(new CachedThisType(cls)) } |