diff --git a/src/compiler/scala/tools/nsc/backend/jvm/BCodeBodyBuilder.scala b/src/compiler/scala/tools/nsc/backend/jvm/BCodeBodyBuilder.scala index 48ed602817b..77b2d186c30 100644 --- a/src/compiler/scala/tools/nsc/backend/jvm/BCodeBodyBuilder.scala +++ b/src/compiler/scala/tools/nsc/backend/jvm/BCodeBodyBuilder.scala @@ -381,7 +381,7 @@ abstract class BCodeBodyBuilder extends BCodeSkelBuilder { val sym = tree.symbol generatedType = symInfoTK(sym) val qualSafeToElide = treeInfo isQualifierSafeToElide qualifier - def genLoadQualUnlessElidable(): Unit = { if (!qualSafeToElide) { genLoadQualifier(tree) } } + def genLoadQualUnlessElidable(): Unit = { if (!qualSafeToElide) { genLoadQualifier(tree, drop = true) } } // receiverClass is used in the bytecode to access the field. using sym.owner may lead to IllegalAccessError, scala/bug#4283 def receiverClass = qualifier.tpe.typeSymbol if (sym.isModule) { @@ -1054,10 +1054,10 @@ abstract class BCodeBodyBuilder extends BCodeSkelBuilder { } /* Emit code to Load the qualifier of `tree` on top of the stack. */ - def genLoadQualifier(tree: Tree): Unit = { + def genLoadQualifier(tree: Tree, drop: Boolean = false): Unit = { lineNumber(tree) tree match { - case Select(qualifier, _) => genLoad(qualifier) + case Select(qualifier, _) => genLoad(qualifier, if (drop) UNIT else tpeTK(qualifier)) case _ => abort(s"Unknown qualifier $tree") } } diff --git a/test/files/run/staticQualifier.check b/test/files/run/staticQualifier.check new file mode 100644 index 00000000000..fe81901643b --- /dev/null +++ b/test/files/run/staticQualifier.check @@ -0,0 +1,3 @@ +42 +hai +42 diff --git a/test/files/run/staticQualifier/A_1.scala b/test/files/run/staticQualifier/A_1.scala new file mode 100644 index 00000000000..d056596542f --- /dev/null +++ b/test/files/run/staticQualifier/A_1.scala @@ -0,0 +1,21 @@ +import scala.language.experimental.macros +import scala.reflect.macros.blackbox.Context + +object A { + def foo(x: Int): Int = macro foo_impl + + def foo_impl(c: Context)(x: c.Expr[Int]): c.Tree = { + val g = c.universe.asInstanceOf[scala.tools.nsc.Global] + import g._ + import scala.tools.nsc.symtab.Flags._ + + val t = x.tree.asInstanceOf[Tree] match { + case s @ Select(_, n) if n.toString == "f2" => + val field = s.symbol.accessed + field.setFlag(STATIC).resetFlag(PRIVATE | LOCAL) + s.setSymbol(field) + } + + t.asInstanceOf[c.Tree] + } +} diff --git a/test/files/run/staticQualifier/Test_2.scala b/test/files/run/staticQualifier/Test_2.scala new file mode 100644 index 00000000000..bff989413cd --- /dev/null +++ b/test/files/run/staticQualifier/Test_2.scala @@ -0,0 +1,24 @@ +import scala.tools.partest.BytecodeTest +import scala.tools.testkit.ASMConverters._ +import scala.tools.asm.Opcodes._ + +object Test extends BytecodeTest { + val f2 = 42 + + def getT: Test.type = { + println("hai") + Test + } + + def show(): Unit = { + println(A.foo(Test.f2)) + println(A.foo(getT.f2)) + + val ins = instructionsFromMethod(getMethod(loadClassNode("Test$"), "show")) + val gs = ins.count { + case Field(GETSTATIC, "Test$", "f2", _) => true + case _ => false + } + assert(gs == 2) + } +}