@@ -2011,16 +2011,39 @@ class Typer extends Namer with TypeAssigner with Applications with Implicits wit
2011
2011
if (nparams > 0 || pt.eq(AnyFunctionProto )) nparams
2012
2012
else - 1 // no eta expansion in this case
2013
2013
}
2014
+
2015
+ /** A synthetic apply should be eta-expanded if it is the apply of an implicit function
2016
+ * class, and the expected type is a function type. This rule is needed so we can pass
2017
+ * an implicit function to a regular function type. So the following is OK
2018
+ *
2019
+ * val f: implicit A => B = ???
2020
+ * val g: A => B = f
2021
+ *
2022
+ * and the last line expands to
2023
+ *
2024
+ * val g: A => B = (x$0: A) => f.apply(x$0)
2025
+ *
2026
+ * One could be tempted not to eta expand the rhs, but that would violate the invariant
2027
+ * that expressions of implicit function types are always implicit closures, which is
2028
+ * exploited by ShortcutImplicits.
2029
+ *
2030
+ * On the other hand, the following would give an error if there is no implicit
2031
+ * instance of A available.
2032
+ *
2033
+ * val x: AnyRef = f
2034
+ *
2035
+ * That's intentional, we want to fail here, otherwise some unsuccesful implicit searches
2036
+ * would go undetected.
2037
+ *
2038
+ * Examples for these cases are found in run/implicitFuns.scala and neg/i2006.scala.
2039
+ */
2014
2040
def isExpandableApply =
2015
2041
defn.isImplicitFunctionClass(tree.symbol.maybeOwner) && defn.isFunctionType(ptNorm)
2016
2042
2017
2043
// Reasons NOT to eta expand:
2018
2044
// - we reference a constructor
2019
2045
// - we are in a patterm
2020
- // - the current tree is a synthetic non-implicit apply (eta-expasion would simply undo that)
2021
- // - the current tree is a synthetic implicit apply and the expected
2022
- // type is a function type (this rule is needed so we can pass an implicit function
2023
- // to a regular function type)
2046
+ // - the current tree is a synthetic apply which is not expandable (eta-expasion would simply undo that)
2024
2047
if (arity >= 0 &&
2025
2048
! tree.symbol.isConstructor &&
2026
2049
! ctx.mode.is(Mode .Pattern ) &&
0 commit comments