Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
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
3 changes: 2 additions & 1 deletion compiler/src/dotty/tools/dotc/reporting/ErrorMessageID.scala
Original file line number Diff line number Diff line change
Expand Up @@ -167,7 +167,8 @@ enum ErrorMessageID extends java.lang.Enum[ErrorMessageID] {
ModifierNotAllowedForDefinitionID,
CannotExtendJavaEnumID,
InvalidReferenceInImplicitNotFoundAnnotationID,
TraitMayNotDefineNativeMethodID
TraitMayNotDefineNativeMethodID,
JavaEnumParentArgsID

def errorNumber = ordinal - 2
}
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 @@ -1528,6 +1528,12 @@ import transform.SymUtils._
def explain = ""
}

class JavaEnumParentArgs(parent: Type)(using Context)
extends TypeMsg(JavaEnumParentArgsID) {
def msg = em"""not enough arguments for constructor Enum: ${hl("(name: String, ordinal: Int)")}: ${hl(parent.show)}"""
def explain = ""
}

class CannotHaveSameNameAs(sym: Symbol, cls: Symbol, reason: CannotHaveSameNameAs.Reason)(using Context)
extends SyntaxMsg(CannotHaveSameNameAsID) {
import CannotHaveSameNameAs._
Expand Down
25 changes: 19 additions & 6 deletions compiler/src/dotty/tools/dotc/typer/RefChecks.scala
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@ object RefChecks {
* and required classes. Also check that only `enum` constructs extend
* `java.lang.Enum`.
*/
private def checkParents(cls: Symbol)(using Context): Unit = cls.info match {
private def checkParents(cls: Symbol, parentTrees: List[Tree])(using Context): Unit = cls.info match {
case cinfo: ClassInfo =>
def checkSelfConforms(other: ClassSymbol, category: String, relation: String) = {
val otherSelf = other.declaredSelfTypeAsSeenFrom(cls.thisType)
Expand All @@ -109,12 +109,25 @@ object RefChecks {
for (reqd <- cinfo.cls.givenSelfType.classSymbols)
checkSelfConforms(reqd, "missing requirement", "required")

def illegalEnumFlags = !cls.isOneOf(Enum | Trait)
def isJavaEnum = parents.exists(_.classSymbol == defn.JavaEnumClass)

// Prevent wrong `extends` of java.lang.Enum
if !migrateTo3 &&
!cls.isOneOf(Enum | Trait) &&
parents.exists(_.classSymbol == defn.JavaEnumClass)
then
if !migrateTo3 && illegalEnumFlags && isJavaEnum then
report.error(CannotExtendJavaEnum(cls), cls.sourcePos)
else if illegalEnumFlags && isJavaEnum then
val javaEnumCtor = defn.JavaEnumClass.primaryConstructor
parentTrees.exists(parent =>
parent.tpe.typeSymbol == defn.JavaEnumClass
&& (
parent match
case tpd.Apply(tpd.TypeApply(fn, _), _) if fn.tpe.termSymbol eq javaEnumCtor =>
// here we are simulating the error for missing arguments to a constructor.
report.error(JavaEnumParentArgs(parent.tpe), cls.sourcePos)
true
case _ =>
false
))

case _ =>
}
Expand Down Expand Up @@ -1089,7 +1102,7 @@ class RefChecks extends MiniPhase { thisPhase =>
override def transformTemplate(tree: Template)(using Context): Tree = try {
val cls = ctx.owner.asClass
checkOverloadedRestrictions(cls)
checkParents(cls)
checkParents(cls, tree.parents)
if (cls.is(Trait)) tree.parents.foreach(checkParentPrefix(cls, _))
checkCompanionNameClashes(cls)
checkAllOverrides(cls)
Expand Down
12 changes: 12 additions & 0 deletions tests/neg/extend-java-enum-migration.check
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
-- [E160] Type Error: tests/neg/extend-java-enum-migration.scala:9:12 --------------------------------------------------
9 |final class C extends jl.Enum[C] // error
| ^
| not enough arguments for constructor Enum: (name: String, ordinal: Int): Enum[C]
-- [E160] Type Error: tests/neg/extend-java-enum-migration.scala:11:7 --------------------------------------------------
11 |object O extends jl.Enum[O.type] // error
| ^
| not enough arguments for constructor Enum: (name: String, ordinal: Int): Enum[O.type]
-- [E160] Type Error: tests/neg/extend-java-enum-migration.scala:14:6 --------------------------------------------------
14 |class Sub extends T // error
| ^
| not enough arguments for constructor Enum: (name: String, ordinal: Int): Enum[T]
14 changes: 14 additions & 0 deletions tests/neg/extend-java-enum-migration.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import java.{lang => jl}

import language.`3.0-migration`

// This file is different from `tests/neg/extend-java-enum.scala` as we
// are testing that it is illegal to *not* pass arguments to jl.Enum
// in 3.0-migration

final class C extends jl.Enum[C] // error

object O extends jl.Enum[O.type] // error

trait T extends jl.Enum[T] // ok
class Sub extends T // error