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