aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/dotty/tools/dotc/core/TypeComparer.scala27
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)