Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[WIP] companion nest #10765

Draft
wants to merge 1 commit into
base: 2.13.x
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
1 change: 1 addition & 0 deletions src/compiler/scala/tools/nsc/Global.scala
Expand Up @@ -1181,6 +1181,7 @@ class Global(var currentSettings: Settings, reporter0: Reporter)
keepPhaseStack = settings.log.isSetByUser

val isScala3: Boolean = settings.isScala3: @nowarn
val isJDK11: Boolean = settings.releaseValue.map(_.toInt >= 11).getOrElse(false)

object sourceFeatures {
private val s = settings
Expand Down
Expand Up @@ -711,13 +711,14 @@ abstract class BCodeBodyBuilder extends BCodeSkelBuilder {
generatedType = genPrimitiveOp(app, expectedType)
} else { // normal method call
def isTraitSuperAccessorBodyCall = app.hasAttachment[UseInvokeSpecial.type]
def isPrivateSpecial = sym.isPrivate && (claszSymbol.info <:< sym.owner.info)
val invokeStyle =
if (sym.isStaticMember)
InvokeStyle.Static
else if (sym.isPrivate || sym.isClassConstructor) InvokeStyle.Special
else if (isTraitSuperAccessorBodyCall)
else if (isPrivateSpecial || sym.isClassConstructor || isTraitSuperAccessorBodyCall)
InvokeStyle.Special
else InvokeStyle.Virtual
else
InvokeStyle.Virtual

if (invokeStyle.hasInstance) genLoadQualifier(fun)
genLoadArguments(args, paramTKs(app))
Expand Down
12 changes: 12 additions & 0 deletions src/compiler/scala/tools/nsc/backend/jvm/BCodeSkelBuilder.scala
Expand Up @@ -197,6 +197,11 @@ abstract class BCodeSkelBuilder extends BCodeHelpers {
if (emitSource) {
cnode.visitSource(cunit.source.toString, null /* SourceDebugExtension */)
}
if (currentRun.isJDK11 && claszSymbol.isModuleClass) {
val linked = claszSymbol.linkedClassOfClass
if (linked.exists)
cnode.visitNestHost(internalName(linked))
}

enclosingMethodAttribute(claszSymbol, internalName, methodBTypeFromSymbol(_).descriptor) match {
case Some(EnclosingMethodEntry(className, methodName, methodDescriptor)) =>
Expand All @@ -208,6 +213,13 @@ abstract class BCodeSkelBuilder extends BCodeHelpers {
cnode.visitAttribute(if (ssa.isDefined) pickleMarkerLocal else pickleMarkerForeign)
emitAnnotations(cnode, claszSymbol.annotations ++ ssa)

if (currentRun.isJDK11 && !claszSymbol.isModuleClass) {
val companion = claszSymbol.companionModule
val linked = companion.moduleClass
if (linked.exists)
cnode.visitNestMember(internalName(linked))
}

if (isCZStaticModule || isCZParcelable) {

if (isCZStaticModule) { addModuleInstanceField() }
Expand Down
6 changes: 5 additions & 1 deletion src/compiler/scala/tools/nsc/transform/ExplicitOuter.scala
Expand Up @@ -434,6 +434,10 @@ abstract class ExplicitOuter extends InfoTransform
else atPos(tree.pos)(outerPath(outerValue, currentClass.outerClass, sym)) // (5)

case Select(qual, name) =>
def isNestable(c0: Symbol, c1: Symbol): Boolean = currentRun.isJDK11 && (
(if (c0.isModuleClass) c0.linkedClassOfClass == c1 else c1.isModuleClass && c1.linkedClassOfClass == c0)
|| c0.hasTransOwner(c1)
)
// make not private symbol accessed from inner classes, as well as
// symbols accessed from @inline methods
//
Expand All @@ -442,7 +446,7 @@ abstract class ExplicitOuter extends InfoTransform
def enclMethodIsInline = closestEnclMethod(currentOwner) hasAnnotation ScalaInlineClass
// scala/bug#8710 The extension method condition reflects our knowledge that a call to `new Meter(12).privateMethod`
// with later be rewritten (in erasure) to `Meter.privateMethod$extension(12)`.
if ((currentClass != sym.owner || enclMethodIsInline) && !sym.isMethodWithExtension)
if ((currentClass != sym.owner || enclMethodIsInline) && !sym.isMethodWithExtension && !isNestable(currentClass, sym.owner))
sym.makeNotPrivate(sym.owner)

val qsym = qual.tpe.widen.typeSymbol
Expand Down
15 changes: 15 additions & 0 deletions test/files/run/t6882.scala
@@ -0,0 +1,15 @@
//> using options --release:11

class C(private val i: Int, private val j: Int) {
private val c = i + C.secret

@inline def f = j * 2
}
object C {
def unwrap(c: C): Int = c.c

private def secret = 5
}
object Test extends App {
assert(C.unwrap(new C(42, 27)) == 47)
}