diff --git a/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala b/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala index 5744d3811783..c3f1c0fb362a 100644 --- a/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala +++ b/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala @@ -272,6 +272,7 @@ abstract class RefChecks extends Transform { * that are not implemented in a subclass. * 4. Check that every member with an `override` modifier * overrides some other member. + * 5. Check that the nested class do not shadow other nested classes from outer class's parent. */ private def checkAllOverrides(clazz: Symbol, typesOnly: Boolean = false): Unit = { val self = clazz.thisType @@ -832,7 +833,26 @@ abstract class RefChecks extends Transform { } member resetFlag (OVERRIDE | ABSOVERRIDE) // Any Override } - } + + // 5. Check that the nested class do not shadow other nested classes from outer class's parent + def checkNestedClassShadow(): Unit = + if (clazz.isNestedClass) { + val outers = clazz.enclClassChain.filterNot(_ == clazz) + outers foreach { outer => + outer.baseClasses + .filter(x => x != outer && x != AnyRefClass && x != AnyClass && x != ObjectClass) + .foreach(base => { + val sym2 = base.info.decl(clazz.name) + if (sym2 != NoSymbol && sym2 != clazz && sym2.isClass) { + 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" + if (currentRun.isScala300) reporter.error(clazz.pos, msg("unsupported")) + else currentRun.reporting.deprecationWarning(clazz.pos, clazz, msg("deprecated"), "2.13.2") + } + }) + } + } + checkNestedClassShadow() + } // end checkAllOverrides // Basetype Checking -------------------------------------------------------- diff --git a/test/files/neg/nested-class-shadowing-removal.check b/test/files/neg/nested-class-shadowing-removal.check new file mode 100644 index 000000000000..3477c1b65103 --- /dev/null +++ b/test/files/neg/nested-class-shadowing-removal.check @@ -0,0 +1,4 @@ +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 + class Status extends super.Status + ^ +1 error diff --git a/test/files/neg/nested-class-shadowing-removal.scala b/test/files/neg/nested-class-shadowing-removal.scala new file mode 100644 index 000000000000..2712156f02c1 --- /dev/null +++ b/test/files/neg/nested-class-shadowing-removal.scala @@ -0,0 +1,10 @@ +// scalac: -Werror -Xlint:deprecation -Xsource:3.0 +// + +trait Core { + class Status +} + +trait Ext extends Core { + class Status extends super.Status +} diff --git a/test/files/neg/nested-class-shadowing.check b/test/files/neg/nested-class-shadowing.check new file mode 100644 index 000000000000..96e60b2b584f --- /dev/null +++ b/test/files/neg/nested-class-shadowing.check @@ -0,0 +1,6 @@ +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 + class Status extends super.Status + ^ +error: No warnings can be incurred under -Werror. +1 warning +1 error diff --git a/test/files/neg/nested-class-shadowing.scala b/test/files/neg/nested-class-shadowing.scala new file mode 100644 index 000000000000..cb2a87882de8 --- /dev/null +++ b/test/files/neg/nested-class-shadowing.scala @@ -0,0 +1,10 @@ +// scalac: -Werror -Xlint:deprecation +// + +trait Core { + class Status +} + +trait Ext extends Core { + class Status extends super.Status +} diff --git a/test/files/res/t597.check b/test/files/res/t597.check index 6cf64f734be2..4cea293a5d83 100644 --- a/test/files/res/t597.check +++ b/test/files/res/t597.check @@ -1,4 +1,6 @@ -nsc> -nsc> +nsc> warning: 2 deprecations (since 2.13.2); re-run with -deprecation for details + +nsc> warning: 1 deprecation (since 2.13.2); re-run with -deprecation for details + nsc> diff --git a/test/files/res/t743.check b/test/files/res/t743.check index 6cf64f734be2..0f4aa7526148 100644 --- a/test/files/res/t743.check +++ b/test/files/res/t743.check @@ -1,4 +1,5 @@ -nsc> +nsc> warning: 1 deprecation (since 2.13.2); re-run with -deprecation for details + nsc> nsc> diff --git a/test/files/res/t831.check b/test/files/res/t831.check index 6cf64f734be2..c96021985fea 100644 --- a/test/files/res/t831.check +++ b/test/files/res/t831.check @@ -1,4 +1,5 @@ -nsc> +nsc> warning: 3 deprecations (since 2.13.2); re-run with -deprecation for details + nsc> nsc> diff --git a/test/files/run/bugs.check b/test/files/run/bugs.check index 261c74ad15e8..951c06133ec7 100644 --- a/test/files/run/bugs.check +++ b/test/files/run/bugs.check @@ -84,12 +84,6 @@ hello <<< bug 328 >>> bug 328 -<<< bug 396 -A -B -C ->>> bug 396 - <<< bug 399 a >>> bug 399 diff --git a/test/files/run/bugs.scala b/test/files/run/bugs.scala index 0630b354a8dd..d26816d6cc49 100644 --- a/test/files/run/bugs.scala +++ b/test/files/run/bugs.scala @@ -1,3 +1,6 @@ +// scalac: -Werror -Xlint:deprecation +// + //############################################################################ // Bugs //############################################################################ @@ -394,29 +397,6 @@ object Bug328Test { def test(args: Array[String]): Unit = test0(args); } -//############################################################################ -// Bug 396 - -trait Bug396A { - class I { - def run = Console.println("A"); - } -} -trait Bug396B extends Bug396A { - class I extends super.I { - override def run = { super.run; Console.println("B"); } - } -} -trait Bug396C extends Bug396A { - trait I extends super.I { - override def run = { super.run; Console.println("C"); } - } -} -object Bug396Test extends Bug396B with Bug396C { - class I2 extends super[Bug396B].I with super[Bug396C].I; - def test(args: Array[String]): Unit = (new I2).run -} - //############################################################################ // Bug 399 @@ -476,7 +456,6 @@ object Test { test(266, Bug266Test.test(args)); test(316, Bug316Test.test(args)); test(328, Bug328Test.test(args)); - test(396, Bug396Test.test(args)); test(399, Bug399Test.test(args)); if (errors > 0) { diff --git a/test/files/run/t6146b.check b/test/files/run/t6146b.check index f3131b84b3c6..b662209f432c 100644 --- a/test/files/run/t6146b.check +++ b/test/files/run/t6146b.check @@ -1,4 +1,4 @@ -t6146b.scala:15: warning: match may not be exhaustive. +t6146b.scala:18: warning: match may not be exhaustive. It would fail on the following inputs: S2(), S3() def foo(f: F[Int]) = f match { case X.S1 => } ^ diff --git a/test/files/run/t6146b.scala b/test/files/run/t6146b.scala index be190cc35a4a..62e9ebf50124 100644 --- a/test/files/run/t6146b.scala +++ b/test/files/run/t6146b.scala @@ -1,7 +1,10 @@ +// scalac: -Xlint:deprecation +// + import scala.tools.partest.ReplTest class A { - sealed trait F[A] + // sealed trait F[A] } class C[T] extends A { diff --git a/test/files/run/t657.scala b/test/files/run/t657.scala index e76b0292ddcb..d7f882b4342a 100644 --- a/test/files/run/t657.scala +++ b/test/files/run/t657.scala @@ -1,38 +1,40 @@ +// scalac: -Werror -Xlint:deprecation +// import scala.language.{ implicitConversions } abstract class BaseList { - type Node <: NodeImpl; - implicit def convertNode(ni : NodeImpl) = ni.asInstanceOf[Node]; - abstract class NodeImpl; + type Node <: BaseNodeImpl + implicit def convertNode(ni : BaseNodeImpl) = ni.asInstanceOf[Node]; + abstract class BaseNodeImpl } abstract class LinkedList extends BaseList { - type Node <: NodeImpl; - trait NodeImpl extends super.NodeImpl; + type Node <: NodeImpl0 + trait NodeImpl0 extends super.BaseNodeImpl; } trait OffsetList extends LinkedList { - type Node <: NodeImpl; - trait NodeImpl extends super.NodeImpl; + type Node <: NodeImpl1 + trait NodeImpl1 extends super.NodeImpl0 } trait PriorityTree extends BaseList { - type Node <: NodeImpl; - trait NodeImpl extends super.NodeImpl { - def chop : Node = this; + type Node <: NodeImpl2 + trait NodeImpl2 extends super.BaseNodeImpl { + def chop : Node = this } } trait PrecedenceParser extends LinkedList with PriorityTree { - type Node <: NodeImpl; - trait NodeImpl extends super[LinkedList].NodeImpl with super[PriorityTree].NodeImpl; + type Node <: NodeImpl3 + trait NodeImpl3 extends super[LinkedList].NodeImpl0 with super[PriorityTree].NodeImpl2 } trait Matcher extends PrecedenceParser { - type Node <: NodeImpl; - trait NodeImpl extends super.NodeImpl; + type Node <: NodeImpl4 + trait NodeImpl4 extends super.NodeImpl3 - type Matchable <: Node with MatchableImpl; - implicit def convertMatchable(m : MatchableImpl) = m.asInstanceOf[Matchable]; - trait MatchableImpl extends NodeImpl { + type Matchable <: Node with MatchableImpl0 + implicit def convertMatchable(m : MatchableImpl0) = m.asInstanceOf[Matchable] + trait MatchableImpl0 extends NodeImpl4 { override def chop : Node = { Console.println("passed"); super.chop; } @@ -40,14 +42,14 @@ trait Matcher extends PrecedenceParser { } class Test1 extends OffsetList with Matcher { - type Node = NodeImpl; - trait NodeImpl extends super[OffsetList].NodeImpl with super[Matcher].NodeImpl; - class MatchableImpl extends super.MatchableImpl with NodeImpl; - type Matchable = MatchableImpl; + type Node = NodeImpl5 + trait NodeImpl5 extends super[OffsetList].NodeImpl1 with super[Matcher].NodeImpl4 + class MatchableImpl1 extends super.MatchableImpl0 with NodeImpl5 + type Matchable = MatchableImpl1 } object Test extends App { - val test = new Test1; - val m = new test.MatchableImpl; - m.chop; + val test = new Test1 + val m = new test.MatchableImpl1 + m.chop } diff --git a/test/files/run/t6677b.check b/test/files/run/t6677b.check new file mode 100644 index 000000000000..509f2991af4d --- /dev/null +++ b/test/files/run/t6677b.check @@ -0,0 +1,3 @@ +t6677b.scala:15: warning: class shadowing is deprecated but class X shadows class X defined in trait U1; rename the class to something else + class U11 extends U1 { class X extends super.X { foo } } // refer to foo to add $outer pointer + ^ diff --git a/test/files/run/t6677b.scala b/test/files/run/t6677b.scala index 2106b2d6d736..764f5ac4a0cb 100644 --- a/test/files/run/t6677b.scala +++ b/test/files/run/t6677b.scala @@ -1,3 +1,6 @@ +// scalac: -Xlint:deprecation +// + trait U { trait U1 { class X diff --git a/test/files/run/t744.check b/test/files/run/t744.check index 757bf0137049..dbb16e997a85 100644 --- a/test/files/run/t744.check +++ b/test/files/run/t744.check @@ -1,3 +1,6 @@ +t744.scala:12: warning: class shadowing is deprecated but class FileImpl shadows trait FileImpl defined in trait Linked; rename the class to something else + trait FileImpl extends super.FileImpl { + ^ BEGIN Hello from linked END diff --git a/test/files/run/t744.scala b/test/files/run/t744.scala index 4895e9baa079..e5b4407284a1 100644 --- a/test/files/run/t744.scala +++ b/test/files/run/t744.scala @@ -1,3 +1,6 @@ +// scalac: -Xlint:deprecation +// + trait Linked { type File <: FileImpl; trait FileImpl {