Skip to content

Commit 08442eb

Browse files
committed
Better documentation of when to eta expand
1 parent cc88c5d commit 08442eb

File tree

1 file changed

+27
-4
lines changed

1 file changed

+27
-4
lines changed

compiler/src/dotty/tools/dotc/typer/Typer.scala

Lines changed: 27 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -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

Comments
 (0)