@@ -541,24 +541,13 @@ 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-
556544 def realApply (implicit ctx : Context ): Tree = track(" realApply" ) {
557545 val originalProto = new FunProto (tree.args, IgnoredProto (pt), this )(argCtx(tree))
558546 val fun1 = typedExpr(tree.fun, originalProto)
559547
560548 // Warning: The following lines are dirty and fragile. We record that auto-tupling was demanded as
561- // a side effect in adapt. If it was, we assume the tupled proto-type in the rest of the application.
549+ // a side effect in adapt. If it was, we assume the tupled proto-type in the rest of the application,
550+ // until, possibly, we have to fall back to insert an implicit on the qualifier.
562551 // This crucially relies on he fact that `proto` is used only in a single call of `adapt`,
563552 // otherwise we would get possible cross-talk between different `adapt` calls using the same
564553 // prototype. A cleaner alternative would be to return a modified prototype from `adapt` together with
@@ -574,6 +563,32 @@ trait Applications extends Compatibility { self: Typer with Dynamic =>
574563 if (! constrainResult(fun1.tpe.widen, proto.derivedFunProto(resultType = pt)))
575564 typr.println(i " result failure for $tree with type ${fun1.tpe.widen}, expected = $pt" )
576565
566+ /** Type application where arguments come from prototype, and no implicits are inserted */
567+ def simpleApply (fun1 : Tree , proto : FunProto )(implicit ctx : Context ): Tree =
568+ methPart(fun1).tpe match {
569+ case funRef : TermRef =>
570+ val app =
571+ if (proto.allArgTypesAreCurrent())
572+ new ApplyToTyped (tree, fun1, funRef, proto.typedArgs, pt)
573+ else
574+ new ApplyToUntyped (tree, fun1, funRef, proto, pt)(argCtx(tree))
575+ convertNewGenericArray(ConstFold (app.result))
576+ case _ =>
577+ handleUnexpectedFunType(tree, fun1)
578+ }
579+
580+ /** Try same application with an implicit inserted around the qualifier of the function
581+ * part. Return an optional value to indicate success.
582+ */
583+ def tryWithImplicitOnQualifier (fun1 : Tree , proto : FunProto )(implicit ctx : Context ): Option [Tree ] =
584+ tryInsertImplicitOnQualifier(fun1, proto) flatMap { fun2 =>
585+ tryEither {
586+ implicit ctx => Some (simpleApply(fun2, proto)): Option [Tree ]
587+ } {
588+ (_, _) => None
589+ }
590+ }
591+
577592 fun1.tpe match {
578593 case ErrorType => tree.withType(ErrorType )
579594 case TryDynamicCallType =>
@@ -583,23 +598,20 @@ trait Applications extends Compatibility { self: Typer with Dynamic =>
583598 case _ =>
584599 handleUnexpectedFunType(tree, fun1)
585600 }
586- case _ => methPart(fun1).tpe match {
587- case funRef : TermRef =>
588- tryEither { implicit ctx =>
589- val app =
590- if (proto.argsAreTyped) new ApplyToTyped (tree, fun1, funRef, proto.typedArgs, pt)
591- else new ApplyToUntyped (tree, fun1, funRef, proto, pt)(argCtx(tree))
592- val result = app.result
593- convertNewGenericArray(ConstFold (result))
594- } { (failedVal, failedState) =>
601+ case _ =>
602+ tryEither {
603+ implicit ctx => simpleApply(fun1, proto)
604+ } {
605+ (failedVal, failedState) =>
595606 def fail = { failedState.commit(); failedVal }
607+ // Try once with original prototype and once (if different) with tupled one.
608+ // The reason we need to try both is that the decision whether to use tupled
609+ // or not was already taken but might have to be revised when an implicit
610+ // is inserted on the qualifier.
596611 tryWithImplicitOnQualifier(fun1, originalProto).getOrElse(
597612 if (proto eq originalProto) fail
598613 else tryWithImplicitOnQualifier(fun1, proto).getOrElse(fail))
599- }
600- case _ =>
601- handleUnexpectedFunType(tree, fun1)
602- }
614+ }
603615 }
604616 }
605617
@@ -611,7 +623,7 @@ trait Applications extends Compatibility { self: Typer with Dynamic =>
611623 *
612624 * { val xs = es; e' = e' + args }
613625 */
614- def typedOpAssign : Tree = track(" typedOpAssign" ) {
626+ def typedOpAssign : Tree = track(" typedOpAssign" ) {
615627 val Apply (Select (lhs, name), rhss) = tree
616628 val lhs1 = typedExpr(lhs)
617629 val liftedDefs = new mutable.ListBuffer [Tree ]
0 commit comments