From 61ff261346289f7886350a8a4da5688574070e59 Mon Sep 17 00:00:00 2001 From: Paul Phillips Date: Fri, 11 Sep 2009 15:23:05 +0000 Subject: Deprecated case classes inheriting from other c... Deprecated case classes inheriting from other case classes, and updated all the tests which did so. --- .../scala/tools/nsc/typechecker/Typers.scala | 11 ++++++++ test/files/neg/bug473.scala | 2 +- test/files/pos/bug1087.scala | 2 -- test/files/pos/jesper.scala | 30 ---------------------- test/files/pos/t0710.scala | 2 +- test/files/pos/t1087.scala | 3 --- test/files/pos/typesafecons.scala | 2 +- test/files/run/canEqualCaseClasses.scala | 23 ----------------- test/files/run/caseclasses.scala | 6 ----- test/files/run/patmatnew.scala | 2 +- test/files/run/t0607.scala | 6 ++--- test/files/run/t0883.scala | 3 ++- 12 files changed, 20 insertions(+), 72 deletions(-) delete mode 100644 test/files/pos/bug1087.scala delete mode 100644 test/files/pos/jesper.scala delete mode 100644 test/files/pos/t1087.scala delete mode 100644 test/files/run/canEqualCaseClasses.scala diff --git a/src/compiler/scala/tools/nsc/typechecker/Typers.scala b/src/compiler/scala/tools/nsc/typechecker/Typers.scala index d9471c6008..790e7e99ca 100644 --- a/src/compiler/scala/tools/nsc/typechecker/Typers.scala +++ b/src/compiler/scala/tools/nsc/typechecker/Typers.scala @@ -1143,6 +1143,17 @@ trait Typers { self: Analyzer => if (psym hasFlag FINAL) { error(parent.pos, "illegal inheritance from final "+psym) } + // XXX I think this should issue a sharper warning of some kind like + // "change your code now!" as there are material bugs (which will not be fixed) + // associated with case class inheritance. + if ((context.owner hasFlag CASE) && !phase.erasedTypes) { + for (ancestor <- parent.tpe.baseClasses find (_ hasFlag CASE)) + unit.deprecationWarning(parent.pos, ( + "case class `%s' has case class ancestor `%s'. This has been deprecated " + + "for unduly complicating both usage and implementation. You should instead " + + "use extractors for pattern matching on non-leaf nodes." ).format(context.owner, ancestor) + ) + } if (psym.isSealed && !phase.erasedTypes) { if (context.unit.source.file != psym.sourceFile) error(parent.pos, "illegal inheritance from sealed "+psym) diff --git a/test/files/neg/bug473.scala b/test/files/neg/bug473.scala index 831f647f71..4c434b9fc0 100644 --- a/test/files/neg/bug473.scala +++ b/test/files/neg/bug473.scala @@ -1,3 +1,3 @@ -case class Foo(x: Foo) +class Foo(x: Foo) case object Bar extends Foo(null) case object Voop extends Foo(Voop) \ No newline at end of file diff --git a/test/files/pos/bug1087.scala b/test/files/pos/bug1087.scala deleted file mode 100644 index 19d62116c6..0000000000 --- a/test/files/pos/bug1087.scala +++ /dev/null @@ -1,2 +0,0 @@ -case class Foo -case class Prd (pred : Char => Boolean) extends Foo diff --git a/test/files/pos/jesper.scala b/test/files/pos/jesper.scala deleted file mode 100644 index b2a027b0f2..0000000000 --- a/test/files/pos/jesper.scala +++ /dev/null @@ -1,30 +0,0 @@ -object Pair { - sealed trait Pair { - type First - type Second <: Pair - } - - case class End extends Pair { - type First = Nothing - type Second = End - - def ::[T](v : T) : Cons[T, End] = Cons(v, this) - } - - case object End extends End - - final case class Cons[T1, T2 <: Pair](_1 : T1, _2 : T2) extends Pair { - type First = T1 - type Second = T2 - - def ::[T](v : T) : Cons[T, Cons[T1, T2]] = Cons(v, this) - def find[T](implicit finder : Cons[T1, T2] => T) = finder(this) - } - - implicit def findFirst[T1, T2 <: Pair] : Cons[T1, T2] => T1 = (p : Cons[T1, T2]) => p._1 - implicit def findSecond[T, T1, T2 <: Pair](implicit finder : T2 => T) : Cons[T1, T2] => T = (p : Cons[T1, T2]) => finder(p._2) - - val p : Cons[Int, Cons[Boolean, End]] = 10 :: false :: End -// val x : Boolean = p.find[Boolean](findSecond(findFirst)) - val x2 : Boolean = p.find[Boolean] // Doesn't compile -} diff --git a/test/files/pos/t0710.scala b/test/files/pos/t0710.scala index 4512a101d9..fb440bc796 100644 --- a/test/files/pos/t0710.scala +++ b/test/files/pos/t0710.scala @@ -1,6 +1,6 @@ object t0710 { def method { - sealed case class Parent + sealed class Parent case object Child extends Parent val x: Parent = Child x match { diff --git a/test/files/pos/t1087.scala b/test/files/pos/t1087.scala deleted file mode 100644 index bb0d7012c1..0000000000 --- a/test/files/pos/t1087.scala +++ /dev/null @@ -1,3 +0,0 @@ -case class Foo -case class Prd (pred : Char => Boolean) extends Foo - diff --git a/test/files/pos/typesafecons.scala b/test/files/pos/typesafecons.scala index b2a027b0f2..5243280160 100644 --- a/test/files/pos/typesafecons.scala +++ b/test/files/pos/typesafecons.scala @@ -4,7 +4,7 @@ object Pair { type Second <: Pair } - case class End extends Pair { + class End extends Pair { type First = Nothing type Second = End diff --git a/test/files/run/canEqualCaseClasses.scala b/test/files/run/canEqualCaseClasses.scala deleted file mode 100644 index b1c3eb91de..0000000000 --- a/test/files/run/canEqualCaseClasses.scala +++ /dev/null @@ -1,23 +0,0 @@ -object Test { - case class Foo(x: Int) - case class Bar(y: Int) extends Foo(y) - case class Nutty() { - override def canEqual(other: Any) = true - } - - def assertEqual(x: AnyRef, y: AnyRef) = - assert((x == y) && (y == x) && (x.hashCode == y.hashCode)) - - def assertUnequal(x: AnyRef, y: AnyRef) = - assert((x != y) && (y != x)) - - def main(args: Array[String]): Unit = { - assertEqual(Foo(5), Foo(5)) - assertEqual(Bar(5), Bar(5)) - assertUnequal(Foo(5), Bar(5)) - - // in case there's an overriding implementation - assert(Nutty() canEqual (new AnyRef)) - assert(!(Foo(5) canEqual (new AnyRef))) - } -} diff --git a/test/files/run/caseclasses.scala b/test/files/run/caseclasses.scala index 56fe6dad96..ed5643a709 100644 --- a/test/files/run/caseclasses.scala +++ b/test/files/run/caseclasses.scala @@ -2,8 +2,6 @@ case class Foo(x: Int)(y: Int) case class Bar -case class Baz(override val x: Int, y: Int) extends Foo(x)(y) - abstract class Base abstract case class Abs(x: Int) extends Base @@ -30,10 +28,6 @@ object Test extends Application { case Foo(1) => Console.println("OK") case Bar() => Console.println("NO") } - (Baz(1, 2): AnyRef) match { - case Baz(1, 2) => ; - case Bar() => Console.println("NO") - } try { Bar() productElement 3 throw new NullPointerException("duh") diff --git a/test/files/run/patmatnew.scala b/test/files/run/patmatnew.scala index 34bd024b29..c78fceb96b 100644 --- a/test/files/run/patmatnew.scala +++ b/test/files/run/patmatnew.scala @@ -928,7 +928,7 @@ override def runTest() { object Ticket710 { // compile-only def method { - sealed case class Parent() + sealed class Parent() case object Child extends Parent() val x: Parent = Child x match { diff --git a/test/files/run/t0607.scala b/test/files/run/t0607.scala index afc7ff9b46..5601494dec 100644 --- a/test/files/run/t0607.scala +++ b/test/files/run/t0607.scala @@ -1,7 +1,7 @@ object Test extends Application { - case class A - case class B extends A + case class A() + class B extends A() { override def toString() = "B()" } println(A()) - println(B()) + println(new B()) } diff --git a/test/files/run/t0883.scala b/test/files/run/t0883.scala index 5cd4418f5b..b9d71702d8 100755 --- a/test/files/run/t0883.scala +++ b/test/files/run/t0883.scala @@ -1,4 +1,5 @@ -case class Foo(name: String) +object Foo { def apply(x: String) = new Foo(x) } +class Foo(name: String) case object Bar extends Foo("Bar") case class Baz extends Foo("Baz") object Test extends Application { -- cgit v1.2.3