summaryrefslogtreecommitdiff
path: root/test
diff options
context:
space:
mode:
authorLukas Rytz <lukas.rytz@gmail.com>2015-02-09 19:33:20 +0100
committerLukas Rytz <lukas.rytz@gmail.com>2015-03-11 15:18:22 -0700
commita4e71b188fe8069b4de3a0753defb624b8b1eb8c (patch)
tree1db043db5e1a84568595413fc5c2ea77679ae0eb /test
parentf8bb3d5289e5eb84ccd94386e5c3df1bdf8b91bc (diff)
downloadscala-a4e71b188fe8069b4de3a0753defb624b8b1eb8c.tar.gz
scala-a4e71b188fe8069b4de3a0753defb624b8b1eb8c.tar.bz2
scala-a4e71b188fe8069b4de3a0753defb624b8b1eb8c.zip
Cast receiver if necessary when rewriting trait calls to impl method
The self parameter type may be incompatible with the trait type. trait T { self: S => def foo = 1 } The $self parameter type of T$class.foo is S, which may be unrelated to T. If we re-write a call to T.foo to T$class.foo, we need to cast the receiver to S, otherwise we get a VerifyError.
Diffstat (limited to 'test')
-rw-r--r--test/junit/scala/tools/nsc/backend/jvm/opt/CallGraphTest.scala1
-rw-r--r--test/junit/scala/tools/nsc/backend/jvm/opt/InlinerTest.scala25
2 files changed, 21 insertions, 5 deletions
diff --git a/test/junit/scala/tools/nsc/backend/jvm/opt/CallGraphTest.scala b/test/junit/scala/tools/nsc/backend/jvm/opt/CallGraphTest.scala
index 16f09db189..d7344ae61f 100644
--- a/test/junit/scala/tools/nsc/backend/jvm/opt/CallGraphTest.scala
+++ b/test/junit/scala/tools/nsc/backend/jvm/opt/CallGraphTest.scala
@@ -11,7 +11,6 @@ import org.junit.Assert._
import scala.tools.asm.tree._
import scala.tools.asm.tree.analysis._
-import scala.tools.nsc.backend.jvm.opt.BytecodeUtils.BasicAnalyzer
import scala.tools.testing.AssertUtil._
import CodeGenTools._
diff --git a/test/junit/scala/tools/nsc/backend/jvm/opt/InlinerTest.scala b/test/junit/scala/tools/nsc/backend/jvm/opt/InlinerTest.scala
index 694dff8dee..7f58f77b15 100644
--- a/test/junit/scala/tools/nsc/backend/jvm/opt/InlinerTest.scala
+++ b/test/junit/scala/tools/nsc/backend/jvm/opt/InlinerTest.scala
@@ -13,7 +13,7 @@ import org.junit.Assert._
import scala.tools.asm.tree._
import scala.tools.asm.tree.analysis._
-import scala.tools.nsc.backend.jvm.opt.BytecodeUtils.BasicAnalyzer
+import scala.tools.nsc.backend.jvm.opt.BytecodeUtils.AsmAnalyzer
import scala.tools.nsc.io._
import scala.tools.testing.AssertUtil._
@@ -84,7 +84,7 @@ class InlinerTest extends ClearAfterClass {
val List(f, g) = cls.methods.asScala.filter(m => Set("f", "g")(m.name)).toList.sortBy(_.name)
val fCall = g.instructions.iterator.asScala.collect({ case i: MethodInsnNode if i.name == "f" => i }).next()
- val analyzer = new BasicAnalyzer(g, clsBType.internalName)
+ val analyzer = new AsmAnalyzer(g, clsBType.internalName)
val r = inliner.inline(
fCall,
@@ -222,7 +222,7 @@ class InlinerTest extends ClearAfterClass {
case m: MethodInsnNode if m.name == "g" => m
}).next()
- val analyzer = new BasicAnalyzer(h, dTp.internalName)
+ val analyzer = new AsmAnalyzer(h, dTp.internalName)
val r = inliner.inline(
gCall,
@@ -374,7 +374,7 @@ class InlinerTest extends ClearAfterClass {
val f = c.methods.asScala.find(_.name == "f").get
val callsiteIns = f.instructions.iterator().asScala.collect({ case c: MethodInsnNode => c }).next()
val clsBType = classBTypeFromParsedClassfile(c.name).get
- val analyzer = new BasicAnalyzer(f, clsBType.internalName)
+ val analyzer = new AsmAnalyzer(f, clsBType.internalName)
val integerClassBType = classBTypeFromInternalName("java/lang/Integer")
val lowestOneBitMethod = byteCodeRepository.methodNode(integerClassBType.internalName, "lowestOneBit", "(I)I").get._1
@@ -720,4 +720,21 @@ class InlinerTest extends ClearAfterClass {
assertNoInvoke(getSingleMethod(d, "m"))
assertNoInvoke(getSingleMethod(c, "m"))
}
+
+ @Test
+ def inlineTraitCastReceiverToSelf(): Unit = {
+ val code =
+ """class C { def foo(x: Int) = x }
+ |trait T { self: C =>
+ | @inline final def f(x: Int) = foo(x)
+ | def t1 = f(1)
+ | def t2(t: T) = t.f(2)
+ |}
+ """.stripMargin
+ val List(c, t, tc) = compile(code)
+ val t1 = getSingleMethod(tc, "t1")
+ val t2 = getSingleMethod(tc, "t2")
+ val cast = TypeOp(CHECKCAST, "C")
+ Set(t1, t2).foreach(m => assert(m.instructions.contains(cast), m.instructions))
+ }
}