@@ -883,7 +883,27 @@ trait Applications extends Compatibility {
883883 case SAMType (samMeth, samParent) => argtpe <:< samMeth.toFunctionType(isJava = samParent.classSymbol.is(JavaDefined ))
884884 case _ => false
885885
886- isCompatible(argtpe, formal)
886+ // For overload resolution, allow wildcard upper bounds to match their bound type.
887+ // For example, given:
888+ // def blub[T](a: Class[? <: T]): String = "a"
889+ // def blub[T](a: Class[T], ints: Int*): String = "b"
890+ // blub(classOf[Object])
891+ //
892+ // The non-varargs overload should be preferred. While Class[? <: T] is not a
893+ // subtype of Class[T] (Class is invariant), for overload resolution we consider
894+ // Class[? <: T] "applicable" where Class[T] is expected by checking if the
895+ // wildcard's upper bound is a subtype of the formal type parameter.
896+ def wildcardArgOK =
897+ (argtpe, formal) match
898+ case (AppliedType (tycon1, args1), AppliedType (tycon2, args2))
899+ if tycon1 =:= tycon2 && args1.length == args2.length =>
900+ args1.lazyZip(args2).forall {
901+ case (TypeBounds (_, hi), formal) => hi relaxed_<:< formal
902+ case (arg, formal) => arg =:= formal
903+ }
904+ case _ => false
905+
906+ isCompatible(argtpe, formal) || wildcardArgOK
887907 // Only allow SAM-conversion to PartialFunction if implicit conversions
888908 // are enabled. This is necessary to avoid ambiguity between an overload
889909 // taking a PartialFunction and one taking a Function1 because
@@ -2176,20 +2196,7 @@ trait Applications extends Compatibility {
21762196 case 0 =>
21772197 if winsType1 != winsType2 then if winsType1 then 1 else - 1
21782198 else if alt1.symbol == alt2.symbol then comparePrefixes
2179- else
2180- // Prefer non-varargs methods over varargs methods as a final tiebreaker.
2181- // While `isAsGood` normally handles this, it can fail when wildcard types are involved.
2182- // For example, when comparing:
2183- // def m[T](a: Class[? <: T]): Unit
2184- // def m[T](a: Class[T], ints: Int*): Unit
2185- // Both winsType1 and winsType2 are false because Class[? <: T] is not
2186- // a subtype of Class[T] (Class is invariant). This tiebreaker ensures the
2187- // non-varargs method is preferred in such cases.
2188- val tp1IsVarArgs = tp1.isVarArgsMethod
2189- val tp2IsVarArgs = tp2.isVarArgsMethod
2190- if tp1IsVarArgs == tp2IsVarArgs then 0
2191- else if tp1IsVarArgs then - 1 // alt2 (non-varargs) wins
2192- else 1 // alt1 (non-varargs) wins
2199+ else 0
21932200 end compareWithTypes
21942201
21952202 if alt1.symbol.is(PhantomSymbol ) && ! alt2.symbol.is(PhantomSymbol ) then - 1
0 commit comments