diff --git a/src/dotty/tools/dotc/typer/Applications.scala b/src/dotty/tools/dotc/typer/Applications.scala index 099105de359a..885270aa9d19 100644 --- a/src/dotty/tools/dotc/typer/Applications.scala +++ b/src/dotty/tools/dotc/typer/Applications.scala @@ -601,16 +601,16 @@ trait Applications extends Compatibility { self: Typer with Dynamic => case _ => tryEither { implicit ctx => simpleApply(fun1, proto) - } { - (failedVal, failedState) => - def fail = { failedState.commit(); failedVal } - // Try once with original prototype and once (if different) with tupled one. - // The reason we need to try both is that the decision whether to use tupled - // or not was already taken but might have to be revised when an implicit - // is inserted on the qualifier. - tryWithImplicitOnQualifier(fun1, originalProto).getOrElse( - if (proto eq originalProto) fail - else tryWithImplicitOnQualifier(fun1, proto).getOrElse(fail)) + } { (failedVal, failedState) => + def fail = { failedState.commit(); failedVal } + // Try once with original prototype and once (if different) with tupled one. + // The reason we need to try both is that the decision whether to use tupled + // or not was already taken but might have to be revised when an implicit + // is inserted on the qualifier. + tryWithImplicitOnQualifier(fun1, originalProto) getOrElse { + if (proto eq originalProto) fail + else tryWithImplicitOnQualifier(fun1, proto).getOrElse(fail) + } } } } diff --git a/src/dotty/tools/dotc/typer/Typer.scala b/src/dotty/tools/dotc/typer/Typer.scala index fdcfe347be56..803656cc7f56 100644 --- a/src/dotty/tools/dotc/typer/Typer.scala +++ b/src/dotty/tools/dotc/typer/Typer.scala @@ -533,7 +533,16 @@ class Typer extends Namer with TypeAssigner with Applications with Implicits wit def typedBlock(tree: untpd.Block, pt: Type)(implicit ctx: Context) = track("typedBlock") { val exprCtx = index(tree.stats) val stats1 = typedStats(tree.stats, ctx.owner) - val expr1 = typedExpr(tree.expr, pt)(exprCtx) + + // A block might appear in function position after desugaring (see + // i1503.scala), so adaptation may insert a `.apply` at the end of expr1. + // When this happens we simply remove the select to make expr1 a valid + // block expression. The `.apply` will be added back around the block when + // the block itself is adapted later. + val expr1 = typedExpr(tree.expr, pt)(exprCtx) match { + case Select(x, nme.apply) => x + case x => x + } ensureNoLocalRefs( assignType(cpy.Block(tree)(stats1, expr1), stats1, expr1), pt, localSyms(stats1)) } diff --git a/tests/run/i1503.check b/tests/run/i1503.check new file mode 100644 index 000000000000..d26b33daea1e --- /dev/null +++ b/tests/run/i1503.check @@ -0,0 +1 @@ +working diff --git a/tests/run/i1503.scala b/tests/run/i1503.scala new file mode 100644 index 000000000000..5fbccf2e6354 --- /dev/null +++ b/tests/run/i1503.scala @@ -0,0 +1,7 @@ +object Test { + def main(args: Array[String]): Unit = { + (new Function0[Unit] { + def apply() = println("working") + })() + } +}