From be3df1782b689858f15a9a1dd518b65794e91e09 Mon Sep 17 00:00:00 2001 From: Dale Wijnand Date: Fri, 6 Mar 2020 08:54:07 +0000 Subject: [PATCH] Silence outer pointer warnings in class-based REPL Case classes, such as final case classes nested within other classes, lose their outer pointer which makes their equality lie (scala/bug#4440): scala> class Outer { final case class Inner(n: Int) } warning: there was one unchecked warning; for details, enable `:setting -unchecked' or `:replay -unchecked' defined class Outer scala> val o1, o2 = new Outer o1: Outer = Outer@627bcd7e o2: Outer = Outer@70543cae scala> new o1.Inner(1) == new o2.Inner(1) res0: Boolean = true vs scala> class Outer { case class Inner(n: Int) } defined class Outer scala> val o1, o2 = new Outer o1: Outer = Outer@77ba583 o2: Outer = Outer@5613247e scala> new o1.Inner(1) == new o2.Inner(1) res0: Boolean = false This isn't a problem in the REPL even with its class-based wrappers as there is only ever 1 instance of (each) wrapper class. --- .../transform/patmat/MatchTreeMaking.scala | 2 +- .../run/repl-class-based-outer-pointers.check | 14 ++++++++ .../run/repl-class-based-outer-pointers.scala | 35 +++++++++++++++++++ 3 files changed, 50 insertions(+), 1 deletion(-) create mode 100644 test/files/run/repl-class-based-outer-pointers.check create mode 100644 test/files/run/repl-class-based-outer-pointers.scala diff --git a/src/compiler/scala/tools/nsc/transform/patmat/MatchTreeMaking.scala b/src/compiler/scala/tools/nsc/transform/patmat/MatchTreeMaking.scala index 4a6731744dcd..15f3dba8247b 100644 --- a/src/compiler/scala/tools/nsc/transform/patmat/MatchTreeMaking.scala +++ b/src/compiler/scala/tools/nsc/transform/patmat/MatchTreeMaking.scala @@ -355,7 +355,7 @@ trait MatchTreeMaking extends MatchCodeGen with Debugging { // this also includes methods and (possibly nested) objects inside of methods. def definedInStaticLocation(tp: Type): Boolean = { def isStatic(tp: Type): Boolean = - if (tp == NoType || tp.typeSymbol.isPackageClass || tp == NoPrefix) true + if (tp == NoType || tp.typeSymbol.isPackageClass || tp == NoPrefix || nme.isReplWrapperName(tp.typeSymbol.name)) true else if (tp.typeSymbol.isModuleClass) isStatic(tp.prefix) else false tp.typeSymbol.owner == tp.prefix.typeSymbol && isStatic(tp.prefix) diff --git a/test/files/run/repl-class-based-outer-pointers.check b/test/files/run/repl-class-based-outer-pointers.check new file mode 100644 index 000000000000..0e2fec8062c1 --- /dev/null +++ b/test/files/run/repl-class-based-outer-pointers.check @@ -0,0 +1,14 @@ + +scala> sealed abstract class Value; object Value { + final case class Num(value: Double) extends Value + final case class Str(value: String) extends Value + final case class Bool(value: Boolean) extends Value +} +defined class Value +defined object Value + +scala> class C { final case class Num(value: Double) } // here it should still warn +warning: there was one unchecked warning; for details, enable `:setting -unchecked' or `:replay -unchecked' +defined class C + +scala> :quit diff --git a/test/files/run/repl-class-based-outer-pointers.scala b/test/files/run/repl-class-based-outer-pointers.scala new file mode 100644 index 000000000000..58cbed80b4a5 --- /dev/null +++ b/test/files/run/repl-class-based-outer-pointers.scala @@ -0,0 +1,35 @@ +import scala.tools.nsc.Settings +import scala.tools.partest.ReplTest + +object Test extends ReplTest { + override def transformSettings(s: Settings) = { + s.Yreplclassbased.value = true + s + } + + def code = """ + |sealed abstract class Value; object Value { + | final case class Num(value: Double) extends Value + | final case class Str(value: String) extends Value + | final case class Bool(value: Boolean) extends Value + |} + |class C { final case class Num(value: Double) } // here it should still warn + |""".stripMargin // scala/bug#11902 +} + +/* was: + +scala> sealed abstract class Value; object Value { + final case class Num(value: Double) extends Value + final case class Str(value: String) extends Value + final case class Bool(value: Boolean) extends Value +} +warning: there were three unchecked warnings; for details, enable `:setting -unchecked' or `:replay -unchecked' +defined class Value +defined object Value + +scala> class C { final case class Num(value: Double) } // here it should still warn +warning: there was one unchecked warning; for details, enable `:setting -unchecked' or `:replay -unchecked' +defined class C + + */