-
Notifications
You must be signed in to change notification settings - Fork 1.1k
Fix #5008: forbid any class extending enums #5031
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Fix #5008: forbid any class extending enums #5031
Conversation
ctx.error(em"normal case $cls in ${cls.owner} cannot extend an enum", cdef.pos) | ||
if (!cdef.mods.isEnumCase && !isEnumAnonCls) { | ||
if (cls.is(Case)) | ||
ctx.error(em"normal case $cls in ${cls.owner} cannot extend an enum", cdef.pos) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we don't need a special error message for case class anymore
tests/pos/enum-List-control.scala
Outdated
@@ -1,20 +0,0 @@ | |||
abstract sealed class List[T] extends Enum |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why is this test removed?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It appears to be entirely about the feature we’re removing, which is why I asked about it.
else if (firstParent != defn.EnumClass && firstParent.derivesFrom(defn.EnumClass) && !cdef.mods.isEnumCase && !isEnumAnonCls) | ||
// Since enums are classes and Namer checks that classes don't extend multiple classes, we only check the class | ||
// parent. | ||
//Tricky to phrase; language taken from "case-to-case inheritance is prohibited". |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Comment irelevant
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No, the messages should be evolved together, so it’s relevant for maintainers. I can make that clearer tho.
// Since enums are classes and Namer checks that classes don't extend multiple classes, we only check the class | ||
// parent. | ||
//Tricky to phrase; language taken from "case-to-case inheritance is prohibited". | ||
ctx.error(s"${cls.name} has enum ancestor ${firstParent.name}, but inheriting from enums is prohibited", cdef.pos) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why not simply: ${cls.name} inherits from enum ${firstParent.name}, ...
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Because that doesn’t say that inheriting from an enum is a problem. We explain that even for case classes, as the “irrelevant” comment points out.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I didn't mean to remove the part after the comma, just rephrase the first part:
"${cls.name} inherits from enum ${firstParent.name}, but inheriting from enums is prohibited"
I find it weird to talk about ancestor when it really is the first parent. Ideally enum should be treated as effectively final and we should report errors similarly to final
inheritance rather than case to case inheritance. Ideally something like:
enum Foo { case F }
class Bar extends Foo
class Bat extends Bar
shoud report similar errors as:
final class Foo
class Bar extends Foo // error: class Bar cannot extend final class Foo
class Bat extends Bar // no error here
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Memo to self: using the flag would not be transitive, so it would also avoid this double reporting.
And the two commits should be squashed since the second commit pretty much reverts the first one |
I think we can differentiate between extending enums and extending the trait |
@Blaisorblade This has been inactive for a month. Let's finish it now. |
79020c7
to
c599de2
Compare
c599de2
to
2dfd81a
Compare
Forbid any class from extending enums. However, keep allowing to extend
Enum
by hand (per current testcase). Thanks to @allanrenucci for the suggesting how.Building on top of #5028, and alternative to it.I'm not sure that's a good idea — there's a testcase from 2017 about this (from d3b2c37, 0ee3281), but it doesn't seem in the spirit of the current restricted enums./cc @hrhino.