@@ -626,17 +626,31 @@ trait Implicits {
626
626
/** This expresses more cleanly in the negative: there's a linear path
627
627
* to a final true or false.
628
628
*/
629
- private def isPlausiblySubType (tp1 : Type , tp2 : Type ) = ! isImpossibleSubType(tp1, tp2)
630
- private def isImpossibleSubType (tp1 : Type , tp2 : Type ) = tp1.dealiasWiden match {
629
+ private def isPlausiblySubType (tp1 : Type , tp2 : Type ): Boolean = ! isImpossibleSubType(tp1, tp2)
630
+ private def isImpossibleSubType (tp1 : Type , tp2 : Type ): Boolean = tp1.dealiasWiden match {
631
631
// We can only rule out a subtype relationship if the left hand
632
632
// side is a class, else we may not know enough.
633
- case tr1 @ TypeRef (_, sym1, _ ) if sym1.isClass =>
633
+ case tr1 @ TypeRef (_, sym1, args1 ) if sym1.isClass =>
634
634
def typeRefHasMember (tp : TypeRef , name : Name ) = {
635
635
tp.baseClasses.exists(_.info.decls.lookupEntry(name) != null )
636
636
}
637
- tp2.dealiasWiden match {
638
- case TypeRef (_, sym2, _) => ((sym1 eq ByNameParamClass ) != (sym2 eq ByNameParamClass )) || (sym2.isClass && ! (sym1 isWeakSubClass sym2))
639
- case RefinedType (parents, decls) => decls.nonEmpty && ! typeRefHasMember(tr1, decls.head.name) // opt avoid full call to .member
637
+
638
+ def existentialUnderlying (t : Type ) = t match {
639
+ case et : ExistentialType => et.underlying
640
+ case tp => tp
641
+ }
642
+ val tp2Bounds = existentialUnderlying(tp2.dealiasWiden.bounds.hi)
643
+ tp2Bounds match {
644
+ case TypeRef (_, sym2, args2) =>
645
+ val impossible = if ((sym1 eq sym2) && (args1 ne Nil )) ! corresponds3(sym1.typeParams, args1, args2) {(tparam, arg1, arg2) =>
646
+ if (tparam.isCovariant) isPlausiblySubType(arg1, arg2) else isPlausiblySubType(arg2, arg1)
647
+ } else {
648
+ ((sym1 eq ByNameParamClass ) != (sym2 eq ByNameParamClass )) || (sym2.isClass && ! (sym1 isWeakSubClass sym2))
649
+ }
650
+ impossible
651
+ case RefinedType (parents, decls) =>
652
+ val impossible = decls.nonEmpty && ! typeRefHasMember(tr1, decls.head.name) // opt avoid full call to .member
653
+ impossible
640
654
case _ => false
641
655
}
642
656
case _ => false
0 commit comments