Targetting JEP-181 Nestmates (alt. to widening and name mangling)

Both Scala and Java differ from the JVM’s model of access control. A private member of a JVM class is only accessible to that class, but at the language level, a private member is accessible to enclosing or inner classes. In Scala, companion classes/objects also have mutual private access.

Scala additionally supports qualified private access that can extend across compilation units. Its package semantics differ from Java: a.b.c can see private[b] members, so this cannot be mapped to JVM package-private without introducing accessor methods.

Historically, Java emitted synthetic accessor methods or constructors to bridge this language vs VM mismatch. Scala took a different approach: because it also needs to handle cross-compilation-unit access, it emits such members as JVM public with mangled names.

Java 11 introduced nestmate-based access control (JEP 181). The relationship between inner and enclosing classes is made explicit via new classfile attributes, and the JVM uses this to treat a nest as the unit of private access.

With a baseline of JDK 11+, it seems worthwhile to take advantage of nestmate access control. This is designed for inner ↔ outer private access in Java, which previously relied on synthetic bridge methods.

Scala could use this to avoid manging/widening for non-qualified private members referenced by inner/enclosing classes, and by companion objects/classes.

It would not help with to qualified privates that extend beyond the compilation unit boundary.

Benefits:

A prototype suggests the implementation is relatively straightforward: Implement JEP 181 Nestmate attributes and support in ExpandPrivate by retronym · Pull Request #1 · retronym/dotty-1 · GitHub

10 Likes

I see this is tracked as Investigate JEP 181: Nest-Based Access Control · Issue #22292 · scala/scala3 · GitHub and explored in Companions and nested classes are nestmates by som-snytt · Pull Request #10765 · scala/scala · GitHub by @som-snytt

3 Likes