-
Notifications
You must be signed in to change notification settings - Fork 1.1k
Description
tested on both 3.0.0 and 3.0.1-RC2
originally reported by Scala book author @cayhorstmann at scala/scala-xml#541
Minimized code
class C1 {
private class C2
new C2 match {
case c: C2 =>
}
}
object Test extends App {
new C1
}Output
java.lang.NoSuchMethodError: C1$C2.C1$C2$$$outer()LC1;
at C1.<init>(S.scala:6)which occurs because C2 simply doesn't have an outer accessor method. C2s constructor accepts an outer reference, but doesn't do anything with it:
public C1$C2(C1);
descriptor: (LC1;)V
flags: ACC_PUBLIC
Code:
stack=1, locals=2, args_size=2
0: aload_0
1: invokespecial #14 // Method java/lang/Object."<init>":()V
4: return
Expectation
The runtime error occurs regardless of whether C2 is declared private[this] or merely private. It stops occurring if you declare C2 to be private[C1]. (Perhaps the private version fails because of the Scala 3 behavior where plain private sometimes means private[this] and sometimes means private[C1]?)
Ironically, Scala 2 does the reverse: for private[this] it gives C2 an outer accessor, but then the pattern match in C1's constructor does not call it...!
So, what would the correct behavior — keep the check and make it work, or omit it? I don't know offhand, especially once you start considering the nuances of the different access levels the inner class might have. But I see there is a lot of previous lore in this area: #2156, scala/bug#4440, scala/bug#1419, maybe others...?