Skip to content

Commit 5d118ac

Browse files
committed
Refine synthesized lambda criterion
- Don't eta expand at all if expected type is Unit. That way we do not have to figure out whether it was an eta expansion after the fact. - For statements the expected type is not Unit, but we do have the original and we can check whether it was a function or a partial function.
1 parent 940e771 commit 5d118ac

File tree

2 files changed

+7
-10
lines changed

2 files changed

+7
-10
lines changed

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

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -329,6 +329,11 @@ trait UntypedTreeInfo extends TreeInfo[Untyped] { self: Trees.Instance[Untyped]
329329
def isFunctionWithUnknownParamType(tree: Tree): Boolean =
330330
functionWithUnknownParamType(tree).isDefined
331331

332+
def isFunction(tree: Tree): Boolean = tree match
333+
case Function(_, _) | Match(EmptyTree, _) => true
334+
case Block(Nil, expr) => isFunction(expr)
335+
case _ => false
336+
332337
/** Is `tree` an context function or closure, possibly nested in a block? */
333338
def isContextualClosure(tree: Tree)(using Context): Boolean = unsplice(tree) match {
334339
case tree: FunctionWithMods => tree.mods.is(Given)

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

Lines changed: 2 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -3415,6 +3415,7 @@ class Typer extends Namer
34153415
&& !tree.symbol.isAllOf(InlineMethod)
34163416
&& !ctx.mode.is(Mode.Pattern)
34173417
&& !(isSyntheticApply(tree) && !functionExpected)
3418+
&& !pt.isRef(defn.UnitClass)
34183419
then
34193420
if (!defn.isFunctionType(pt))
34203421
pt match {
@@ -3830,17 +3831,8 @@ class Typer extends Namer
38303831
&& isPureExpr(tree)
38313832
&& !isSelfOrSuperConstrCall(tree)
38323833
then tree match
3833-
case closureDef(meth)
3834-
if meth.span == meth.rhs.span.toSynthetic
3835-
&& !original.isInstanceOf[untpd.Function] =>
3834+
case closureDef(meth) if !untpd.isFunction(original) =>
38363835
// It's a synthesized lambda, for instance via an eta expansion: report a hard error
3837-
// There are two tests for synthetic lambdas which both have to be true.
3838-
// The first test compares spans of closure definition with the closure's right hand
3839-
// side. This is usually accurate but can fail for compiler-generated test code.
3840-
// See repl.DocTests for two failing tests. The second tests rules out closures
3841-
// if the original tree was a lambda. This does not work always either since
3842-
// sometimes we do not have the original anymore and use the transformed tree instead.
3843-
// But taken together, the two criteria are quite accurate.
38443836
missingArgs(tree, tree.tpe.widen)
38453837
case _ =>
38463838
report.warning(PureExpressionInStatementPosition(original, exprOwner), original.srcPos)

0 commit comments

Comments
 (0)