aboutsummaryrefslogtreecommitdiff
path: root/src/dotty/tools/dotc/core/Types.scala
diff options
context:
space:
mode:
authorMartin Odersky <odersky@gmail.com>2014-08-27 08:55:21 +0200
committerMartin Odersky <odersky@gmail.com>2014-08-27 08:55:21 +0200
commit292ce6844a212b47defc671c91396d7cec86833b (patch)
tree43c4576fc6b2e05e4f7552106bbdb57e13fdf06b /src/dotty/tools/dotc/core/Types.scala
parent08c6eacaf59386ed26aeead472e1df2c5944a3fb (diff)
downloaddotty-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.scala23
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))
}