@@ -541,17 +541,29 @@ trait Applications extends Compatibility { self: Typer with Dynamic =>
541541
542542 def typedApply (tree : untpd.Apply , pt : Type )(implicit ctx : Context ): Tree = {
543543
544+ /** Try same application with an implicit inserted around the qualifier of the function
545+ * part. Return an optional value to indicate success.
546+ */
547+ def tryWithImplicitOnQualifier (fun1 : Tree , proto : FunProto )(implicit ctx : Context ): Option [Tree ] =
548+ tryInsertImplicitOnQualifier(fun1, proto) flatMap { fun2 =>
549+ tryEither { implicit ctx =>
550+ Some (typedApply(
551+ cpy.Apply (tree)(untpd.TypedSplice (fun2), proto.typedArgs map untpd.TypedSplice ),
552+ pt)): Option [Tree ]
553+ } { (_, _) => None }
554+ }
555+
544556 def realApply (implicit ctx : Context ): Tree = track(" realApply" ) {
545- var proto = new FunProto (tree.args, IgnoredProto (pt), this )(argCtx(tree))
546- val fun1 = typedExpr(tree.fun, proto )
557+ val originalProto = new FunProto (tree.args, IgnoredProto (pt), this )(argCtx(tree))
558+ val fun1 = typedExpr(tree.fun, originalProto )
547559
548- // Warning: The following line is dirty and fragile. We record that auto-tupling was demanded as
560+ // Warning: The following lines are dirty and fragile. We record that auto-tupling was demanded as
549561 // a side effect in adapt. If it was, we assume the tupled proto-type in the rest of the application.
550562 // This crucially relies on he fact that `proto` is used only in a single call of `adapt`,
551563 // otherwise we would get possible cross-talk between different `adapt` calls using the same
552564 // prototype. A cleaner alternative would be to return a modified prototype from `adapt` together with
553565 // a modified tree but this would be more convoluted and less efficient.
554- if (proto .isTupled) proto = proto .tupled
566+ val proto = if (originalProto .isTupled) originalProto .tupled else originalProto
555567
556568 // If some of the application's arguments are function literals without explicitly declared
557569 // parameter types, relate the normalized result type of the application with the
@@ -580,13 +592,11 @@ trait Applications extends Compatibility { self: Typer with Dynamic =>
580592 val result = app.result
581593 convertNewGenericArray(ConstFold (result))
582594 } { (failedVal, failedState) =>
583- val fun2 = tryInsertImplicitOnQualifier(fun1, proto)
584- if (fun1 eq fun2) {
585- failedState.commit()
586- failedVal
587- } else typedApply(
588- cpy.Apply (tree)(untpd.TypedSplice (fun2), proto.typedArgs map untpd.TypedSplice ), pt)
589- }
595+ def fail = { failedState.commit(); failedVal }
596+ tryWithImplicitOnQualifier(fun1, originalProto).getOrElse(
597+ if (proto eq originalProto) fail
598+ else tryWithImplicitOnQualifier(fun1, proto).getOrElse(fail))
599+ }
590600 case _ =>
591601 handleUnexpectedFunType(tree, fun1)
592602 }
0 commit comments