aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/dotty/tools/dotc/ast/Trees.scala2
-rw-r--r--src/dotty/tools/dotc/ast/tpd.scala8
-rw-r--r--src/dotty/tools/dotc/core/Substituters.scala4
-rw-r--r--src/dotty/tools/dotc/core/SymDenotations.scala21
-rw-r--r--src/dotty/tools/dotc/core/TypeComparer.scala18
-rw-r--r--src/dotty/tools/dotc/core/TypeOps.scala6
-rw-r--r--src/dotty/tools/dotc/core/Types.scala39
-rw-r--r--src/dotty/tools/dotc/core/pickling/UnPickler.scala8
-rw-r--r--src/dotty/tools/dotc/printing/PlainPrinter.scala4
-rw-r--r--src/dotty/tools/dotc/printing/RefinedPrinter.scala10
-rw-r--r--src/dotty/tools/dotc/transform/Splitter.scala4
-rw-r--r--src/dotty/tools/dotc/transform/SuperAccessors.scala2
-rw-r--r--src/dotty/tools/dotc/typer/Checking.scala2
-rw-r--r--src/dotty/tools/dotc/typer/TypeAssigner.scala2
14 files changed, 64 insertions, 66 deletions
diff --git a/src/dotty/tools/dotc/ast/Trees.scala b/src/dotty/tools/dotc/ast/Trees.scala
index 554517cd7..49294718b 100644
--- a/src/dotty/tools/dotc/ast/Trees.scala
+++ b/src/dotty/tools/dotc/ast/Trees.scala
@@ -387,7 +387,7 @@ object Trees {
type ThisTree[-T >: Untyped] <: DenotingTree[T]
override def denot(implicit ctx: Context) = tpe match {
case tpe: NamedType => tpe.denot
- case ThisType(cls) => cls.denot
+ case tpe: ThisType => tpe.cls.denot
case _ => NoDenotation
}
}
diff --git a/src/dotty/tools/dotc/ast/tpd.scala b/src/dotty/tools/dotc/ast/tpd.scala
index 7bddd49f4..7208d4560 100644
--- a/src/dotty/tools/dotc/ast/tpd.scala
+++ b/src/dotty/tools/dotc/ast/tpd.scala
@@ -255,9 +255,9 @@ object tpd extends Trees.Instance[Type] with TypedTreeInfo {
def prefixIsElidable(tp: NamedType)(implicit ctx: Context) = tp.prefix match {
case NoPrefix =>
true
- case ThisType(cls) =>
- cls.isStaticOwner ||
- tp.symbol.is(ParamOrAccessor) && tp.symbol.maybeOwner.enclosingClass == cls
+ case pre: ThisType =>
+ pre.cls.isStaticOwner ||
+ tp.symbol.is(ParamOrAccessor) && tp.symbol.maybeOwner.enclosingClass == pre.cls
case pre: TermRef =>
pre.symbol.is(Module) && pre.symbol.isStatic
case _ =>
@@ -283,7 +283,7 @@ object tpd extends Trees.Instance[Type] with TypedTreeInfo {
def singleton(tp: Type)(implicit ctx: Context): Tree = tp match {
case tp: TermRef => ref(tp)
- case ThisType(cls) => This(cls)
+ case tp: ThisType => This(tp.cls)
case SuperType(qual, _) => singleton(qual)
case ConstantType(value) => Literal(value)
}
diff --git a/src/dotty/tools/dotc/core/Substituters.scala b/src/dotty/tools/dotc/core/Substituters.scala
index e05f76cd9..fdcc077b3 100644
--- a/src/dotty/tools/dotc/core/Substituters.scala
+++ b/src/dotty/tools/dotc/core/Substituters.scala
@@ -163,8 +163,8 @@ trait Substituters { this: Context =>
final def substThis(tp: Type, from: ClassSymbol, to: Type, theMap: SubstThisMap): Type =
tp match {
- case tp @ ThisType(clazz) =>
- if (clazz eq from) to else tp
+ case tp: ThisType =>
+ if (tp.cls eq from) to else tp
case tp: NamedType =>
if (tp.symbol.isStaticOwner) tp
else tp.derivedSelect(substThis(tp.prefix, from, to, theMap))
diff --git a/src/dotty/tools/dotc/core/SymDenotations.scala b/src/dotty/tools/dotc/core/SymDenotations.scala
index cb457bd73..660287089 100644
--- a/src/dotty/tools/dotc/core/SymDenotations.scala
+++ b/src/dotty/tools/dotc/core/SymDenotations.scala
@@ -471,9 +471,8 @@ object SymDenotations {
* or, if this symbol is protected, a subclass of the owner?
*/
def isCorrectThisType(pre: Type): Boolean = pre match {
- case ThisType(pclazz) =>
- (pclazz eq owner) ||
- (this is Protected) && pclazz.derivesFrom(owner)
+ case pre: ThisType =>
+ (pre.cls eq owner) || (this is Protected) && pre.cls.derivesFrom(owner)
case pre: TermRef =>
pre.symbol.moduleClass == owner
case _ =>
@@ -1000,18 +999,26 @@ object SymDenotations {
private[this] var myThisType: Type = null
+ /** The this-type depends on the kind of class:
+ * - for a package class `p`: ThisType(TypeRef(Noprefix, p))
+ * - for a module class `m`: A term ref to m's source module.
+ * - for all other classes `c` with owner `o`: ThisType(TypeRef(o.thisType, c))
+ */
override def thisType(implicit ctx: Context): Type = {
if (myThisType == null) myThisType = computeThisType
myThisType
}
private def computeThisType(implicit ctx: Context): Type =
- if (this.is(Module, butNot = Package)) {
+ if (this is Package)
+ ThisType.raw(TypeRef(NoPrefix, symbol.asType))
+ else {
val pre = owner.thisType
- if ((pre eq NoPrefix) || ctx.erasedTypes) pre select sourceModule
- else TermRef.withSig(pre, name.sourceModuleName, Signature.NotAMethod)
+ if (this is Module)
+ if (isMissing(pre)) TermRef(pre, sourceModule.asTerm)
+ else TermRef.withSig(pre, name.sourceModuleName, Signature.NotAMethod)
+ else ThisType.raw(TypeRef(pre, symbol.asType))
}
- else ThisType.raw(classSymbol)
private[this] var myTypeRef: TypeRef = null
diff --git a/src/dotty/tools/dotc/core/TypeComparer.scala b/src/dotty/tools/dotc/core/TypeComparer.scala
index 29f6dda69..fda9667e9 100644
--- a/src/dotty/tools/dotc/core/TypeComparer.scala
+++ b/src/dotty/tools/dotc/core/TypeComparer.scala
@@ -323,7 +323,7 @@ class TypeComparer(initctx: Context) extends DotClass {
}
tp.prefix match {
case RefinedThis(rt) => rebaseFrom(rt)
- case ThisType(cls) => rebaseFrom(cls.info)
+ case pre: ThisType => rebaseFrom(pre.cls.info)
case _ => tp
}
}
@@ -443,11 +443,11 @@ class TypeComparer(initctx: Context) extends DotClass {
// We treat two prefixes A.this, B.this as equivalent if
// A's selftype derives from B and B's selftype derives from A.
def equivalentThisTypes(tp1: Type, tp2: Type) = tp1 match {
- case ThisType(cls1) =>
+ case tp1: ThisType =>
tp2 match {
- case ThisType(cls2) =>
- cls1.classInfo.selfType.derivesFrom(cls2) &&
- cls2.classInfo.selfType.derivesFrom(cls1)
+ case tp2: ThisType =>
+ tp1.cls.classInfo.selfType.derivesFrom(tp2.cls) &&
+ tp2.cls.classInfo.selfType.derivesFrom(tp1.cls)
case _ => false
}
case _ => false
@@ -483,8 +483,8 @@ class TypeComparer(initctx: Context) extends DotClass {
)
else (tp1.name eq tp2.name) && isSameType(tp1.prefix, tp2.prefix)
) || isHKSubType || secondTryNamed(tp1, tp2)
- case ThisType(cls) if cls eq tp2.symbol.moduleClass =>
- isSubType(cls.owner.thisType, tp2.prefix)
+ case tp1: ThisType if tp1.cls eq tp2.symbol.moduleClass =>
+ isSubType(tp1.cls.owner.thisType, tp2.prefix)
case _ =>
isHKSubType || secondTry(tp1, tp2)
}
@@ -529,8 +529,8 @@ class TypeComparer(initctx: Context) extends DotClass {
def secondTry(tp1: Type, tp2: Type): Boolean = tp1 match {
case tp1: NamedType =>
tp2 match {
- case ThisType(cls) if cls eq tp1.symbol.moduleClass =>
- isSubType(tp1.prefix, cls.owner.thisType)
+ case tp2: ThisType if tp2.cls eq tp1.symbol.moduleClass =>
+ isSubType(tp1.prefix, tp2.cls.owner.thisType)
case _ =>
secondTryNamed(tp1, tp2)
}
diff --git a/src/dotty/tools/dotc/core/TypeOps.scala b/src/dotty/tools/dotc/core/TypeOps.scala
index f9ff42709..efd7fcca3 100644
--- a/src/dotty/tools/dotc/core/TypeOps.scala
+++ b/src/dotty/tools/dotc/core/TypeOps.scala
@@ -30,8 +30,8 @@ trait TypeOps { this: Context =>
val sym = tp.symbol
if (sym.isStatic) tp
else tp.derivedSelect(asSeenFrom(tp.prefix, pre, cls, theMap))
- case ThisType(thiscls) =>
- toPrefix(pre, cls, thiscls)
+ case tp: ThisType =>
+ toPrefix(pre, cls, tp.cls)
case _: BoundType | NoPrefix =>
tp
case tp: RefinedType =>
@@ -224,7 +224,7 @@ trait TypeOps { this: Context =>
*/
def forwardRef(argSym: Symbol, from: Symbol, to: TypeBounds, cls: ClassSymbol, decls: Scope) =
argSym.info match {
- case info @ TypeBounds(lo2 @ TypeRef(ThisType(_), name), hi2) =>
+ case info @ TypeBounds(lo2 @ TypeRef(_: ThisType, name), hi2) =>
if (name == from.name &&
(lo2 eq hi2) &&
info.variance == to.variance &&
diff --git a/src/dotty/tools/dotc/core/Types.scala b/src/dotty/tools/dotc/core/Types.scala
index 787c7c4e9..e09d54a23 100644
--- a/src/dotty/tools/dotc/core/Types.scala
+++ b/src/dotty/tools/dotc/core/Types.scala
@@ -1416,7 +1416,7 @@ object Types {
if (ctx.phase.erasedTypes) NoPrefix else prefix
/** Is the prefix seen at current phase the same as NoPrefix? */
- private def isMissing(prefix: Type)(implicit ctx: Context) =
+ def isMissing(prefix: Type)(implicit ctx: Context) =
(prefix eq NoPrefix) || ctx.phase.erasedTypes
/** Assert current phase does not have erasure semantics */
@@ -1534,33 +1534,24 @@ object Types {
// --- Other SingletonTypes: ThisType/SuperType/ConstantType ---------------------------
- /** The type cls.this */
- 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)
+ /** The type cls.this
+ * @param tref A type ref which indicates the class `cls`.
+ * Note: we do not pass a class symbol directly, because symbols
+ * do not survive runs whereas typerefs do.
+ */
+ abstract case class ThisType(tref: TypeRef) extends CachedProxyType with SingletonType {
+ def cls(implicit ctx: Context): ClassSymbol = tref.symbol.asClass
+ override def underlying(implicit ctx: Context): Type =
+ if (ctx.erasedTypes) tref else cls.classInfo.selfType
+ override def computeHash = doHash(tref)
}
- final class CachedThisType(cls: ClassSymbol) extends ThisType(cls)
+ final class CachedThisType(tref: TypeRef) extends ThisType(tref)
- // TODO: consider hash before constructing types?
object ThisType {
- def raw(cls: ClassSymbol)(implicit ctx: Context) =
- unique(new CachedThisType(cls))
+ /** Normally one should use ClassSymbol#thisType instead */
+ def raw(tref: TypeRef)(implicit ctx: Context) =
+ unique(new CachedThisType(tref))
}
/** The type of a super reference cls.super where
diff --git a/src/dotty/tools/dotc/core/pickling/UnPickler.scala b/src/dotty/tools/dotc/core/pickling/UnPickler.scala
index e82002c9f..b80e2322a 100644
--- a/src/dotty/tools/dotc/core/pickling/UnPickler.scala
+++ b/src/dotty/tools/dotc/core/pickling/UnPickler.scala
@@ -629,18 +629,18 @@ class UnPickler(bytes: Array[Byte], classRoot: ClassDenotation, moduleClassRoot:
var pre = readTypeRef()
val sym = readSymbolRef()
pre match {
- case ThisType(cls) =>
+ case thispre: ThisType =>
// The problem is that class references super.C get pickled as
// this.C. Dereferencing the member might then get an overriding class
// instance. The problem arises for instance for LinkedHashMap#MapValues
// and also for the inner Transform class in all views. We fix it by
// replacing the this with the appropriate super.
- if (sym.owner != cls) {
- val overriding = cls.decls.lookup(sym.name)
+ if (sym.owner != thispre.cls) {
+ val overriding = thispre.cls.decls.lookup(sym.name)
if (overriding.exists && overriding != sym) {
val base = pre.baseTypeWithArgs(sym.owner)
assert(base.exists)
- pre = SuperType(pre, base)
+ pre = SuperType(thispre, base)
}
}
case _ =>
diff --git a/src/dotty/tools/dotc/printing/PlainPrinter.scala b/src/dotty/tools/dotc/printing/PlainPrinter.scala
index 94b325996..f4eb8606c 100644
--- a/src/dotty/tools/dotc/printing/PlainPrinter.scala
+++ b/src/dotty/tools/dotc/printing/PlainPrinter.scala
@@ -190,8 +190,8 @@ class PlainPrinter(_ctx: Context) extends Printer {
tp match {
case tp: TermRef =>
toTextPrefix(tp.prefix) ~ selectionString(tp)
- case ThisType(cls) =>
- nameString(cls) + ".this"
+ case tp: ThisType =>
+ nameString(tp.cls) + ".this"
case SuperType(thistpe: SingletonType, _) =>
toTextRef(thistpe).map(_.replaceAll("""\bthis$""", "super"))
case SuperType(thistpe, _) =>
diff --git a/src/dotty/tools/dotc/printing/RefinedPrinter.scala b/src/dotty/tools/dotc/printing/RefinedPrinter.scala
index c5ae129ed..7669b1a3a 100644
--- a/src/dotty/tools/dotc/printing/RefinedPrinter.scala
+++ b/src/dotty/tools/dotc/printing/RefinedPrinter.scala
@@ -45,9 +45,9 @@ class RefinedPrinter(_ctx: Context) extends PlainPrinter(_ctx) {
override def toTextRef(tp: SingletonType): Text = controlled {
tp match {
- case ThisType(cls) =>
- if (cls.isAnonymousClass) return "this"
- if (cls is ModuleClass) return fullNameString(cls.sourceModule)
+ case tp: ThisType =>
+ if (tp.cls.isAnonymousClass) return "this"
+ if (tp.cls is ModuleClass) return fullNameString(tp.cls.sourceModule)
case _ =>
}
super.toTextRef(tp)
@@ -56,8 +56,8 @@ class RefinedPrinter(_ctx: Context) extends PlainPrinter(_ctx) {
override def toTextPrefix(tp: Type): Text = controlled {
def isOmittable(sym: Symbol) = isOmittablePrefix(sym) && !ctx.settings.verbose.value
tp match {
- case ThisType(cls) =>
- if (isOmittable(cls)) return ""
+ case tp: ThisType =>
+ if (isOmittable(tp.cls)) return ""
case tp @ TermRef(pre, _) =>
val sym = tp.symbol
if (sym.isPackageObject) return toTextPrefix(pre)
diff --git a/src/dotty/tools/dotc/transform/Splitter.scala b/src/dotty/tools/dotc/transform/Splitter.scala
index d9c1c5e5e..823485af9 100644
--- a/src/dotty/tools/dotc/transform/Splitter.scala
+++ b/src/dotty/tools/dotc/transform/Splitter.scala
@@ -19,9 +19,9 @@ class Splitter extends MiniPhaseTransform {
/** Replace self referencing idents with ThisTypes. */
override def transformIdent(tree: Ident)(implicit ctx: Context, info: TransformerInfo) = tree.tpe match {
- case ThisType(cls) =>
+ case tp: ThisType =>
ctx.debuglog(s"owner = ${ctx.owner}, context = ${ctx}")
- This(cls) withPos tree.pos
+ This(tp.cls) withPos tree.pos
case _ => tree
}
diff --git a/src/dotty/tools/dotc/transform/SuperAccessors.scala b/src/dotty/tools/dotc/transform/SuperAccessors.scala
index 2ef104db4..7cb4c5825 100644
--- a/src/dotty/tools/dotc/transform/SuperAccessors.scala
+++ b/src/dotty/tools/dotc/transform/SuperAccessors.scala
@@ -551,7 +551,7 @@ class SuperAccessors extends MacroTransform with IdentityDenotTransformer { this
/** Is 'tpe' the type of a member of an enclosing class? */
private def isThisType(tpe: Type)(implicit ctx: Context): Boolean = tpe match {
- case ThisType(cls) => !cls.is(PackageClass)
+ case tpe: ThisType => !tpe.cls.is(PackageClass)
case tpe: TypeProxy => isThisType(tpe.underlying)
case _ => false
}
diff --git a/src/dotty/tools/dotc/typer/Checking.scala b/src/dotty/tools/dotc/typer/Checking.scala
index 22129bde2..6ecfee4e3 100644
--- a/src/dotty/tools/dotc/typer/Checking.scala
+++ b/src/dotty/tools/dotc/typer/Checking.scala
@@ -119,7 +119,7 @@ object Checking {
// global symbols when doing the cyclicity check.
def isInteresting(prefix: Type): Boolean = prefix.stripTypeVar match {
case NoPrefix => true
- case ThisType(cls) => sym.owner.isClass && cls.isContainedIn(sym.owner)
+ case prefix: ThisType => sym.owner.isClass && prefix.cls.isContainedIn(sym.owner)
case prefix: NamedType => !prefix.symbol.isStaticOwner && isInteresting(prefix.prefix)
case SuperType(thistp, _) => isInteresting(thistp)
case AndType(tp1, tp2) => isInteresting(tp1) || isInteresting(tp2)
diff --git a/src/dotty/tools/dotc/typer/TypeAssigner.scala b/src/dotty/tools/dotc/typer/TypeAssigner.scala
index c9f838c0b..4d996fd61 100644
--- a/src/dotty/tools/dotc/typer/TypeAssigner.scala
+++ b/src/dotty/tools/dotc/typer/TypeAssigner.scala
@@ -107,7 +107,7 @@ trait TypeAssigner {
else tpe
} else tpe
tpe.prefix match {
- case ThisType(cls) if cls is Package => tryInsert
+ case pre: ThisType if pre.cls is Package => tryInsert
case pre: TermRef if pre.symbol is Package => tryInsert
case _ => tpe
}