diff options
author | Martin Odersky <odersky@gmail.com> | 2014-08-31 17:56:04 +0200 |
---|---|---|
committer | Martin Odersky <odersky@gmail.com> | 2014-08-31 17:56:04 +0200 |
commit | 6e47e2b8bce96571e643bdd5f4cdca01002aff4e (patch) | |
tree | 264d68a4a26389abb64aacf89df824f30b8e7c4d | |
parent | 5e7c262bf08fafb8ced88688121a05efda81f21b (diff) | |
download | dotty-6e47e2b8bce96571e643bdd5f4cdca01002aff4e.tar.gz dotty-6e47e2b8bce96571e643bdd5f4cdca01002aff4e.tar.bz2 dotty-6e47e2b8bce96571e643bdd5f4cdca01002aff4e.zip |
Generalize equivalentThisTypes
// We treat two prefixes A.this, B.this as equivalent if
// A's selftype derives from B and B's selftype derives from A.
It makes sense to apply this principle to comparing this types in general, and not
only when being the prefix of a named type. Not doing so revealed a problem in
retyping Applications.scala after outerAccessors. There two type applications of
the same class had as prefixes (1) Applications.this, (2) Typer.this & Applications.this.
Typer and Applications match the principle, so the prefixes should be regarded as equivalent.
Why this manifested itself only after outerAccessors is an unsolved puzzle.
-rw-r--r-- | src/dotty/tools/dotc/core/TypeComparer.scala | 23 |
1 files changed, 10 insertions, 13 deletions
diff --git a/src/dotty/tools/dotc/core/TypeComparer.scala b/src/dotty/tools/dotc/core/TypeComparer.scala index c9c4595ca..eb57119ff 100644 --- a/src/dotty/tools/dotc/core/TypeComparer.scala +++ b/src/dotty/tools/dotc/core/TypeComparer.scala @@ -440,18 +440,6 @@ class TypeComparer(initctx: Context) extends DotClass { def firstTry(tp1: Type, tp2: Type): Boolean = { tp2 match { case tp2: NamedType => - // 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 tp1: ThisType => - tp2 match { - case tp2: ThisType => - tp1.cls.classInfo.selfType.derivesFrom(tp2.cls) && - tp2.cls.classInfo.selfType.derivesFrom(tp1.cls) - case _ => false - } - case _ => false - } def isHKSubType = tp2.name == tpnme.Apply && { val lambda2 = tp2.prefix.LambdaClass(forcing = true) lambda2.exists && !tp1.isLambda && @@ -474,7 +462,6 @@ class TypeComparer(initctx: Context) extends DotClass { val pre1 = tp1.prefix val pre2 = tp2.prefix ( isSameType(pre1, pre2) - || equivalentThisTypes(pre1, pre2) || sym1.isClass && pre2.classSymbol.exists && pre2.abstractTypeMembers.isEmpty @@ -517,6 +504,16 @@ class TypeComparer(initctx: Context) extends DotClass { isSubType(tp1, tp2.ref) case tp2: AnnotatedType => isSubType(tp1, tp2.tpe) // todo: refine? + case tp2: ThisType => + tp1 match { + case tp1: ThisType => + // We treat two prefixes A.this, B.this as equivalent if + // A's selftype derives from B and B's selftype derives from A. + tp1.cls.classInfo.selfType.derivesFrom(tp2.cls) && + tp2.cls.classInfo.selfType.derivesFrom(tp1.cls) + case _ => + secondTry(tp1, tp2) + } case AndType(tp21, tp22) => isSubType(tp1, tp21) && isSubType(tp1, tp22) case ErrorType => |