Skip to content

Commit 4d89123

Browse files
committed
Deprecate nested class shadowing
Fixes scala/bug#8353 Fixes scala/bug#11360 This deprecates nested class shadowing for Dotty compatibilty.
1 parent d1b3235 commit 4d89123

17 files changed

+105
-61
lines changed

src/compiler/scala/tools/nsc/typechecker/RefChecks.scala

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -272,6 +272,7 @@ abstract class RefChecks extends Transform {
272272
* that are not implemented in a subclass.
273273
* 4. Check that every member with an `override` modifier
274274
* overrides some other member.
275+
* 5. Check that the nested class do not shadow other nested classes from outer class's parent.
275276
*/
276277
private def checkAllOverrides(clazz: Symbol, typesOnly: Boolean = false): Unit = {
277278
val self = clazz.thisType
@@ -832,7 +833,26 @@ abstract class RefChecks extends Transform {
832833
}
833834
member resetFlag (OVERRIDE | ABSOVERRIDE) // Any Override
834835
}
835-
}
836+
837+
// 5. Check that the nested class do not shadow other nested classes from outer class's parent
838+
def checkNestedClassShadow(): Unit =
839+
if (clazz.isNestedClass) {
840+
val outers = clazz.enclClassChain.filterNot(_ == clazz)
841+
outers foreach { outer =>
842+
outer.baseClasses
843+
.filter(x => x != outer && x != AnyRefClass && x != AnyClass && x != ObjectClass)
844+
.foreach(base => {
845+
val sym2 = base.info.decl(clazz.name)
846+
if (sym2 != NoSymbol && sym2 != clazz && sym2.isClass) {
847+
def msg(what: String) = s"class shadowing is $what but class ${clazz.name} shadows $sym2 defined in ${sym2.owner}; rename the class to something else"
848+
if (currentRun.isScala300) reporter.error(clazz.pos, msg("unsupported"))
849+
else currentRun.reporting.deprecationWarning(clazz.pos, clazz, msg("deprecated"), "2.13.2")
850+
}
851+
})
852+
}
853+
}
854+
checkNestedClassShadow()
855+
} // end checkAllOverrides
836856

837857
// Basetype Checking --------------------------------------------------------
838858

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
nested-class-shadowing-removal.scala:9: error: class shadowing is unsupported but class Status shadows class Status defined in trait Core; rename the class to something else
2+
class Status extends super.Status
3+
^
4+
1 error
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
// scalac: -Werror -Xlint:deprecation -Xsource:3.0
2+
//
3+
4+
trait Core {
5+
class Status
6+
}
7+
8+
trait Ext extends Core {
9+
class Status extends super.Status
10+
}
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
nested-class-shadowing.scala:9: warning: class shadowing is deprecated but class Status shadows class Status defined in trait Core; rename the class to something else
2+
class Status extends super.Status
3+
^
4+
error: No warnings can be incurred under -Werror.
5+
1 warning
6+
1 error
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
// scalac: -Werror -Xlint:deprecation
2+
//
3+
4+
trait Core {
5+
class Status
6+
}
7+
8+
trait Ext extends Core {
9+
class Status extends super.Status
10+
}

test/files/res/t597.check

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
11

2-
nsc>
3-
nsc>
2+
nsc> warning: 2 deprecations (since 2.13.2); re-run with -deprecation for details
3+
4+
nsc> warning: 1 deprecation (since 2.13.2); re-run with -deprecation for details
5+
46
nsc>

test/files/res/t743.check

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11

2-
nsc>
2+
nsc> warning: 1 deprecation (since 2.13.2); re-run with -deprecation for details
3+
34
nsc>
45
nsc>

test/files/res/t831.check

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11

2-
nsc>
2+
nsc> warning: 3 deprecations (since 2.13.2); re-run with -deprecation for details
3+
34
nsc>
45
nsc>

test/files/run/bugs.check

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -84,12 +84,6 @@ hello
8484
<<< bug 328
8585
>>> bug 328
8686

87-
<<< bug 396
88-
A
89-
B
90-
C
91-
>>> bug 396
92-
9387
<<< bug 399
9488
a
9589
>>> bug 399

test/files/run/bugs.scala

Lines changed: 3 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,6 @@
1+
// scalac: -Werror -Xlint:deprecation
2+
//
3+
14
//############################################################################
25
// Bugs
36
//############################################################################
@@ -394,29 +397,6 @@ object Bug328Test {
394397
def test(args: Array[String]): Unit = test0(args);
395398
}
396399

397-
//############################################################################
398-
// Bug 396
399-
400-
trait Bug396A {
401-
class I {
402-
def run = Console.println("A");
403-
}
404-
}
405-
trait Bug396B extends Bug396A {
406-
class I extends super.I {
407-
override def run = { super.run; Console.println("B"); }
408-
}
409-
}
410-
trait Bug396C extends Bug396A {
411-
trait I extends super.I {
412-
override def run = { super.run; Console.println("C"); }
413-
}
414-
}
415-
object Bug396Test extends Bug396B with Bug396C {
416-
class I2 extends super[Bug396B].I with super[Bug396C].I;
417-
def test(args: Array[String]): Unit = (new I2).run
418-
}
419-
420400
//############################################################################
421401
// Bug 399
422402

@@ -476,7 +456,6 @@ object Test {
476456
test(266, Bug266Test.test(args));
477457
test(316, Bug316Test.test(args));
478458
test(328, Bug328Test.test(args));
479-
test(396, Bug396Test.test(args));
480459
test(399, Bug399Test.test(args));
481460

482461
if (errors > 0) {

0 commit comments

Comments
 (0)