summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLukas Rytz <lukas.rytz@gmail.com>2016-04-13 12:21:23 +0200
committerLukas Rytz <lukas.rytz@gmail.com>2016-04-20 08:53:52 +0200
commitb61c35c38931be3b690bce92d5db9647802b1b34 (patch)
treead3250fe1c29f54e5aba317e98409308c419376f
parent3fca034c51dd159ff077fdde7e3146b1e41cc925 (diff)
downloadscala-b61c35c38931be3b690bce92d5db9647802b1b34.tar.gz
scala-b61c35c38931be3b690bce92d5db9647802b1b34.tar.bz2
scala-b61c35c38931be3b690bce92d5db9647802b1b34.zip
Ensure that lzycompute methods are entered into the scope
For some reason this was not the case, leading to spurious inliner warnings (no inline info found for method O$lzycompute).
-rw-r--r--src/compiler/scala/tools/nsc/transform/LazyVals.scala14
-rw-r--r--test/junit/scala/tools/nsc/backend/jvm/opt/ScalaInlineInfoTest.scala16
2 files changed, 22 insertions, 8 deletions
diff --git a/src/compiler/scala/tools/nsc/transform/LazyVals.scala b/src/compiler/scala/tools/nsc/transform/LazyVals.scala
index 8a0086dbdd..bc9f70679c 100644
--- a/src/compiler/scala/tools/nsc/transform/LazyVals.scala
+++ b/src/compiler/scala/tools/nsc/transform/LazyVals.scala
@@ -215,14 +215,16 @@ abstract class LazyVals extends Transform with TypingTransformers with ast.TreeD
def mkSlowPathDef(clazz: Symbol, lzyVal: Symbol, cond: Tree, syncBody: List[Tree],
stats: List[Tree], retVal: Tree): Tree = {
- // Q: is there a reason to first set owner to `clazz` (by using clazz.newMethod), and then
- // changing it to lzyVal.owner very soon after? Could we just do lzyVal.owner.newMethod?
- val defSym = clazz.newMethod(nme.newLazyValSlowComputeName(lzyVal.name.toTermName), lzyVal.pos, STABLE | PRIVATE)
+ val owner = lzyVal.owner
+ val defSym = owner.newMethod(nme.newLazyValSlowComputeName(lzyVal.name.toTermName), lzyVal.pos, STABLE | PRIVATE)
defSym setInfo MethodType(List(), lzyVal.tpe.resultType)
- defSym.owner = lzyVal.owner
+ if (owner.isClass) owner.info.decls.enter(defSym)
debuglog(s"crete slow compute path $defSym with owner ${defSym.owner} for lazy val $lzyVal")
- if (bitmaps.contains(lzyVal))
- bitmaps(lzyVal).map(_.owner = defSym)
+ // this is a hack i don't understand for lazy vals nested in a lazy val, introduced in 3769f4d,
+ // tested in pos/t3670 (add9be64). class A { val n = { lazy val b = { lazy val dd = 3; dd }; b } }
+ // bitmaps has an entry bMethodSym -> List(bitmap$0), where bitmap$0.owner == bMethodSym.
+ // now we set bitmap$0.owner = b$lzycomputeMethodSym.
+ for (bitmap <- bitmaps(lzyVal)) bitmap.owner = defSym
val rhs: Tree = gen.mkSynchronizedCheck(clazz, cond, syncBody, stats).changeOwner(currentOwner -> defSym)
DefDef(defSym, addBitmapDefs(lzyVal, BLOCK(rhs, retVal)))
diff --git a/test/junit/scala/tools/nsc/backend/jvm/opt/ScalaInlineInfoTest.scala b/test/junit/scala/tools/nsc/backend/jvm/opt/ScalaInlineInfoTest.scala
index 46b3ad3f8e..e2d03d8c62 100644
--- a/test/junit/scala/tools/nsc/backend/jvm/opt/ScalaInlineInfoTest.scala
+++ b/test/junit/scala/tools/nsc/backend/jvm/opt/ScalaInlineInfoTest.scala
@@ -24,8 +24,7 @@ object ScalaInlineInfoTest extends ClearAfterClass.Clearable {
@RunWith(classOf[JUnit4])
class ScalaInlineInfoTest extends ClearAfterClass {
ClearAfterClass.stateToClear = ScalaInlineInfoTest
-
- val compiler = newCompiler()
+ val compiler = ScalaInlineInfoTest.compiler
def inlineInfo(c: ClassNode): InlineInfo = c.attrs.asScala.collect({ case a: InlineInfoAttribute => a.inlineInfo }).head
@@ -113,6 +112,7 @@ class ScalaInlineInfoTest extends ClearAfterClass {
val infoC = inlineInfo(c)
val expectC = InlineInfo(false, None, Map(
"O()LT$O$;" -> MethodInlineInfo(true ,false,false),
+ "O$lzycompute()LT$O$;" -> MethodInlineInfo(true, false,false),
"f6()I" -> MethodInlineInfo(false,false,false),
"x1()I" -> MethodInlineInfo(false,false,false),
"T$_setter_$x1_$eq(I)V" -> MethodInlineInfo(false,false,false),
@@ -167,4 +167,16 @@ class ScalaInlineInfoTest extends ClearAfterClass {
("U",None)))
}
+
+ @Test
+ def lzyComputeInlineInfo(): Unit = {
+ val code = "class C { object O }"
+ val List(c, om) = compileClasses(compiler)(code)
+ val infoC = inlineInfo(c)
+ val expected = Map(
+ "<init>()V" -> MethodInlineInfo(false,false,false),
+ "O$lzycompute()LC$O$;" -> MethodInlineInfo(true,false,false),
+ "O()LC$O$;" -> MethodInlineInfo(true,false,false))
+ assert(infoC.methodInfos == expected, mapDiff(infoC.methodInfos, expected))
+ }
}