Skip to content

Commit 72d9322

Browse files
Allow traits to extend jl.Enum, and classes to do so in migration mode
1 parent 277873f commit 72d9322

File tree

5 files changed

+37
-3
lines changed

5 files changed

+37
-3
lines changed

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

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ import scala.util.{Try, Failure, Success}
1717
import config.{ScalaVersion, NoScalaVersion}
1818
import Decorators._
1919
import typer.ErrorReporting._
20-
import config.Feature.warnOnMigration
20+
import config.Feature.{warnOnMigration, migrateTo3}
2121
import reporting._
2222

2323
object RefChecks {
@@ -106,8 +106,13 @@ object RefChecks {
106106
for (reqd <- cinfo.cls.givenSelfType.classSymbols)
107107
checkSelfConforms(reqd, "missing requirement", "required")
108108

109-
if !cls.is(Enum) && parents.exists(_.classSymbol == defn.JavaEnumClass) then
109+
// Prevent wrong `extends` of java.lang.Enum
110+
if !migrateTo3 &&
111+
!cls.isOneOf(Enum | Trait) &&
112+
parents.exists(_.classSymbol == defn.JavaEnumClass)
113+
then
110114
report.error(CannotExtendJavaEnum(cls), cls.sourcePos)
115+
111116
case _ =>
112117
}
113118

compiler/test/dotty/tools/dotc/CompilationTests.scala

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,7 @@ class CompilationTests extends ParallelTesting {
6666
compileFile("tests/pos-custom-args/i5498-postfixOps.scala", defaultOptions withoutLanguageFeature "postfixOps"),
6767
compileFile("tests/pos-custom-args/i8875.scala", defaultOptions.and("-Xprint:getters")),
6868
compileFile("tests/pos-custom-args/i9267.scala", defaultOptions.and("-Ystop-after:erasure")),
69+
compileFile("tests/pos-special/extend-java-enum.scala", defaultOptions.and("-source", "3.0-migration")),
6970
).checkCompile()
7071
}
7172

tests/neg/extend-java-enum.scala

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,4 +4,6 @@ class C1 extends jl.Enum[C1] // error: class C1 cannot extend java.lang.Enum
44

55
class C2(name: String, ordinal: Int) extends jl.Enum[C2](name, ordinal) // error: class C2 cannot extend java.lang.Enum
66

7-
trait T extends jl.Enum[T] // error: trait T cannot extend java.lang.Enum
7+
trait T extends jl.Enum[T] // ok
8+
9+
class C3 extends T // error: class C3 cannot extend java.lang.Enum
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
import java.{lang => jl}
2+
3+
final class ConfigSyntax private (name: String, ordinal: Int)
4+
extends jl.Enum[ConfigSyntax](name, ordinal)
5+
6+
object ConfigSyntax {
7+
8+
final val JSON = new ConfigSyntax("JSON", 0)
9+
final val CONF = new ConfigSyntax("CONF", 1)
10+
final val PROPERTIES = new ConfigSyntax("PROPERTIES", 2)
11+
12+
private[this] final val _values: Array[ConfigSyntax] =
13+
Array(JSON, CONF, PROPERTIES)
14+
15+
def values: Array[ConfigSyntax] = _values.clone()
16+
17+
def valueOf(name: String): ConfigSyntax =
18+
_values.find(_.name == name).getOrElse {
19+
throw new IllegalArgumentException("No enum const ConfigSyntax." + name)
20+
}
21+
}

tests/pos/trait-java-enum.scala

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
trait T extends java.lang.Enum[T]
2+
3+
enum MyEnum extends T {
4+
case A, B
5+
}

0 commit comments

Comments
 (0)