Skip to content

Commit 70041d2

Browse files
committed
Move @static immutable fields & methods to companion traits
The original code in addition adds the flag `Mutable` while moving, which does not respect Scala semantics.
1 parent 82cff1a commit 70041d2

File tree

5 files changed

+82
-6
lines changed

5 files changed

+82
-6
lines changed

compiler/src/dotty/tools/dotc/transform/MoveStatics.scala

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -24,12 +24,11 @@ class MoveStatics extends MiniPhase with SymTransformer {
2424
override def phaseName: String = MoveStatics.name
2525

2626
def transformSym(sym: SymDenotation)(implicit ctx: Context): SymDenotation = {
27-
if (sym.hasAnnotation(defn.ScalaStaticAnnot) && sym.owner.is(Flags.Module) &&
28-
sym.owner.companionClass.exists && !sym.owner.companionClass.is(Flags.Trait)) {
27+
if (sym.hasAnnotation(defn.ScalaStaticAnnot) && sym.owner.is(Flags.Module) && sym.owner.companionClass.exists &&
28+
(sym.is(Flags.Method) || !(sym.is(Flags.Mutable) && sym.owner.companionClass.is(Flags.Trait)))) {
2929
sym.owner.asClass.delete(sym.symbol)
3030
sym.owner.companionClass.asClass.enter(sym.symbol)
31-
val flags = if (sym.is(Flags.Method)) sym.flags else sym.flags | Flags.Mutable
32-
sym.copySymDenotation(owner = sym.owner.companionClass, initFlags = flags)
31+
sym.copySymDenotation(owner = sym.owner.companionClass)
3332
}
3433
else sym
3534
}
@@ -59,9 +58,8 @@ class MoveStatics extends MiniPhase with SymTransformer {
5958
}
6059

6160
def move(module: TypeDef, companion: TypeDef): List[Tree] = {
62-
assert(companion ne module)
61+
assert(companion != module)
6362
if (!module.symbol.is(Flags.Module)) move(companion, module)
64-
else if (companion != null && companion.symbol.is(Flags.Trait)) List(module, companion)
6563
else {
6664
val allMembers =
6765
(if(companion != null) {companion.rhs.asInstanceOf[Template].body} else Nil) ++

compiler/test/dotty/tools/backend/jvm/DottyBytecodeTest.scala

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,10 @@ trait DottyBytecodeTest {
7373
classNode.methods.asScala.find(_.name == name) getOrElse
7474
sys.error(s"Didn't find method '$name' in class '${classNode.name}'")
7575

76+
protected def getField(classNode: ClassNode, name: String): FieldNode =
77+
classNode.fields.asScala.find(_.name == name) getOrElse
78+
sys.error(s"Didn't find field '$name' in class '${classNode.name}'")
79+
7680
def diffInstructions(isa: List[Instruction], isb: List[Instruction]): String = {
7781
val len = Math.max(isa.length, isb.length)
7882
val sb = new StringBuilder

compiler/test/dotty/tools/backend/jvm/DottyBytecodeTests.scala

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -695,4 +695,50 @@ class TestBCode extends DottyBytecodeTest {
695695
"`test` was not properly generated\n" + diffInstructions(instructions, expected))
696696
}
697697
}
698+
699+
@Test def i5924b = {
700+
val source =
701+
"""|import scala.annotation.static
702+
|trait Base
703+
|
704+
|object Base {
705+
| @static val x = 10
706+
| @static final val y = 10
707+
| @static def f: Int = 30
708+
|}
709+
""".stripMargin
710+
711+
checkBCode(source) { dir =>
712+
val clsIn = dir.lookupName("Base.class", directory = false).input
713+
val clsNode = loadClassNode(clsIn)
714+
getMethod(clsNode, "f")
715+
getField(clsNode, "x")
716+
getField(clsNode, "y")
717+
}
718+
}
719+
720+
@Test def i5924c = {
721+
val source =
722+
"""|import scala.annotation.static
723+
|class Base
724+
|
725+
|object Base {
726+
| @static val x = 10
727+
| @static final val y = 10
728+
| @static var a = 10
729+
| @static final var b = 10
730+
| @static def f: Int = 30
731+
|}
732+
""".stripMargin
733+
734+
checkBCode(source) { dir =>
735+
val clsIn = dir.lookupName("Base.class", directory = false).input
736+
val clsNode = loadClassNode(clsIn)
737+
getMethod(clsNode, "f")
738+
getField(clsNode, "x")
739+
getField(clsNode, "y")
740+
getField(clsNode, "a")
741+
getField(clsNode, "b")
742+
}
743+
}
698744
}

tests/run/i5924b.scala

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
import scala.annotation.static
2+
3+
trait Base
4+
5+
object Base {
6+
@static val x = 10
7+
@static final val y = 10
8+
@static def f: Int = 30
9+
}
10+
11+
object Test {
12+
def main(args: Array[String]): Unit = Base
13+
}

tests/run/i5924c.scala

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
import scala.annotation.static
2+
3+
class Base
4+
5+
object Base {
6+
@static val x = 10
7+
@static final val y = 10
8+
@static var a = 10
9+
@static final var b = 10
10+
@static def f: Int = 30
11+
}
12+
13+
object Test {
14+
def main(args: Array[String]): Unit = Base
15+
}

0 commit comments

Comments
 (0)