diff --git a/compiler/src/dotty/tools/dotc/reporting/diagnostic/ErrorMessageID.java b/compiler/src/dotty/tools/dotc/reporting/diagnostic/ErrorMessageID.java index b4dbd031bea9..f91f19b23014 100644 --- a/compiler/src/dotty/tools/dotc/reporting/diagnostic/ErrorMessageID.java +++ b/compiler/src/dotty/tools/dotc/reporting/diagnostic/ErrorMessageID.java @@ -97,6 +97,7 @@ public enum ErrorMessageID { DuplicatePrivateProtectedQualifierID, ExpectedStartOfTopLevelDefinitionID, MissingReturnTypeWithReturnStatementID, + NoReturnFromInlineID, ; public int errorNumber() { diff --git a/compiler/src/dotty/tools/dotc/reporting/diagnostic/messages.scala b/compiler/src/dotty/tools/dotc/reporting/diagnostic/messages.scala index 301c9d1582d2..b471a6b2453c 100644 --- a/compiler/src/dotty/tools/dotc/reporting/diagnostic/messages.scala +++ b/compiler/src/dotty/tools/dotc/reporting/diagnostic/messages.scala @@ -1737,4 +1737,14 @@ object messages { hl"you have to provide either ${"class"}, ${"trait"}, ${"object"}, or ${"enum"} definitions after qualifiers" } + case class NoReturnFromInline(owner: Symbol)(implicit ctx: Context) + extends Message(NoReturnFromInlineID) { + val kind = "Syntax" + val msg = hl"no explicit ${"return"} allowed from inline $owner" + val explanation = + hl"""Methods marked with ${"@inline"} may not use ${"return"} statements. + |Instead, you should rely on the last expression's value being + |returned from a method. + |""" + } } diff --git a/compiler/src/dotty/tools/dotc/typer/Typer.scala b/compiler/src/dotty/tools/dotc/typer/Typer.scala index d94a5851574e..a69f509a677e 100644 --- a/compiler/src/dotty/tools/dotc/typer/Typer.scala +++ b/compiler/src/dotty/tools/dotc/typer/Typer.scala @@ -985,7 +985,7 @@ class Typer extends Namer with TypeAssigner with Applications with Implicits wit } else if (owner != cx.outer.owner && owner.isRealMethod) { if (owner.isInlineMethod) - (EmptyTree, errorType(em"no explicit return allowed from inline $owner", tree.pos)) + (EmptyTree, errorType(NoReturnFromInline(owner), tree.pos)) else if (!owner.isCompleted) (EmptyTree, errorType(MissingReturnTypeWithReturnStatement(owner), tree.pos)) else { diff --git a/compiler/test/dotty/tools/dotc/reporting/ErrorMessagesTests.scala b/compiler/test/dotty/tools/dotc/reporting/ErrorMessagesTests.scala index aa473912ed7d..90497f54f8b4 100644 --- a/compiler/test/dotty/tools/dotc/reporting/ErrorMessagesTests.scala +++ b/compiler/test/dotty/tools/dotc/reporting/ErrorMessagesTests.scala @@ -970,4 +970,19 @@ class ErrorMessagesTests extends ErrorMessagesTest { val MissingReturnTypeWithReturnStatement(method) :: Nil = messages assertEquals(method.name.show, "bad") } + + @Test def noReturnInInline = + checkMessagesAfter("frontend") { + """class BadFunction { + | @inline def usesReturn: Int = { return 42 } + |} + """.stripMargin + }.expect { (ictx, messages) => + implicit val ctx: Context = ictx + + assertMessageCount(1, messages) + + val NoReturnFromInline(method) :: Nil = messages + assertEquals("method usesReturn", method.show) + } }