diff --git a/compiler/src/dotty/tools/dotc/reporting/diagnostic/messages.scala b/compiler/src/dotty/tools/dotc/reporting/diagnostic/messages.scala index ab79b8524d9c..bd0e27cbd7ce 100644 --- a/compiler/src/dotty/tools/dotc/reporting/diagnostic/messages.scala +++ b/compiler/src/dotty/tools/dotc/reporting/diagnostic/messages.scala @@ -1715,10 +1715,11 @@ object messages { } } - case class FunctionTypeNeedsNonEmptyParameterList(isImplicit: Boolean = true, isErased: Boolean = true)(implicit ctx: Context) + case class FunctionTypeNeedsNonEmptyParameterList(isImplicit: Boolean, isErased: Boolean)(implicit ctx: Context) extends Message(FunctionTypeNeedsNonEmptyParameterListID) { + assert(isImplicit || isErased) val kind = "Syntax" - val mods = ((isImplicit, "implicit") :: (isErased, "erased") :: Nil).filter(_._1).mkString(" ") + val mods = ((isErased, "erased") :: (isImplicit, "implicit") :: Nil).collect { case (true, mod) => mod }.mkString(" ") val msg = mods + " function type needs non-empty parameter list" val explanation = { val code1 = s"type Transactional[T] = $mods Transaction => T" diff --git a/compiler/src/dotty/tools/dotc/typer/Typer.scala b/compiler/src/dotty/tools/dotc/typer/Typer.scala index 2a5937b42571..954bd38ec216 100644 --- a/compiler/src/dotty/tools/dotc/typer/Typer.scala +++ b/compiler/src/dotty/tools/dotc/typer/Typer.scala @@ -764,7 +764,7 @@ class Typer extends Namer case tree: untpd.NonEmptyFunction => if (args.nonEmpty) (tree.mods.is(Implicit), tree.mods.is(Erased)) else { - ctx.error(FunctionTypeNeedsNonEmptyParameterList(), tree.pos) + ctx.error(FunctionTypeNeedsNonEmptyParameterList(tree.mods.is(Implicit), tree.mods.is(Erased)), tree.pos) (false, false) } case _ => (false, false) diff --git a/compiler/test/dotty/tools/dotc/reporting/ErrorMessagesTests.scala b/compiler/test/dotty/tools/dotc/reporting/ErrorMessagesTests.scala index aa96910be106..1d730311b4dd 100644 --- a/compiler/test/dotty/tools/dotc/reporting/ErrorMessagesTests.scala +++ b/compiler/test/dotty/tools/dotc/reporting/ErrorMessagesTests.scala @@ -881,7 +881,7 @@ class ErrorMessagesTests extends ErrorMessagesTest { implicit val ctx: Context = ictx assertMessageCount(2, messages) - messages.foreach(assertEquals(_, FunctionTypeNeedsNonEmptyParameterList())) + messages.foreach(assertEquals(_, FunctionTypeNeedsNonEmptyParameterList(isImplicit = true, isErased = false))) } @Test def wrongNumberOfParameters = @@ -1306,4 +1306,46 @@ class ErrorMessagesTests extends ErrorMessagesTest { val DoubleDeclaration(symbol, previousSymbol) :: Nil = messages assertEquals(symbol.name.mangledString, "a") } + + @Test def i4127a = + checkMessagesAfter("frontend") { + """ + |class Foo { + | val x: implicit () => Int = () => 1 + |} + """.stripMargin + }.expect { (ictx, messages) => + implicit val ctx: Context = ictx + assertMessageCount(1, messages) + val (msg @ FunctionTypeNeedsNonEmptyParameterList(_, _)) :: Nil = messages + assertEquals(msg.mods, "implicit") + } + + @Test def i4127b = + checkMessagesAfter("frontend") { + """ + |class Foo { + | val x: erased () => Int = () => 1 + |} + """.stripMargin + }.expect { (ictx, messages) => + implicit val ctx: Context = ictx + assertMessageCount(1, messages) + val (msg @ FunctionTypeNeedsNonEmptyParameterList(_, _)) :: Nil = messages + assertEquals(msg.mods, "erased") + } + + @Test def i4127c = + checkMessagesAfter("frontend") { + """ + |class Foo { + | val x: erased implicit () => Int = () => 1 + |} + """.stripMargin + }.expect { (ictx, messages) => + implicit val ctx: Context = ictx + assertMessageCount(1, messages) + val (msg @ FunctionTypeNeedsNonEmptyParameterList(_, _)) :: Nil = messages + assertEquals(msg.mods, "erased implicit") + } }