Skip to content

Commit cc88c5d

Browse files
committed
Fine-tune condition when to eta expand
1 parent 8b9b68c commit cc88c5d

File tree

3 files changed

+21
-11
lines changed

3 files changed

+21
-11
lines changed

compiler/src/dotty/tools/dotc/ast/TreeInfo.scala

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -477,7 +477,9 @@ trait TypedTreeInfo extends TreeInfo[Type] { self: Trees.Instance[Type] =>
477477
case _ => false
478478
}
479479

480-
/** Is tree a compiler-generated `.apply` node? */
480+
/** Is tree a compiler-generated `.apply` node that refers to the
481+
* apply of a function class? (implicit functions are excluded)
482+
*/
481483
def isSyntheticApply(tree: Tree): Boolean = tree match {
482484
case Select(qual, nme.apply) => tree.pos.end == qual.pos.end
483485
case _ => false

compiler/src/dotty/tools/dotc/core/Definitions.scala

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -809,8 +809,8 @@ class Definitions {
809809
*/
810810
def erasedFunctionClass(cls: Symbol): Symbol = {
811811
val arity = scalaClassName(cls).functionArity
812-
if (arity > 22) defn.FunctionXXLClass
813-
else if (arity >= 0) defn.FunctionClass(arity)
812+
if (arity > 22) FunctionXXLClass
813+
else if (arity >= 0) FunctionClass(arity)
814814
else NoSymbol
815815
}
816816

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

Lines changed: 16 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2011,17 +2011,25 @@ 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-
if (wtp.isImplicit)
2016-
err.typeMismatch(tree, pt)
2017-
else if (arity >= 0 &&
2018-
!tree.symbol.isConstructor &&
2019-
!ctx.mode.is(Mode.Pattern) &&
2020-
!isApplyProto(pt) &&
2021-
!isSyntheticApply(tree))
2014+
def isExpandableApply =
2015+
defn.isImplicitFunctionClass(tree.symbol.maybeOwner) && defn.isFunctionType(ptNorm)
2016+
2017+
// Reasons NOT to eta expand:
2018+
// - we reference a constructor
2019+
// - 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)
2024+
if (arity >= 0 &&
2025+
!tree.symbol.isConstructor &&
2026+
!ctx.mode.is(Mode.Pattern) &&
2027+
!(isSyntheticApply(tree) && !isExpandableApply))
20222028
typed(etaExpand(tree, wtp, arity), pt)
20232029
else if (wtp.paramInfos.isEmpty)
20242030
adaptInterpolated(tpd.Apply(tree, Nil), pt, EmptyTree)
2031+
else if (wtp.isImplicit)
2032+
err.typeMismatch(tree, pt)
20252033
else
20262034
missingArgs
20272035
case _ =>

0 commit comments

Comments
 (0)