Skip to content

Commit bc37acd

Browse files
oderskymichelou
authored andcommitted
Disallow lambdas in statement position
Disallow lambdas in statement position or if the expected type is Unit. Fixes scala#11671
1 parent 69fb762 commit bc37acd

File tree

3 files changed

+27
-13
lines changed

3 files changed

+27
-13
lines changed

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

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,14 @@ object ErrorReporting {
4343
def wrongNumberOfTypeArgs(fntpe: Type, expectedArgs: List[ParamInfo], actual: List[untpd.Tree], pos: SrcPos)(using Context): ErrorType =
4444
errorType(WrongNumberOfTypeArgs(fntpe, expectedArgs, actual), pos)
4545

46+
def missingArgs(tree: Tree, mt: Type)(using Context): Unit =
47+
val meth = err.exprStr(methPart(tree))
48+
mt match
49+
case mt: MethodType if mt.paramNames.isEmpty =>
50+
report.error(MissingEmptyArgumentList(meth), tree.srcPos)
51+
case _ =>
52+
report.error(em"missing arguments for $meth", tree.srcPos)
53+
4654
class Errors(using Context) {
4755

4856
/** An explanatory note to be added to error messages

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

Lines changed: 11 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -3110,12 +3110,9 @@ class Typer extends Namer
31103110
def readapt(tree: Tree, shouldTryGadtHealing: Boolean = tryGadtHealing)(using Context) = adapt(tree, pt, locked, shouldTryGadtHealing)
31113111
def readaptSimplified(tree: Tree)(using Context) = readapt(simplify(tree, pt, locked))
31123112

3113-
def missingArgs(mt: MethodType) = {
3114-
val meth = err.exprStr(methPart(tree))
3115-
if (mt.paramNames.length == 0) report.error(MissingEmptyArgumentList(meth), tree.srcPos)
3116-
else report.error(em"missing arguments for $meth", tree.srcPos)
3113+
def missingArgs(mt: MethodType) =
3114+
ErrorReporting.missingArgs(tree, mt)
31173115
tree.withType(mt.resultType)
3118-
}
31193116

31203117
def adaptOverloaded(ref: TermRef) = {
31213118
val altDenots =
@@ -3409,19 +3406,19 @@ class Typer extends Namer
34093406
// - we reference a typelevel method
34103407
// - we are in a pattern
34113408
// - the current tree is a synthetic apply which is not expandable (eta-expasion would simply undo that)
3412-
if (arity >= 0 &&
3413-
!tree.symbol.isConstructor &&
3414-
!tree.symbol.isAllOf(InlineMethod) &&
3415-
!ctx.mode.is(Mode.Pattern) &&
3416-
!(isSyntheticApply(tree) && !functionExpected)) {
3409+
if arity >= 0
3410+
&& !tree.symbol.isConstructor
3411+
&& !tree.symbol.isAllOf(InlineMethod)
3412+
&& !ctx.mode.is(Mode.Pattern)
3413+
&& !(isSyntheticApply(tree) && !functionExpected)
3414+
then
34173415
if (!defn.isFunctionType(pt))
34183416
pt match {
34193417
case SAMType(_) if !pt.classSymbol.hasAnnotation(defn.FunctionalInterfaceAnnot) =>
34203418
report.warning(ex"${tree.symbol} is eta-expanded even though $pt does not have the @FunctionalInterface annotation.", tree.srcPos)
34213419
case _ =>
34223420
}
34233421
simplify(typed(etaExpand(tree, wtp, arity), pt), pt, locked)
3424-
}
34253422
else if (wtp.paramInfos.isEmpty && isAutoApplied(tree.symbol))
34263423
readaptSimplified(tpd.Apply(tree, Nil))
34273424
else if (wtp.isImplicitMethod)
@@ -3841,8 +3838,9 @@ class Typer extends Namer
38413838
&& !tree.isInstanceOf[Inlined]
38423839
&& isPureExpr(tree)
38433840
&& !isSelfOrSuperConstrCall(tree)
3844-
then
3845-
report.warning(PureExpressionInStatementPosition(original, exprOwner), original.srcPos)
3841+
then tree match
3842+
case closureDef(_) => missingArgs(tree, tree.tpe.widen)
3843+
case _ => report.warning(PureExpressionInStatementPosition(original, exprOwner), original.srcPos)
38463844

38473845
/** Types the body Scala 2 macro declaration `def f = macro <body>` */
38483846
private def typedScala2MacroBody(call: untpd.Tree)(using Context): Tree =

tests/neg/i11671.scala

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
def go(x: Int): Unit =
2+
go // error
3+
go // error
4+
go // error
5+
6+
def foo: Unit =
7+
(x: Int) => go(x) // error
8+

0 commit comments

Comments
 (0)