diff --git a/compiler/src/dotty/tools/dotc/typer/Checking.scala b/compiler/src/dotty/tools/dotc/typer/Checking.scala index 9e3528ff0388..a9573ff9e48b 100644 --- a/compiler/src/dotty/tools/dotc/typer/Checking.scala +++ b/compiler/src/dotty/tools/dotc/typer/Checking.scala @@ -1080,7 +1080,8 @@ trait Checking { report.error(em"$what can only be used in an inline method", pos) /** 1. Check that all case classes that extend `scala.Enum` are `enum` cases - * 2. Check that case class `enum` cases do not extend java.lang.Enum. + * 2. Check that parameterised `enum` cases do not extend java.lang.Enum. + * 3. Check that only a static `enum` base class can extend java.lang.Enum. */ def checkEnum(cdef: untpd.TypeDef, cls: Symbol, firstParent: Symbol)(using Context): Unit = { def isEnumAnonCls = @@ -1088,12 +1089,14 @@ trait Checking { && cls.owner.isTerm && (cls.owner.flagsUNSAFE.isAllOf(EnumCase) || ((cls.owner.name eq nme.DOLLAR_NEW) && cls.owner.flagsUNSAFE.isAllOf(Private | Synthetic))) - if (!isEnumAnonCls) - if (cdef.mods.isEnumCase) { - if (cls.derivesFrom(defn.JavaEnumClass)) + val isJavaEnum = cls.derivesFrom(defn.JavaEnumClass) + if isJavaEnum && cdef.mods.isEnumClass && !cls.isStatic then + report.error(em"An enum extending java.lang.Enum must be declared in a static scope", cdef.srcPos) + if !isEnumAnonCls then + if cdef.mods.isEnumCase then + if isJavaEnum then report.error(em"paramerized case is not allowed in an enum that extends java.lang.Enum", cdef.srcPos) - } - else if (cls.is(Case) || firstParent.is(Enum)) + else if cls.is(Case) || firstParent.is(Enum) then // Since enums are classes and Namer checks that classes don't extend multiple classes, we only check the class // parent. // diff --git a/tests/neg/extend-java-enum-nonstatic.scala b/tests/neg/extend-java-enum-nonstatic.scala new file mode 100644 index 000000000000..5f0b6d36f8a8 --- /dev/null +++ b/tests/neg/extend-java-enum-nonstatic.scala @@ -0,0 +1,22 @@ +import java.{lang => jl} + +object TestSuite: + def test(op: => Unit): Unit = op + test { + enum E extends jl.Enum[E] { case A } // error: enum extending java.lang.Enum must be declared in a static scope + } + +class Container: + enum E extends jl.Enum[E] { case A } // error: enum extending java.lang.Enum must be declared in a static scope + +object Wrap: + def force = + enum E extends jl.Enum[E] { case A } // error: enum extending java.lang.Enum must be declared in a static scope + +trait Universe: + enum E extends jl.Enum[E] { case A } // error: enum extending java.lang.Enum must be declared in a static scope + +enum E extends jl.Enum[E] { case A } // ok, a declaration at package level is static. + +object Static: + enum E extends jl.Enum[E] { case A } // ok, a declaration within a static object is static.