@@ -2011,16 +2011,39 @@ class Typer extends Namer with TypeAssigner with Applications with Implicits wit
20112011 if (nparams > 0 || pt.eq(AnyFunctionProto )) nparams
20122012 else - 1 // no eta expansion in this case
20132013 }
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+ */
20142040 def isExpandableApply =
20152041 defn.isImplicitFunctionClass(tree.symbol.maybeOwner) && defn.isFunctionType(ptNorm)
20162042
20172043 // Reasons NOT to eta expand:
20182044 // - we reference a constructor
20192045 // - 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)
20242047 if (arity >= 0 &&
20252048 ! tree.symbol.isConstructor &&
20262049 ! ctx.mode.is(Mode .Pattern ) &&
0 commit comments