Skip to content

Commit 1fcdc61

Browse files
committed
Warn for usage of open modifier on traits or classes where redundant
Fixes #11963
1 parent ea0002d commit 1fcdc61

File tree

6 files changed

+40
-11
lines changed

6 files changed

+40
-11
lines changed

compiler/src/dotty/tools/dotc/ast/Desugar.scala

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -451,6 +451,14 @@ object desugar {
451451
}
452452
else originalTparams
453453

454+
if mods.is(Open) && (mods.isOneOf(AbstractOrTrait) || ctx.owner.is(Method)) then
455+
val kind =
456+
if mods.is(Abstract) then RedundantModifierOwnerKind.AbstractClass
457+
else if mods.is(Trait) then RedundantModifierOwnerKind.Trait
458+
else RedundantModifierOwnerKind.LocalClass
459+
val srcPos = mods.mods.find(_.flags == Open).get.srcPos
460+
report.warning(ModifierRedundantFor(cdef, "open", kind), srcPos)
461+
454462
if mods.is(Trait) then
455463
for vparams <- originalVparamss; vparam <- vparams do
456464
if vparam.tpt.isInstanceOf[ByNameTypeTree] then
@@ -865,10 +873,10 @@ object desugar {
865873
if (mods.is(Abstract))
866874
report.error(AbstractCannotBeUsedForObjects(mdef), flagSourcePos(Abstract))
867875
if (mods.is(Sealed))
868-
report.error(ModifierRedundantForObjects(mdef, "sealed"), flagSourcePos(Sealed))
876+
report.error(ModifierRedundantFor(mdef, "sealed", RedundantModifierOwnerKind.Module), flagSourcePos(Sealed))
869877
// Maybe this should be an error; see https://github.com/scala/bug/issues/11094.
870878
if (mods.is(Final) && !mods.is(Synthetic))
871-
report.warning(ModifierRedundantForObjects(mdef, "final"), flagSourcePos(Final))
879+
report.warning(ModifierRedundantFor(mdef, "final", RedundantModifierOwnerKind.Module), flagSourcePos(Final))
872880

873881
if (mods.is(Package))
874882
packageModuleDef(mdef)

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -156,6 +156,7 @@ enum ErrorMessageID extends java.lang.Enum[ErrorMessageID] {
156156
EnumerationsShouldNotBeEmptyID,
157157
AbstractCannotBeUsedForObjectsID,
158158
ModifierRedundantForObjectsID,
159+
ModifierRedundantForID,
159160
TypedCaseDoesNotExplicitlyExtendTypedEnumID,
160161
IllegalRedefinitionOfStandardKindID,
161162
NoExtensionMethodAllowedID,

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

Lines changed: 21 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -2379,17 +2379,29 @@ import transform.SymUtils._
23792379
|""".stripMargin
23802380
}
23812381

2382-
class ModifierRedundantForObjects(mdef: untpd.ModuleDef, modifier: String)(using Context)
2383-
extends SyntaxMsg(ModifierRedundantForObjectsID) {
2384-
def msg = em"${hl(modifier)} modifier is redundant for objects"
2385-
2386-
def explain =
2387-
em"""|Objects cannot be extended making the ${hl(modifier)} modifier redundant.
2388-
|You may want to define the object without it:
2389-
| ${hl("object")} ${mdef.name} { }
2382+
enum RedundantModifierOwnerKind {
2383+
case AbstractClass, LocalClass, Module, Trait
2384+
def show: String = this match
2385+
case AbstractClass => "abstract class"
2386+
case LocalClass => "class"
2387+
case Module => "object"
2388+
case Trait => "trait"
2389+
def namePlural: String = this match
2390+
case AbstractClass => "abstract classes"
2391+
case LocalClass => "local classes"
2392+
case Module => "objects"
2393+
case Trait => "traits"
2394+
}
2395+
2396+
class ModifierRedundantFor(tree: untpd.NameTree, modifier: String, ownerKind: RedundantModifierOwnerKind)(using Context)
2397+
extends SyntaxMsg(ModifierRedundantForID) {
2398+
def msg = em"${hl(modifier)} modifier is redundant here"
2399+
def explain =
2400+
em"""|The modifier ${hl(modifier)} is redundant on ${ownerKind.namePlural}.
2401+
|You may want to define the ${ownerKind.show} without it:
2402+
| ${hl(ownerKind.show)} ${tree.name} { }
23902403
|""".stripMargin
23912404
}
2392-
23932405
class TypedCaseDoesNotExplicitlyExtendTypedEnum(enumDef: Symbol, caseDef: untpd.TypeDef)(using Context)
23942406
extends SyntaxMsg(TypedCaseDoesNotExplicitlyExtendTypedEnumID) {
23952407
def msg = i"explicit extends clause needed because both enum case and enum class have type parameters"
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
open trait Foo // redundant modifier open
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
open abstract class Foo // redundant modifier open
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
object Test {
2+
def foo: Any = {
3+
open class Bar // redundant modifier open
4+
new Bar
5+
}
6+
}

0 commit comments

Comments
 (0)