aboutsummaryrefslogtreecommitdiff
path: root/src/dotty/tools/dotc/core/TypeComparer.scala
diff options
context:
space:
mode:
authorMartin Odersky <odersky@gmail.com>2014-08-31 17:56:04 +0200
committerMartin Odersky <odersky@gmail.com>2014-08-31 17:56:04 +0200
commit6e47e2b8bce96571e643bdd5f4cdca01002aff4e (patch)
tree264d68a4a26389abb64aacf89df824f30b8e7c4d /src/dotty/tools/dotc/core/TypeComparer.scala
parent5e7c262bf08fafb8ced88688121a05efda81f21b (diff)
downloaddotty-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.
Diffstat (limited to 'src/dotty/tools/dotc/core/TypeComparer.scala')
-rw-r--r--src/dotty/tools/dotc/core/TypeComparer.scala23
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 =>