diff options
author | Martin Odersky <odersky@gmail.com> | 2013-12-29 19:50:01 +0100 |
---|---|---|
committer | Martin Odersky <odersky@gmail.com> | 2013-12-29 19:50:01 +0100 |
commit | 4a175b13e4fcefc7cb3cf70da254205a14dc2418 (patch) | |
tree | e5dccaaba301d0c127ba3e698fc5ee4462d08b8c | |
parent | 0553f08eaeee1f9ac7ef6c28b341a92e0fb452e3 (diff) | |
download | dotty-4a175b13e4fcefc7cb3cf70da254205a14dc2418.tar.gz dotty-4a175b13e4fcefc7cb3cf70da254205a14dc2418.tar.bz2 dotty-4a175b13e4fcefc7cb3cf70da254205a14dc2418.zip |
Adding a new case to subtype tests.
This one handles situations like
val sym: Symbol
sym.type <:< Symbol { type ThisType = sym.ThisType }
-rw-r--r-- | src/dotty/tools/dotc/core/TypeComparer.scala | 27 |
1 files changed, 19 insertions, 8 deletions
diff --git a/src/dotty/tools/dotc/core/TypeComparer.scala b/src/dotty/tools/dotc/core/TypeComparer.scala index 0d76155f1..5dbfc894d 100644 --- a/src/dotty/tools/dotc/core/TypeComparer.scala +++ b/src/dotty/tools/dotc/core/TypeComparer.scala @@ -292,14 +292,25 @@ class TypeComparer(initctx: Context) extends DotClass { // optimized case; all info on tp1.name2 is in refinement tp1.refinedInfo. isSubType(tp1, parent2) && isSubType(tp1.refinedInfo, tp2.refinedInfo) case _ => - def hasMatchingMember(name: Name): Boolean = traceIndented(s"hasMatchingMember($name)") { - tp1.member(name).hasAltWith(alt => isSubType(alt.info, tp2.refinedInfo)) || - name.isHkParamName && { - val idx = name.hkParamIndex - val tparams = tp1.typeParams - idx < tparams.length && hasMatchingMember(tparams(idx).name) - } - } + def hasMatchingMember(name: Name): Boolean = traceIndented(s"hasMatchingMember($name)") ( + tp1.member(name).hasAltWith(alt => isSubType(alt.info, tp2.refinedInfo)) + || + { // special case for situations like: + // foo <: C { type T = foo.T } + tp2.refinedInfo match { + case TypeBounds(lo, hi) if lo eq hi => + val ref = tp1 select name + isSubType(ref, lo) && isSubType(hi, ref) + case _ => false + } + } + || + name.isHkParamName && { + val idx = name.hkParamIndex + val tparams = tp1.typeParams + idx < tparams.length && hasMatchingMember(tparams(idx).name) + } + ) isSubType(tp1, parent2) && ( name2 == nme.WILDCARD || hasMatchingMember(name2) |