@@ -1565,18 +1565,34 @@ class Typer extends Namer with TypeAssigner with Applications with Implicits wit
1565
1565
* `fallBack`.
1566
1566
*
1567
1567
* 1st strategy: Try to insert `.apply` so that the result conforms to prototype `pt`.
1568
+ * This strategy is not tried if the prototype represents already
1569
+ * another `.apply` or `.apply()` selection.
1568
1570
* 2nd strategy: If tree is a select `qual.name`, try to insert an implicit conversion
1569
1571
* around the qualifier part `qual` so that the result conforms to the expected type
1570
1572
* with wildcard result type.
1571
1573
*/
1572
- def tryInsertApplyOrImplicit (tree : Tree , pt : ProtoType )(fallBack : (Tree , TyperState ) => Tree )(implicit ctx : Context ): Tree =
1573
- tryEither { implicit ctx =>
1574
+ def tryInsertApplyOrImplicit (tree : Tree , pt : ProtoType )(fallBack : => Tree )(implicit ctx : Context ): Tree = {
1575
+
1576
+ /** Is `pt` a prototype of an `apply` selection, or a parameterless function yielding one? */
1577
+ def isApplyProto (pt : Type ): Boolean = pt match {
1578
+ case pt : SelectionProto => pt.name == nme.apply
1579
+ case pt : FunProto => pt.args.isEmpty && isApplyProto(pt.resultType)
1580
+ case pt : IgnoredProto => isApplyProto(pt.ignored)
1581
+ case _ => false
1582
+ }
1583
+
1584
+ def tryApply (implicit ctx : Context ) = {
1574
1585
val sel = typedSelect(untpd.Select (untpd.TypedSplice (tree), nme.apply), pt)
1575
1586
if (sel.tpe.isError) sel else adapt(sel, pt)
1576
- } { (failedTree, failedState) =>
1577
- tryInsertImplicitOnQualifier(tree, pt).getOrElse(fallBack(failedTree, failedState))
1578
1587
}
1579
1588
1589
+ def tryImplicit =
1590
+ tryInsertImplicitOnQualifier(tree, pt).getOrElse(fallBack)
1591
+
1592
+ if (isApplyProto(pt)) tryImplicit
1593
+ else tryEither(tryApply(_))((_, _) => tryImplicit)
1594
+ }
1595
+
1580
1596
/** If this tree is a select node `qual.name`, try to insert an implicit conversion
1581
1597
* `c` around `qual` so that `c(qual).name` conforms to `pt`.
1582
1598
*/
@@ -1668,7 +1684,7 @@ class Typer extends Namer with TypeAssigner with Applications with Implicits wit
1668
1684
def hasEmptyParams (denot : SingleDenotation ) = denot.info.paramTypess == ListOfNil
1669
1685
pt match {
1670
1686
case pt : FunProto =>
1671
- tryInsertApplyOrImplicit(tree, pt)((_, _) => noMatches)
1687
+ tryInsertApplyOrImplicit(tree, pt)(noMatches)
1672
1688
case _ =>
1673
1689
if (altDenots exists (_.info.paramTypess == ListOfNil ))
1674
1690
typed(untpd.Apply (untpd.TypedSplice (tree), Nil ), pt)
@@ -1707,7 +1723,7 @@ class Typer extends Namer with TypeAssigner with Applications with Implicits wit
1707
1723
case Apply (_, _) => " more"
1708
1724
case _ => " "
1709
1725
}
1710
- (_, _) => errorTree(tree, em " $methodStr does not take $more parameters " )
1726
+ errorTree(tree, em " $methodStr does not take $more parameters " )
1711
1727
}
1712
1728
}
1713
1729
@@ -1924,9 +1940,7 @@ class Typer extends Namer with TypeAssigner with Applications with Implicits wit
1924
1940
case pt : FunProto =>
1925
1941
adaptToArgs(wtp, pt)
1926
1942
case pt : PolyProto =>
1927
- tryInsertApplyOrImplicit(tree, pt) {
1928
- (_, _) => tree // error will be reported in typedTypeApply
1929
- }
1943
+ tryInsertApplyOrImplicit(tree, pt)(tree) // error will be reported in typedTypeApply
1930
1944
case _ =>
1931
1945
if (ctx.mode is Mode .Type ) adaptType(tree.tpe)
1932
1946
else adaptNoArgs(wtp)
0 commit comments