@@ -474,21 +474,24 @@ trait Applications extends Compatibility { self: Typer with Dynamic =>
474474 type TypedArg = Arg
475475 type Result = Unit
476476
477+ protected def argOK (arg : TypedArg , formal : Type ) = argType(arg, formal) match {
478+ case ref : TermRef if ref.denot.isOverloaded =>
479+ // in this case we could not resolve overloading because no alternative
480+ // matches expected type
481+ false
482+ case argtpe =>
483+ def SAMargOK = formal match {
484+ case SAMType (meth) => argtpe <:< meth.info.toFunctionType()
485+ case _ => false
486+ }
487+ isCompatible(argtpe, formal) || ctx.mode.is(Mode .ImplicitsEnabled ) && SAMargOK
488+ }
489+
477490 /** The type of the given argument */
478491 protected def argType (arg : Arg , formal : Type ): Type
479492
480493 def typedArg (arg : Arg , formal : Type ): Arg = arg
481- def addArg (arg : TypedArg , formal : Type ) =
482- ok = ok & {
483- argType(arg, formal) match {
484- case ref : TermRef if ref.denot.isOverloaded =>
485- // in this case we could not resolve overloading because no alternative
486- // matches expected type
487- false
488- case argtpe =>
489- isCompatible(argtpe, formal)
490- }
491- }
494+ final def addArg (arg : TypedArg , formal : Type ) = ok = ok & argOK(arg, formal)
492495 def makeVarArg (n : Int , elemFormal : Type ) = {}
493496 def fail (msg : => Message , arg : Arg ) =
494497 ok = false
@@ -512,11 +515,10 @@ trait Applications extends Compatibility { self: Typer with Dynamic =>
512515 }
513516
514517 /** Subclass of Application for applicability tests with type arguments and value
515- * argument trees.
516- */
518+ * argument trees.
519+ */
517520 class ApplicableToTreesDirectly (methRef : TermRef , targs : List [Type ], args : List [Tree ], resultType : Type )(implicit ctx : Context ) extends ApplicableToTrees (methRef, targs, args, resultType)(ctx) {
518- override def addArg (arg : TypedArg , formal : Type ) =
519- ok = ok & (argType(arg, formal) <:< formal)
521+ override def argOK (arg : TypedArg , formal : Type ) = argType(arg, formal) <:< formal
520522 }
521523
522524 /** Subclass of Application for applicability tests with value argument types. */
@@ -1197,7 +1199,8 @@ trait Applications extends Compatibility { self: Typer with Dynamic =>
11971199 /** Resolve overloaded alternative `alts`, given expected type `pt` and
11981200 * possibly also type argument `targs` that need to be applied to each alternative
11991201 * to form the method type.
1200- * todo: use techniques like for implicits to pick candidates quickly?
1202+ * Two trials: First, without implicits or SAM conversions enabled. Then,
1203+ * if the fist finds no eligible candidates, with implicits and SAM conversions enabled.
12011204 */
12021205 def resolveOverloaded (alts : List [TermRef ], pt : Type )(implicit ctx : Context ): List [TermRef ] = track(" resolveOverloaded" ) {
12031206
@@ -1222,7 +1225,7 @@ trait Applications extends Compatibility { self: Typer with Dynamic =>
12221225 * fallback to `chosen`.
12231226 *
12241227 * Note this order of events is done for speed. One might be tempted to
1225- * preselect alternatives by result type. But is slower, because it discriminates
1228+ * preselect alternatives by result type. But this is slower, because it discriminates
12261229 * less. The idea is when searching for a best solution, as is the case in overloading
12271230 * resolution, we should first try criteria which are cheap and which have a high
12281231 * probability of pruning the search. result type comparisons are neither cheap nor
@@ -1258,7 +1261,7 @@ trait Applications extends Compatibility { self: Typer with Dynamic =>
12581261 /** This private version of `resolveOverloaded` does the bulk of the work of
12591262 * overloading resolution, but does not do result adaptation. It might be
12601263 * called twice from the public `resolveOverloaded` method, once with
1261- * implicits enabled, and once without.
1264+ * implicits and SAM conversions enabled, and once without.
12621265 */
12631266 private def resolveOverloaded (alts : List [TermRef ], pt : Type , targs : List [Type ])(implicit ctx : Context ): List [TermRef ] = track(" resolveOverloaded" ) {
12641267
@@ -1338,7 +1341,7 @@ trait Applications extends Compatibility { self: Typer with Dynamic =>
13381341 if (isDetermined(alts1)) alts1
13391342 else {
13401343 val alts2 = narrowByShapes(alts1)
1341- // ctx.log(i"narrowed by shape: ${alts1 .map(_.symbol.showDcl)}%, %")
1344+ // ctx.log(i"narrowed by shape: ${alts2 .map(_.symbol.showDcl)}%, %")
13421345 if (isDetermined(alts2)) alts2
13431346 else {
13441347 pretypeArgs(alts2, pt)
0 commit comments