@@ -583,10 +583,19 @@ class SpaceEngine(implicit ctx: Context) extends SpaceLogic {
583
583
// map `ThisType` of `tp1` to a type variable
584
584
// precondition: `tp1` should have the shape `path.Child`, thus `ThisType` is always covariant
585
585
val thisTypeMap = new TypeMap {
586
- def apply (t : Type ): Type = t match {
586
+ def apply (t : Type ): Type = t.dealias match {
587
587
case tp @ ThisType (tref) if ! tref.symbol.isStaticOwner =>
588
588
if (tref.symbol.is(Module )) mapOver(tref)
589
589
else newTypeVar(TypeBounds .upper(tp.underlying))
590
+ case tp : TypeRef if tp.underlying.isInstanceOf [TypeBounds ] =>
591
+ // See tests/patmat/3645b.scala
592
+ val exposed =
593
+ if (variance == 0 ) newTypeVar(tp.underlying.bounds)
594
+ else if (variance == 1 ) mapOver(tp.underlying.hiBound)
595
+ else mapOver(tp.underlying.loBound)
596
+
597
+ debug.println(s " $tp exposed to =====> $exposed" )
598
+ exposed
590
599
case _ =>
591
600
mapOver(t)
592
601
}
@@ -625,13 +634,19 @@ class SpaceEngine(implicit ctx: Context) extends SpaceLogic {
625
634
val tvars = tp1.typeParams.map { tparam => newTypeVar(tparam.paramInfo.bounds) }
626
635
val protoTp1 = thisTypeMap(tp1.appliedTo(tvars))
627
636
637
+ // tests/patmat/3645b.scala
638
+ def parentQualify = tp1.widen.classSymbol.info.parents.exists { parent =>
639
+ (parent.argInfos.nonEmpty || parent.abstractTypeMembers.nonEmpty) &&
640
+ instantiate(parent, tp2)(ctx.fresh.setNewTyperState()).exists
641
+ }
642
+
628
643
if (protoTp1 <:< tp2) {
629
644
if (isFullyDefined(protoTp1, force)) protoTp1
630
645
else instUndetMap(protoTp1)
631
646
}
632
647
else {
633
648
val protoTp2 = typeParamMap(tp2)
634
- if (protoTp1 <:< protoTp2) {
649
+ if (protoTp1 <:< protoTp2 || parentQualify ) {
635
650
if (isFullyDefined(AndType (protoTp1, protoTp2), force)) protoTp1
636
651
else instUndetMap(protoTp1)
637
652
}
0 commit comments