Skip to content

Commit 9a3fc28

Browse files
dwijnandretronym
authored andcommitted
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.
1 parent e1e2bfe commit 9a3fc28

File tree

3 files changed

+50
-1
lines changed

3 files changed

+50
-1
lines changed

src/compiler/scala/tools/nsc/transform/patmat/MatchTreeMaking.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -355,7 +355,7 @@ trait MatchTreeMaking extends MatchCodeGen with Debugging {
355355
// this also includes methods and (possibly nested) objects inside of methods.
356356
def definedInStaticLocation(tp: Type): Boolean = {
357357
def isStatic(tp: Type): Boolean =
358-
if (tp == NoType || tp.typeSymbol.isPackageClass || tp == NoPrefix) true
358+
if (tp == NoType || tp.typeSymbol.isPackageClass || tp == NoPrefix || nme.isReplWrapperName(tp.typeSymbol.name)) true
359359
else if (tp.typeSymbol.isModuleClass) isStatic(tp.prefix)
360360
else false
361361
tp.typeSymbol.owner == tp.prefix.typeSymbol && isStatic(tp.prefix)
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
2+
scala> sealed abstract class Value; object Value {
3+
final case class Num(value: Double) extends Value
4+
final case class Str(value: String) extends Value
5+
final case class Bool(value: Boolean) extends Value
6+
}
7+
defined class Value
8+
defined object Value
9+
10+
scala> class C { final case class Num(value: Double) } // here it should still warn
11+
warning: there was one unchecked warning; for details, enable `:setting -unchecked' or `:replay -unchecked'
12+
defined class C
13+
14+
scala> :quit
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
import scala.tools.nsc.Settings
2+
import scala.tools.partest.ReplTest
3+
4+
object Test extends ReplTest {
5+
override def transformSettings(s: Settings) = {
6+
s.Yreplclassbased.value = true
7+
s
8+
}
9+
10+
def code = """
11+
|sealed abstract class Value; object Value {
12+
| final case class Num(value: Double) extends Value
13+
| final case class Str(value: String) extends Value
14+
| final case class Bool(value: Boolean) extends Value
15+
|}
16+
|class C { final case class Num(value: Double) } // here it should still warn
17+
|""".stripMargin // scala/bug#11902
18+
}
19+
20+
/* was:
21+
22+
scala> sealed abstract class Value; object Value {
23+
final case class Num(value: Double) extends Value
24+
final case class Str(value: String) extends Value
25+
final case class Bool(value: Boolean) extends Value
26+
}
27+
warning: there were three unchecked warnings; for details, enable `:setting -unchecked' or `:replay -unchecked'
28+
defined class Value
29+
defined object Value
30+
31+
scala> class C { final case class Num(value: Double) } // here it should still warn
32+
warning: there was one unchecked warning; for details, enable `:setting -unchecked' or `:replay -unchecked'
33+
defined class C
34+
35+
*/

0 commit comments

Comments
 (0)