Skip to content

Add error message for only functional erased or implicit types #7848

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions compiler/src/dotty/tools/dotc/parsing/Parsers.scala
Original file line number Diff line number Diff line change
Expand Up @@ -1431,9 +1431,9 @@ object Parsers {
case FORSOME => syntaxError(ExistentialTypesNoLongerSupported()); t
case _ =>
if (imods.isOneOf(GivenOrImplicit) && !t.isInstanceOf[FunctionWithMods])
syntaxError("Types with implicit keyword can only be function types `implicit (...) => ...`", implicitKwPos(start))
syntaxError(ImplicitTypesCanOnlyBeFunctionTypes(), implicitKwPos(start))
if (imods.is(Erased) && !t.isInstanceOf[FunctionWithMods])
syntaxError("Types with erased keyword can only be function types `erased (...) => ...`", implicitKwPos(start))
syntaxError(ErasedTypesCanOnlyBeFunctionTypes(), implicitKwPos(start))
t
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -149,7 +149,9 @@ enum ErrorMessageID extends java.lang.Enum[ErrorMessageID] {
TraitParameterUsedAsParentPrefixID,
UnknownNamedEnclosingClassOrObjectID,
IllegalCyclicTypeReferenceID,
MissingTypeParameterInTypeAppID
MissingTypeParameterInTypeAppID,
ImplicitTypesCanOnlyBeFunctionTypesID,
ErasedTypesCanOnlyBeFunctionTypesID

def errorNumber = ordinal - 2
}
14 changes: 14 additions & 0 deletions compiler/src/dotty/tools/dotc/reporting/diagnostic/messages.scala
Original file line number Diff line number Diff line change
Expand Up @@ -2381,4 +2381,18 @@ object messages {
val msg: String = i"illegal cyclic type reference: ${where} ${hl(lastChecked.show)} of $sym refers back to the type itself"
val explanation: String = ""
}

case class ImplicitTypesCanOnlyBeFunctionTypes()(implicit val ctx: Context)
extends Message(ImplicitTypesCanOnlyBeFunctionTypesID) {
val kind: String = "Syntax"
val msg: String = "Types with given keyword can only be function types `given (...) => ...`"
val explanation: String = ""
}

case class ErasedTypesCanOnlyBeFunctionTypes()(implicit val ctx: Context)
extends Message(ErasedTypesCanOnlyBeFunctionTypesID) {
val kind: String = "Syntax"
val msg: String = "Types with erased keyword can only be function types `erased (...) => ...`"
val explanation: String = ""
}
}
1 change: 1 addition & 0 deletions compiler/test/dotty/tools/DottyTest.scala
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ trait DottyTest extends ContextEscapeDetection {
protected def initializeCtx(fc: FreshContext): Unit = {
fc.setSetting(fc.settings.encoding, "UTF8")
fc.setSetting(fc.settings.classpath, TestConfiguration.basicClasspath)
fc.setSetting(fc.settings.YerasedTerms, true)
fc.setProperty(ContextDoc, new ContextDocstrings)
}

Expand Down
26 changes: 26 additions & 0 deletions compiler/test/dotty/tools/dotc/reporting/ErrorMessagesTests.scala
Original file line number Diff line number Diff line change
Expand Up @@ -1684,4 +1684,30 @@ class ErrorMessagesTests extends ErrorMessagesTest {
assertEquals("alias", where)
assertEquals("List[X]", lastChecked.show)
}

@Test def implicitTypesCanOnlyBeFunctionTypesSuccess() =
checkMessagesAfter(RefChecks.name) ("def foo(f: (given Int) => Int): Int = 1")
.expectNoErrors

@Test def erasedTypesCanOnlyBeFunctionTypesSuccess() =
checkMessagesAfter(FrontEnd.name) ("def foo(f: (erased Int) => Int): Int = 1")
.expectNoErrors

@Test def implicitTypesCanOnlyBeFunctionTypesFailed() =
checkMessagesAfter(FrontEnd.name) ("def foo(f: (given Int)): Int = 1")
.expect { (ictx, messages) =>
implicit val ctx: Context = ictx
assertMessageCount(1, messages)
val ImplicitTypesCanOnlyBeFunctionTypes() :: Nil = messages
assertEquals("Types with given keyword can only be function types `given (...) => ...`", messages.head.msg)
}

@Test def erasedTypesCanOnlyBeFunctionTypesFailed() =
checkMessagesAfter(FrontEnd.name) ("def foo(f: (erased Int)): Int = 1")
.expect { (ictx, messages) =>
implicit val ctx: Context = ictx
assertMessageCount(1, messages)
val ErasedTypesCanOnlyBeFunctionTypes() :: Nil = messages
assertEquals("Types with erased keyword can only be function types `erased (...) => ...`", messages.head.msg)
}
}