Skip to content

Commit

Permalink
fix: better error messages when an enum derives from AnyVal (#22236)
Browse files Browse the repository at this point in the history
Closes #21944
  • Loading branch information
hamzaremmal authored Dec 18, 2024
2 parents ae80285 + 54312c6 commit 60b5dd1
Show file tree
Hide file tree
Showing 6 changed files with 21 additions and 2 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -219,6 +219,7 @@ enum ErrorMessageID(val isActive: Boolean = true) extends java.lang.Enum[ErrorMe
case DeprecatedAssignmentSyntaxID // errorNumber: 203
case DeprecatedInfixNamedArgumentSyntaxID // errorNumber: 204
case GivenSearchPriorityID // errorNumber: 205
case EnumMayNotBeValueClassesID // errorNumber: 206

def errorNumber = ordinal - 1

Expand Down
6 changes: 6 additions & 0 deletions compiler/src/dotty/tools/dotc/reporting/messages.scala
Original file line number Diff line number Diff line change
Expand Up @@ -3399,3 +3399,9 @@ class GivenSearchPriorityWarning(
|$migrationHints"""

def explain(using Context) = ""

final class EnumMayNotBeValueClasses(sym: Symbol)(using Context) extends SyntaxMsg(EnumMayNotBeValueClassesID):
def msg(using Context): String = i"$sym may not be a value class"

def explain(using Context) = ""
end EnumMayNotBeValueClasses
7 changes: 6 additions & 1 deletion compiler/src/dotty/tools/dotc/typer/Checking.scala
Original file line number Diff line number Diff line change
Expand Up @@ -734,11 +734,16 @@ object Checking {
case _ =>
report.error(ValueClassesMayNotContainInitalization(clazz), stat.srcPos)
}
if (clazz.isDerivedValueClass) {
// We don't check synthesised enum anonymous classes that are generated from
// enum extending a value class type (AnyVal or an alias of it)
// The error message 'EnumMayNotBeValueClassesID' will take care of generating the error message (See #22236)
if (clazz.isDerivedValueClass && !clazz.isEnumAnonymClass) {
if (clazz.is(Trait))
report.error(CannotExtendAnyVal(clazz), clazz.srcPos)
if clazz.is(Module) then
report.error(CannotExtendAnyVal(clazz), clazz.srcPos)
if (clazz.is(Enum))
report.error(EnumMayNotBeValueClasses(clazz), clazz.srcPos)
if (clazz.is(Abstract))
report.error(ValueClassesMayNotBeAbstract(clazz), clazz.srcPos)
if (!clazz.isStatic)
Expand Down
3 changes: 2 additions & 1 deletion compiler/src/dotty/tools/dotc/typer/Namer.scala
Original file line number Diff line number Diff line change
Expand Up @@ -1626,7 +1626,8 @@ class Namer { typer: Typer =>
}
else {
val pclazz = pt.typeSymbol
if pclazz.is(Final) then
// The second condition avoids generating a useless message (See #22236 for more details)
if pclazz.is(Final) && !(pclazz.is(Enum) && pclazz.isDerivedValueClass) then
report.error(ExtendFinalClass(cls, pclazz), cls.srcPos)
else if pclazz.isEffectivelySealed && pclazz.associatedFile != cls.associatedFile then
if pclazz.is(Sealed) && !pclazz.is(JavaDefined) then
Expand Down
4 changes: 4 additions & 0 deletions tests/neg/i21944.check
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
-- [E206] Syntax Error: tests/neg/i21944.scala:1:5 ---------------------------------------------------------------------
1 |enum Orientation extends AnyVal: // error
| ^
| class Orientation may not be a value class
2 changes: 2 additions & 0 deletions tests/neg/i21944.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
enum Orientation extends AnyVal: // error
case North, South, East, West

0 comments on commit 60b5dd1

Please sign in to comment.