@@ -683,17 +683,31 @@ trait Implicits {
683
683
/** This expresses more cleanly in the negative: there's a linear path
684
684
* to a final true or false.
685
685
*/
686
- private def isPlausiblySubType (tp1 : Type , tp2 : Type ) = ! isImpossibleSubType(tp1, tp2)
687
- private def isImpossibleSubType (tp1 : Type , tp2 : Type ) = tp1.dealiasWiden match {
686
+ private def isPlausiblySubType (tp1 : Type , tp2 : Type ): Boolean = ! isImpossibleSubType(tp1, tp2)
687
+ private def isImpossibleSubType (tp1 : Type , tp2 : Type ): Boolean = tp1.dealiasWiden match {
688
688
// We can only rule out a subtype relationship if the left hand
689
689
// side is a class, else we may not know enough.
690
- case tr1 @ TypeRef (_, sym1, _ ) if sym1.isClass =>
690
+ case tr1 @ TypeRef (_, sym1, args1 ) if sym1.isClass =>
691
691
def typeRefHasMember (tp : TypeRef , name : Name ) = {
692
692
tp.baseClasses.exists(_.info.decls.lookupEntry(name) != null )
693
693
}
694
- tp2.dealiasWiden match {
695
- case TypeRef (_, sym2, _) => ((sym1 eq ByNameParamClass ) != (sym2 eq ByNameParamClass )) || (sym2.isClass && ! (sym1 isWeakSubClass sym2))
696
- case RefinedType (parents, decls) => decls.nonEmpty && ! typeRefHasMember(tr1, decls.head.name) // opt avoid full call to .member
694
+
695
+ def existentialUnderlying (t : Type ) = t match {
696
+ case et : ExistentialType => et.underlying
697
+ case tp => tp
698
+ }
699
+ val tp2Bounds = existentialUnderlying(tp2.dealiasWiden.bounds.hi) // TODO incompat with sip23-narrow.scala on 2.13.x
700
+ tp2Bounds match {
701
+ case TypeRef (_, sym2, args2) =>
702
+ val impossible = if ((sym1 eq sym2) && (args1 ne Nil )) ! corresponds3(sym1.typeParams, args1, args2) {(tparam, arg1, arg2) =>
703
+ if (tparam.isCovariant) isPlausiblySubType(arg1, arg2) else isPlausiblySubType(arg2, arg1)
704
+ } else {
705
+ ((sym1 eq ByNameParamClass ) != (sym2 eq ByNameParamClass )) || (sym2.isClass && ! (sym1 isWeakSubClass sym2))
706
+ }
707
+ impossible
708
+ case RefinedType (parents, decls) =>
709
+ val impossible = decls.nonEmpty && ! typeRefHasMember(tr1, decls.head.name) // opt avoid full call to .member
710
+ impossible
697
711
case _ => false
698
712
}
699
713
case _ => false
0 commit comments