diff options
-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) |