Skip to content

Commit 7d73d1f

Browse files
committed
Fix codegen for @static definitions
MoveStatics moves some of these definitions from the companion to the corresponding class, but does not update the trees referencing these definitions, so the qualifier type cannot be used as a receiver. I think we need to seriously rethink how we handle static methods in the compiler, but that would be a huge refactoring, so this commit just patches the backend to special case `@static` methods to use the method owner as receiver as was always done before this PR.
1 parent 0e27448 commit 7d73d1f

File tree

3 files changed

+9
-4
lines changed

3 files changed

+9
-4
lines changed

compiler/src/dotty/tools/backend/jvm/BCodeBodyBuilder.scala

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -439,8 +439,10 @@ trait BCodeBodyBuilder extends BCodeSkelBuilder {
439439
/*
440440
* must-single-thread
441441
*/
442-
private def fieldOp(field: Symbol, isLoad: Boolean, hostClass: Symbol): Unit = {
443-
val owner = internalName(if (hostClass == null) field.owner else hostClass)
442+
private def fieldOp(field: Symbol, isLoad: Boolean, specificReceiver: Symbol): Unit = {
443+
val useSpecificReceiver = specificReceiver != null && !field.isScalaStatic
444+
445+
val owner = internalName(if (useSpecificReceiver) specificReceiver else field.owner)
444446
val fieldJName = field.javaSimpleName.toString
445447
val fieldDescr = symInfoTK(field).descriptor
446448
val isStatic = field.isStaticMember
@@ -1143,7 +1145,7 @@ trait BCodeBodyBuilder extends BCodeSkelBuilder {
11431145
if (specificReceiver != null)
11441146
assert(style.isVirtual || specificReceiver == methodOwner, s"specificReceiver can only be specified for virtual calls. $method - $specificReceiver")
11451147

1146-
val useSpecificReceiver = specificReceiver != null && !specificReceiver.isBottomClass
1148+
val useSpecificReceiver = specificReceiver != null && !specificReceiver.isBottomClass && !method.isScalaStatic
11471149
val receiver = if (useSpecificReceiver) specificReceiver else methodOwner
11481150

11491151
// workaround for a JVM bug: https://bugs.openjdk.java.net/browse/JDK-8154587

compiler/src/dotty/tools/backend/jvm/BackendInterface.scala

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -491,6 +491,7 @@ abstract class BackendInterface extends BackendInterfaceDefinitions {
491491
def getsJavaPrivateFlag: Boolean
492492
def isFinal: Boolean
493493
def getsJavaFinalFlag: Boolean
494+
def isScalaStatic: Boolean
494495
def isStaticMember: Boolean
495496
def isBottomClass: Boolean
496497
def isBridge: Boolean

compiler/src/dotty/tools/backend/jvm/DottyBackendInterface.scala

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -678,8 +678,10 @@ class DottyBackendInterface(outputDirectory: AbstractFile, val superCallsMap: Ma
678678
isPrivate || (sym.isPrimaryConstructor && sym.owner.isTopLevelModuleClass)
679679

680680
def isFinal: Boolean = sym.is(Flags.Final)
681+
def isScalaStatic: Boolean =
682+
toDenot(sym).hasAnnotation(ctx.definitions.ScalaStaticAnnot)
681683
def isStaticMember: Boolean = (sym ne NoSymbol) &&
682-
(sym.is(Flags.JavaStatic) || toDenot(sym).hasAnnotation(ctx.definitions.ScalaStaticAnnot))
684+
(sym.is(Flags.JavaStatic) || isScalaStatic)
683685
// guard against no sumbol cause this code is executed to select which call type(static\dynamic) to use to call array.clone
684686

685687
def isBottomClass: Boolean = (sym eq defn.NullClass) || (sym eq defn.NothingClass)

0 commit comments

Comments
 (0)