Compiler internals question: for classfiles with a Scala signature, the classfile parser doesn’t actually parse the classfile content but just unpickles the signature (see here). When defining nested classes, only the top-level class gets a Scala signature, nested symbols are created from there. The classfiles for nested classes obtain a “Scala” marker attribute.
In the classfile parser, isScala
is a classfile with a Scala signature, isScalaRaw
is one with a marker attribute.
I’m wondering why we don’t skip over isScalaRaw
classfiles and unlink their symbols from the scope. Instead, the content of the classfile (parents, fields, methods) is parsed and symbols are created, like for a java-defined classfile.
In 2.11 you can do this
$ cat B.scala
class B { class C }
$ scalac11 B.scala
$ scala11
Welcome to Scala 2.11.8 (Java HotSpot(TM) 64-Bit Server VM, Java 1.8.0_112).
scala> val bc = new B$C(new B)
bc: B$C = B$C@6504e3b2
scala> val c: B#C = bc
<console>:12: error: type mismatch;
found : B$C
required: B#C
val c: B#C = bc
^
So there are two incompatible symbols for the same class.
In 2.12 an assertion in the backend fails.
scala> new B$C(new B)
java.lang.AssertionError: assertion failed: List(LB$C;)
I (very) vaguely remember that there’s a connection from this to the 2.11 optimizer (or specialization?), but I couldn’t find it so far – maybe it rings a bell for @dragos?
I observed that many specialized classfiles (Tuple2$mcZZ$sp
etc) are completed in this way during specialization (see here) - maybe we could save some cycles there.