Skip to content

NoSuchMethodError when pattern matching on inner class (no outer accessor) #13096

Closed
@SethTisue

Description

@SethTisue

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...?

Metadata

Metadata

Type

No type

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions