Skip to content

Commit b6a0d1c

Browse files
authored
Merge pull request #154 from scala/backport-lts-3.3-22236
Backport "fix: better error messages when an enum derives from AnyVal" to 3.3 LTS
2 parents b63e940 + 95dcbc6 commit b6a0d1c

File tree

6 files changed

+31
-9
lines changed

6 files changed

+31
-9
lines changed

compiler/src/dotty/tools/dotc/reporting/ErrorMessageID.scala

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -216,6 +216,10 @@ enum ErrorMessageID(val isActive: Boolean = true) extends java.lang.Enum[ErrorMe
216216
case FinalLocalDefID // errorNumber: 200
217217
case NonNamedArgumentInJavaAnnotationID // errorNumber: 201 - unused in LTS
218218
case QuotedTypeMissingID // errorNumber: 202
219+
case DeprecatedAssignmentSyntaxID // errorNumber: 203
220+
case DeprecatedInfixNamedArgumentSyntaxID // errorNumber: 204
221+
case GivenSearchPriorityID // errorNumber: 205
222+
case EnumMayNotBeValueClassesID // errorNumber: 206
219223

220224
def errorNumber = ordinal - 1
221225

compiler/src/dotty/tools/dotc/reporting/messages.scala

Lines changed: 13 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1812,12 +1812,12 @@ class NotAPath(tp: Type, usage: String)(using Context) extends TypeMsg(NotAPathI
18121812
if sym.isAllOf(Flags.InlineParam) then
18131813
i"""
18141814
|Inline parameters are not considered immutable paths and cannot be used as
1815-
|singleton types.
1816-
|
1815+
|singleton types.
1816+
|
18171817
|Hint: Removing the `inline` qualifier from the `${sym.name}` parameter
18181818
|may help resolve this issue."""
18191819
else ""
1820-
1820+
18211821

18221822
class WrongNumberOfParameters(tree: untpd.Tree, foundCount: Int, pt: Type, expectedCount: Int)(using Context)
18231823
extends SyntaxMsg(WrongNumberOfParametersID) {
@@ -3173,15 +3173,21 @@ final class QuotedTypeMissing(tpe: Type)(using Context) extends StagingMessage(Q
31733173

31743174
private def witness = defn.QuotedTypeClass.typeRef.appliedTo(tpe)
31753175

3176-
override protected def msg(using Context): String =
3176+
override protected def msg(using Context): String =
31773177
i"Reference to $tpe within quotes requires a given ${witness} in scope"
31783178

31793179
override protected def explain(using Context): String =
3180-
i"""Referencing `$tpe` inside a quoted expression requires a `${witness}` to be in scope.
3180+
i"""Referencing `$tpe` inside a quoted expression requires a `${witness}` to be in scope.
31813181
|Since Scala is subject to erasure at runtime, the type information will be missing during the execution of the code.
3182-
|`${witness}` is therefore needed to carry `$tpe`'s type information into the quoted code.
3183-
|Without an implicit `${witness}`, the type `$tpe` cannot be properly referenced within the expression.
3182+
|`${witness}` is therefore needed to carry `$tpe`'s type information into the quoted code.
3183+
|Without an implicit `${witness}`, the type `$tpe` cannot be properly referenced within the expression.
31843184
|To resolve this, ensure that a `${witness}` is available, either through a context-bound or explicitly.
31853185
|"""
31863186

31873187
end QuotedTypeMissing
3188+
3189+
final class EnumMayNotBeValueClasses(sym: Symbol)(using Context) extends SyntaxMsg(EnumMayNotBeValueClassesID):
3190+
def msg(using Context): String = i"$sym may not be a value class"
3191+
3192+
def explain(using Context) = ""
3193+
end EnumMayNotBeValueClasses

compiler/src/dotty/tools/dotc/typer/Checking.scala

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -715,11 +715,16 @@ object Checking {
715715
case _ =>
716716
report.error(ValueClassesMayNotContainInitalization(clazz), stat.srcPos)
717717
}
718-
if (clazz.isDerivedValueClass) {
718+
// We don't check synthesised enum anonymous classes that are generated from
719+
// enum extending a value class type (AnyVal or an alias of it)
720+
// The error message 'EnumMayNotBeValueClassesID' will take care of generating the error message (See #22236)
721+
if (clazz.isDerivedValueClass && !clazz.isEnumAnonymClass) {
719722
if (clazz.is(Trait))
720723
report.error(CannotExtendAnyVal(clazz), clazz.srcPos)
721724
if clazz.is(Module) then
722725
report.error(CannotExtendAnyVal(clazz), clazz.srcPos)
726+
if (clazz.is(Enum))
727+
report.error(EnumMayNotBeValueClasses(clazz), clazz.srcPos)
723728
if (clazz.is(Abstract))
724729
report.error(ValueClassesMayNotBeAbstract(clazz), clazz.srcPos)
725730
if (!clazz.isStatic)

compiler/src/dotty/tools/dotc/typer/Namer.scala

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1581,7 +1581,8 @@ class Namer { typer: Typer =>
15811581
}
15821582
else {
15831583
val pclazz = pt.typeSymbol
1584-
if pclazz.is(Final) then
1584+
// The second condition avoids generating a useless message (See #22236 for more details)
1585+
if pclazz.is(Final) && !(pclazz.is(Enum) && pclazz.isDerivedValueClass) then
15851586
report.error(ExtendFinalClass(cls, pclazz), cls.srcPos)
15861587
else if pclazz.isEffectivelySealed && pclazz.associatedFile != cls.associatedFile then
15871588
if pclazz.is(Sealed) && !pclazz.is(JavaDefined) then

tests/neg/i21944.check

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
-- [E206] Syntax Error: tests/neg/i21944.scala:1:5 ---------------------------------------------------------------------
2+
1 |enum Orientation extends AnyVal: // error
3+
| ^
4+
| class Orientation may not be a value class

tests/neg/i21944.scala

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
enum Orientation extends AnyVal: // error
2+
case North, South, East, West

0 commit comments

Comments
 (0)