@@ -305,9 +305,21 @@ trait Infer {
305
305
}
306
306
307
307
308
- def isCompatible (tp : Type , pt : Type ): Boolean = {
308
+ /** "Compatible" means conforming after conversions.
309
+ * "Raising to a thunk" is not implicit; therefore, for purposes of applicability and
310
+ * specificity, an arg type `A` is considered compatible with cbn formal parameter type `=>A`.
311
+ * For this behavior, the type `pt` must have cbn params preserved; for instance, `formalTypes(removeByName = false)`.
312
+ *
313
+ * `isAsSpecific` no longer prefers A by testing applicability to A for both m(A) and m(=>A)
314
+ * since that induces a tie between m(=>A) and m(=>A,B*) [SI-3761]
315
+ */
316
+ private def isCompatible (tp : Type , pt : Type ): Boolean = {
317
+ def isCompatibleByName (tp : Type , pt : Type ): Boolean = pt match {
318
+ case TypeRef (_, ByNameParamClass , List (res)) if ! isByNameParamType(tp) => isCompatible(tp, res)
319
+ case _ => false
320
+ }
309
321
val tp1 = normalize(tp)
310
- (tp1 weak_<:< pt) || isCoercible(tp1, pt)
322
+ (tp1 weak_<:< pt) || isCoercible(tp1, pt) || isCompatibleByName(tp, pt)
311
323
}
312
324
def isCompatibleArgs (tps : List [Type ], pts : List [Type ]) =
313
325
(tps corresponds pts)(isCompatible)
@@ -662,7 +674,7 @@ trait Infer {
662
674
case ExistentialType (tparams, qtpe) =>
663
675
isApplicable(undetparams, qtpe, argtpes0, pt)
664
676
case MethodType (params, _) =>
665
- val formals = formalTypes(params map { _.tpe }, argtpes0.length)
677
+ val formals = formalTypes(params map { _.tpe }, argtpes0.length, removeByName = false )
666
678
667
679
def tryTupleApply : Boolean = {
668
680
// if 1 formal, 1 argtpe (a tuple), otherwise unmodified argtpes0
0 commit comments