@@ -2413,13 +2413,16 @@ class Typer extends Namer
2413
2413
def dummyArg (tp : Type ) = untpd.Ident (nme.??? ).withTypeUnchecked(tp)
2414
2414
2415
2415
def addImplicitArgs (implicit ctx : Context ) = {
2416
- def implicitArgs (formals : List [Type ], argIndex : Int ): List [Tree ] = formals match {
2416
+ def implicitArgs (formals : List [Type ], argIndex : Int , pt : Type ): List [Tree ] = formals match {
2417
2417
case Nil => Nil
2418
2418
case formal :: formals1 =>
2419
2419
val arg = inferImplicitArg(formal, tree.span.endPos)
2420
2420
arg.tpe match {
2421
- case failed : SearchFailureType
2422
- if ! failed.isInstanceOf [AmbiguousImplicits ] && ! tree.symbol.hasDefaultParams =>
2421
+ case failed : AmbiguousImplicits =>
2422
+ val pt1 = pt.deepenProto
2423
+ if ((pt1 `ne` pt) && resultMatches(wtp, pt1)) implicitArgs(formals, argIndex, pt1)
2424
+ else arg :: implicitArgs(formals1, argIndex + 1 , pt1)
2425
+ case failed : SearchFailureType if ! tree.symbol.hasDefaultParams =>
2423
2426
// no need to search further, the adapt fails in any case
2424
2427
// the reason why we continue inferring arguments in case of an AmbiguousImplicits
2425
2428
// is that we need to know whether there are further errors.
@@ -2433,10 +2436,10 @@ class Typer extends Namer
2433
2436
if (wtp.isParamDependent && arg.tpe.exists)
2434
2437
formals1.mapconserve(f1 => safeSubstParam(f1, wtp.paramRefs(argIndex), arg.tpe))
2435
2438
else formals1
2436
- arg :: implicitArgs(formals2, argIndex + 1 )
2439
+ arg :: implicitArgs(formals2, argIndex + 1 , pt )
2437
2440
}
2438
2441
}
2439
- val args = implicitArgs(wtp.paramInfos, 0 )
2442
+ val args = implicitArgs(wtp.paramInfos, 0 , pt )
2440
2443
2441
2444
def propagatedFailure (args : List [Tree ]): Type = args match {
2442
2445
case arg :: args1 =>
@@ -2612,11 +2615,12 @@ class Typer extends Namer
2612
2615
case _ => tp
2613
2616
}
2614
2617
2618
+ def resultMatches (wtp : Type , pt : Type ) =
2619
+ constrainResult(tree.symbol, wtp, revealProtoOfExtMethod(followAlias(pt)))
2620
+
2615
2621
def adaptNoArgs (wtp : Type ): Tree = {
2616
2622
val ptNorm = underlyingApplied(pt)
2617
2623
def functionExpected = defn.isFunctionType(ptNorm)
2618
- def resultMatch =
2619
- constrainResult(tree.symbol, wtp, revealProtoOfExtMethod(followAlias(pt)))
2620
2624
def needsEta = pt match {
2621
2625
case _ : SingletonType => false
2622
2626
case IgnoredProto (_ : FunOrPolyProto ) => false
@@ -2627,8 +2631,9 @@ class Typer extends Namer
2627
2631
case wtp : ExprType =>
2628
2632
readaptSimplified(tree.withType(wtp.resultType))
2629
2633
case wtp : MethodType if wtp.isImplicitMethod &&
2630
- ({ resMatch = resultMatch; resMatch } || ! functionExpected) =>
2631
- if (resMatch || ctx.mode.is(Mode .ImplicitsEnabled )) adaptNoArgsImplicitMethod(wtp)
2634
+ ({ resMatch = resultMatches(wtp, pt); resMatch } || ! functionExpected) =>
2635
+ if (resMatch || ctx.mode.is(Mode .ImplicitsEnabled ))
2636
+ adaptNoArgsImplicitMethod(wtp)
2632
2637
else {
2633
2638
// Don't proceed with implicit search if result type cannot match - the search
2634
2639
// will likely be under-constrained, which means that an unbounded number of alternatives
0 commit comments