@@ -1585,18 +1585,34 @@ class Typer extends Namer with TypeAssigner with Applications with Implicits wit
1585
1585
* `fallBack`.
1586
1586
*
1587
1587
* 1st strategy: Try to insert `.apply` so that the result conforms to prototype `pt`.
1588
+ * This strategy is not tried if the prototype represents already
1589
+ * another `.apply` or `.apply()` selection.
1588
1590
* 2nd strategy: If tree is a select `qual.name`, try to insert an implicit conversion
1589
1591
* around the qualifier part `qual` so that the result conforms to the expected type
1590
1592
* with wildcard result type.
1591
1593
*/
1592
- def tryInsertApplyOrImplicit (tree : Tree , pt : ProtoType )(fallBack : (Tree , TyperState ) => Tree )(implicit ctx : Context ): Tree =
1593
- tryEither { implicit ctx =>
1594
+ def tryInsertApplyOrImplicit (tree : Tree , pt : ProtoType )(fallBack : => Tree )(implicit ctx : Context ): Tree = {
1595
+
1596
+ /** Is `pt` a prototype of an `apply` selection, or a parameterless function yielding one? */
1597
+ def isApplyProto (pt : Type ): Boolean = pt match {
1598
+ case pt : SelectionProto => pt.name == nme.apply
1599
+ case pt : FunProto => pt.args.isEmpty && isApplyProto(pt.resultType)
1600
+ case pt : IgnoredProto => isApplyProto(pt.ignored)
1601
+ case _ => false
1602
+ }
1603
+
1604
+ def tryApply (implicit ctx : Context ) = {
1594
1605
val sel = typedSelect(untpd.Select (untpd.TypedSplice (tree), nme.apply), pt)
1595
1606
if (sel.tpe.isError) sel else adapt(sel, pt)
1596
- } { (failedTree, failedState) =>
1597
- tryInsertImplicitOnQualifier(tree, pt).getOrElse(fallBack(failedTree, failedState))
1598
1607
}
1599
1608
1609
+ def tryImplicit =
1610
+ tryInsertImplicitOnQualifier(tree, pt).getOrElse(fallBack)
1611
+
1612
+ if (isApplyProto(pt)) tryImplicit
1613
+ else tryEither(tryApply(_))((_, _) => tryImplicit)
1614
+ }
1615
+
1600
1616
/** If this tree is a select node `qual.name`, try to insert an implicit conversion
1601
1617
* `c` around `qual` so that `c(qual).name` conforms to `pt`.
1602
1618
*/
@@ -1688,7 +1704,7 @@ class Typer extends Namer with TypeAssigner with Applications with Implicits wit
1688
1704
def hasEmptyParams (denot : SingleDenotation ) = denot.info.paramTypess == ListOfNil
1689
1705
pt match {
1690
1706
case pt : FunProto =>
1691
- tryInsertApplyOrImplicit(tree, pt)((_, _) => noMatches)
1707
+ tryInsertApplyOrImplicit(tree, pt)(noMatches)
1692
1708
case _ =>
1693
1709
if (altDenots exists (_.info.paramTypess == ListOfNil ))
1694
1710
typed(untpd.Apply (untpd.TypedSplice (tree), Nil ), pt)
@@ -1727,7 +1743,7 @@ class Typer extends Namer with TypeAssigner with Applications with Implicits wit
1727
1743
case Apply (_, _) => " more"
1728
1744
case _ => " "
1729
1745
}
1730
- (_, _) => errorTree(tree, em " $methodStr does not take $more parameters " )
1746
+ errorTree(tree, em " $methodStr does not take $more parameters " )
1731
1747
}
1732
1748
}
1733
1749
@@ -1946,9 +1962,7 @@ class Typer extends Namer with TypeAssigner with Applications with Implicits wit
1946
1962
case pt : FunProto =>
1947
1963
adaptToArgs(wtp, pt)
1948
1964
case pt : PolyProto =>
1949
- tryInsertApplyOrImplicit(tree, pt) {
1950
- (_, _) => tree // error will be reported in typedTypeApply
1951
- }
1965
+ tryInsertApplyOrImplicit(tree, pt)(tree) // error will be reported in typedTypeApply
1952
1966
case _ =>
1953
1967
if (ctx.mode is Mode .Type ) adaptType(tree.tpe)
1954
1968
else adaptNoArgs(wtp)
0 commit comments