diff --git a/compiler/src/dotty/tools/dotc/reporting/diagnostic/messages.scala b/compiler/src/dotty/tools/dotc/reporting/diagnostic/messages.scala index 088b121da737..2222379b0953 100644 --- a/compiler/src/dotty/tools/dotc/reporting/diagnostic/messages.scala +++ b/compiler/src/dotty/tools/dotc/reporting/diagnostic/messages.scala @@ -1835,10 +1835,10 @@ object messages { } } - case class OnlyFunctionsCanBeFollowedByUnderscore(pt: Type)(implicit ctx: Context) + case class OnlyFunctionsCanBeFollowedByUnderscore(tp: Type)(implicit ctx: Context) extends Message(OnlyFunctionsCanBeFollowedByUnderscoreID) { val kind = "Syntax" - val msg = hl"Not a function: $pt: cannot be followed by ${"_"}" + val msg = hl"Only function types can be followed by ${"_"} but the current expression has type $tp" val explanation = hl"""The syntax ${"x _"} is no longer supported if ${"x"} is not a function. |To convert to a function value, you need to explicitly write ${"() => x"}""" diff --git a/compiler/src/dotty/tools/dotc/typer/Typer.scala b/compiler/src/dotty/tools/dotc/typer/Typer.scala index 754ccddefed2..88fb0c9494d3 100644 --- a/compiler/src/dotty/tools/dotc/typer/Typer.scala +++ b/compiler/src/dotty/tools/dotc/typer/Typer.scala @@ -1645,9 +1645,10 @@ class Typer extends Namer val nestedCtx = ctx.fresh.setNewTyperState() val res = typed(qual, pt1)(nestedCtx) res match { - case res @ closure(_, _, _) => + case closure(_, _, _) => case _ => - ctx.errorOrMigrationWarning(OnlyFunctionsCanBeFollowedByUnderscore(res.tpe), tree.pos) + val recovered = typed(qual)(ctx.fresh.setExploreTyperState()) + ctx.errorOrMigrationWarning(OnlyFunctionsCanBeFollowedByUnderscore(recovered.tpe.widen), tree.pos) if (ctx.scala2Mode) { // Under -rewrite, patch `x _` to `(() => x)` patch(Position(tree.pos.start), "(() => ") diff --git a/compiler/test-resources/repl/errmsgs b/compiler/test-resources/repl/errmsgs index dbf6779d56b7..0acdde67a633 100644 --- a/compiler/test-resources/repl/errmsgs +++ b/compiler/test-resources/repl/errmsgs @@ -72,3 +72,11 @@ scala> val a: iDontExist = 1 1 | val a: iDontExist = 1 | ^^^^^^^^^^ | not found: type iDontExist +scala> def foo1(x: => Int) = x _ +1 | def foo1(x: => Int) = x _ + | ^^^ + |Only function types can be followed by _ but the current expression has type Int +scala> def foo2(x: => Int): () => Int = x _ +1 | def foo2(x: => Int): () => Int = x _ + | ^^^ + |Only function types can be followed by _ but the current expression has type Int \ No newline at end of file diff --git a/compiler/test/dotty/tools/dotc/reporting/ErrorMessagesTests.scala b/compiler/test/dotty/tools/dotc/reporting/ErrorMessagesTests.scala index 96f6c55ce501..aa96910be106 100644 --- a/compiler/test/dotty/tools/dotc/reporting/ErrorMessagesTests.scala +++ b/compiler/test/dotty/tools/dotc/reporting/ErrorMessagesTests.scala @@ -1050,8 +1050,8 @@ class ErrorMessagesTests extends ErrorMessagesTest { implicit val ctx: Context = ictx assertMessageCount(1, messages) - val OnlyFunctionsCanBeFollowedByUnderscore(pt) :: Nil = messages - assertEquals("String(n)", pt.show) + val OnlyFunctionsCanBeFollowedByUnderscore(tp) :: Nil = messages + assertEquals("String", tp.show) } @Test def missingEmptyArgumentList =