diff options
author | Lukas Rytz <lukas.rytz@typesafe.com> | 2016-04-07 21:59:32 +0200 |
---|---|---|
committer | Lukas Rytz <lukas.rytz@typesafe.com> | 2016-04-07 21:59:32 +0200 |
commit | d6f66ec0f38e42c19f79cbe9d32d29c65dee1e05 (patch) | |
tree | 3a517ac17158c218b1e07f9c81e1af116da3df08 /test | |
parent | a326ef408084ed4aab860572d07222abe80b461d (diff) | |
parent | 17d97067a72b15c33a249dd201f3af452e3bb3ab (diff) | |
download | scala-d6f66ec0f38e42c19f79cbe9d32d29c65dee1e05.tar.gz scala-d6f66ec0f38e42c19f79cbe9d32d29c65dee1e05.tar.bz2 scala-d6f66ec0f38e42c19f79cbe9d32d29c65dee1e05.zip |
Merge pull request #5082 from lrytz/inlineImplClassCleanup
Cleanups related to the removal of trait impl classes
Diffstat (limited to 'test')
4 files changed, 91 insertions, 55 deletions
diff --git a/test/files/jvm/innerClassAttribute/Classes_1.scala b/test/files/jvm/innerClassAttribute/Classes_1.scala index 0abed140f1..bffc495b4f 100644 --- a/test/files/jvm/innerClassAttribute/Classes_1.scala +++ b/test/files/jvm/innerClassAttribute/Classes_1.scala @@ -186,7 +186,7 @@ trait A24 extends A24Base { } } -class SI_9105 { +class SI_9105 { // outerClass enclMeth val fun = (s: String) => { class A // SI_9105 null @@ -269,6 +269,23 @@ class SpecializedClassesAreTopLevel { // } } +object AnonymousClassesMayBeNestedInSpecialized { + abstract class A + class C[@specialized(Int) T] { + def foo(t: T): A = new A { } + } + + // specialization duplicates the anonymous class, one copy is nested in the specialized subclass of C + + // class C$mcI$sp extends C[Int] { + // override def foo(t: Int): A = C$mcI$sp.this.foo$mcI$sp(t); + // override def foo$mcI$sp(t: Int): A = { + // final class $anon extends A { } + // new <$anon: A>() + // } + // } +} + object NestedInValueClass { // note that we can only test anonymous functions, nested classes are not allowed inside value classes class A(val arg: String) extends AnyVal { diff --git a/test/files/jvm/innerClassAttribute/Test.scala b/test/files/jvm/innerClassAttribute/Test.scala index 1ac5a2dcf6..1b78773d42 100644 --- a/test/files/jvm/innerClassAttribute/Test.scala +++ b/test/files/jvm/innerClassAttribute/Test.scala @@ -414,6 +414,11 @@ object Test extends BytecodeTest { List("SpecializedClassesAreTopLevel$T$", "SpecializedClassesAreTopLevel$T$B$mcI$sp", "SpecializedClassesAreTopLevel$T$B").foreach(testInner(_, t, b)) } + def testAnonymousClassesMayBeNestedInSpecialized() { + assertEnclosingMethod("AnonymousClassesMayBeNestedInSpecialized$C$$anon$17", "AnonymousClassesMayBeNestedInSpecialized$C", "foo", "(Ljava/lang/Object;)LAnonymousClassesMayBeNestedInSpecialized$A;") + assertEnclosingMethod("AnonymousClassesMayBeNestedInSpecialized$C$mcI$sp$$anon$18", "AnonymousClassesMayBeNestedInSpecialized$C$mcI$sp", "foo$mcI$sp", "(I)LAnonymousClassesMayBeNestedInSpecialized$A;") + } + def testNestedInValueClass() { List( "NestedInValueClass", @@ -466,6 +471,7 @@ object Test extends BytecodeTest { testSI_9124() testImplClassesTopLevel() testSpecializedClassesTopLevel() + testAnonymousClassesMayBeNestedInSpecialized() testNestedInValueClass() } } diff --git a/test/junit/scala/tools/nsc/backend/jvm/opt/InlineWarningTest.scala b/test/junit/scala/tools/nsc/backend/jvm/opt/InlineWarningTest.scala index 01d97855c8..90236265e6 100644 --- a/test/junit/scala/tools/nsc/backend/jvm/opt/InlineWarningTest.scala +++ b/test/junit/scala/tools/nsc/backend/jvm/opt/InlineWarningTest.scala @@ -70,30 +70,6 @@ class InlineWarningTest extends ClearAfterClass { assert(count == 4, count) } - // TODO SD-86: no more impl classes. this test (and the warning it tests!) can be removed - @org.junit.Ignore @Test - def traitMissingImplClass(): Unit = { - val codeA = "trait T { @inline final def f = 1 }" - val codeB = "class C { def t1(t: T) = t.f }" - - val removeImpl = (outDir: AbstractFile) => { - val f = outDir.lookupName("T$class.class", directory = false) - if (f != null) f.delete() - } - - val warn = - """T::f()I is annotated @inline but cannot be inlined: the trait method call could not be rewritten to the static implementation method. Possible reason: - |The method f(LT;)I could not be found in the class T$class or any of its parents. - |Note that the following parent classes could not be found on the classpath: T$class""".stripMargin - - var c = 0 - compileSeparately(List(codeA, codeB), extraArgs = InlineWarningTest.args, afterEach = removeImpl, allowMessage = i => {c += 1; i.msg contains warn}) - assert(c == 1, c) - - // only summary here - compileSeparately(List(codeA, codeB), extraArgs = InlineWarningTest.argsNoWarn, afterEach = removeImpl, allowMessage = _.msg contains "there was one inliner warning") - } - @Test def handlerNonEmptyStack(): Unit = { val code = 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 10ab006017..4db2657c1b 100644 --- a/test/junit/scala/tools/nsc/backend/jvm/opt/ScalaInlineInfoTest.scala +++ b/test/junit/scala/tools/nsc/backend/jvm/opt/ScalaInlineInfoTest.scala @@ -29,12 +29,24 @@ class ScalaInlineInfoTest extends ClearAfterClass { def inlineInfo(c: ClassNode): InlineInfo = c.attrs.asScala.collect({ case a: InlineInfoAttribute => a.inlineInfo }).head + def mapDiff[A, B](a: Map[A, B], b: Map[A, B]) = { + val r = new StringBuilder + for ((a, av) <- a) { + if (!b.contains(a)) r.append(s"missing in b: $a\n") + else if (av != b(a)) r.append(s"different for $a: $av != ${b(a)}\n") + } + for (b <- b.keys.toList diff a.keys.toList) { + r.append(s"missing in a: $b\n") + } + r.toString + } + @Test def traitMembersInlineInfo(): Unit = { val code = """trait T { | def f1 = 1 // concrete method - | private def f2 = 1 // implOnly method (does not end up in the interface) + | private def f2 = 1 // default method only (not in subclass) | def f3 = { | def nest = 0 // nested method (does not end up in the interface) | nest @@ -44,13 +56,13 @@ class ScalaInlineInfoTest extends ClearAfterClass { | def f4 = super.toString // super accessor | | object O // module accessor (method is generated) - | def f5 = { + | final def f5 = { | object L { val x = 0 } // nested module (just flattened out) | L.x | } | | @noinline - | def f6: Int // abstract method (not in impl class) + | def f6: Int // abstract method | | // fields | @@ -61,40 +73,65 @@ class ScalaInlineInfoTest extends ClearAfterClass { | | final val x5 = 0 |} + |class C extends T { + | def f6 = 0 + | var x3 = 0 + |} """.stripMargin - val cs @ List(t, tl, to) = compileClasses(compiler)(code) - val info = inlineInfo(t) - val expect = InlineInfo ( - None, // self type + val cs @ List(c, t, tl, to) = compileClasses(compiler)(code) + val infoT = inlineInfo(t) + val expectT = InlineInfo ( false, // final class None, // not a sam Map( - // TODO SD-86: the module accessor used to be `effectivelyFinal` before nuke-impl-classes - ("O()LT$O$;", MethodInlineInfo(false,false,false,false)), - ("T$$super$toString()Ljava/lang/String;", MethodInlineInfo(false,false,false,false)), - ("T$_setter_$x1_$eq(I)V", MethodInlineInfo(false,false,false,false)), - ("f1()I", MethodInlineInfo(false,false,false,false)), - ("f3()I", MethodInlineInfo(false,false,false,false)), - ("f4()Ljava/lang/String;", MethodInlineInfo(false,false,true, false)), - ("f5()I", MethodInlineInfo(false,false,false,false)), - ("f6()I", MethodInlineInfo(false,false,false,true )), - ("x1()I", MethodInlineInfo(false,false,false,false)), - ("x3()I", MethodInlineInfo(false,false,false,false)), - ("x3_$eq(I)V", MethodInlineInfo(false,false,false,false)), - ("x4()I", MethodInlineInfo(false,false,false,false)), - ("x5()I", MethodInlineInfo(true, false,false,false)), - ("y2()I", MethodInlineInfo(false,false,false,false)), - ("y2_$eq(I)V", MethodInlineInfo(false,false,false,false)), - ("f2()I", MethodInlineInfo(true, false,false,false)), - ("L$lzycompute$1(Lscala/runtime/VolatileObjectRef;)LT$L$2$;",MethodInlineInfo(true, false,false,false)), - // TODO SD-86: should probably be effectivelyFinal - ("L$1(Lscala/runtime/VolatileObjectRef;)LT$L$2$;", MethodInlineInfo(false,false,false,false)), - ("nest$1()I", MethodInlineInfo(true, false,false,false)), - ("$init$()V", MethodInlineInfo(false,false,false,false))), + ("O()LT$O$;", MethodInlineInfo(true ,false,false)), // the accessor is abstract in bytecode, but still effectivelyFinal because there's no (late)DEFERRED flag, https://github.com/scala/scala-dev/issues/126 + ("T$$super$toString()Ljava/lang/String;", MethodInlineInfo(true ,false,false)), + ("T$_setter_$x1_$eq(I)V", MethodInlineInfo(false,false,false)), + ("f1()I", MethodInlineInfo(false,false,false)), + ("f2()I", MethodInlineInfo(true, false,false)), + ("f3()I", MethodInlineInfo(false,false,false)), + ("f4()Ljava/lang/String;", MethodInlineInfo(false,true, false)), + ("f5()I", MethodInlineInfo(true ,false,false)), + ("f6()I", MethodInlineInfo(false,false,true )), + ("x1()I", MethodInlineInfo(false,false,false)), + ("y2()I", MethodInlineInfo(false,false,false)), + ("y2_$eq(I)V", MethodInlineInfo(false,false,false)), + ("x3()I", MethodInlineInfo(false,false,false)), + ("x3_$eq(I)V", MethodInlineInfo(false,false,false)), + ("x4()I", MethodInlineInfo(false,false,false)), + ("x5()I", MethodInlineInfo(true, false,false)), + ("L$lzycompute$1(Lscala/runtime/VolatileObjectRef;)LT$L$2$;", MethodInlineInfo(true, false,false)), + ("L$1(Lscala/runtime/VolatileObjectRef;)LT$L$2$;", MethodInlineInfo(true ,false,false)), + ("nest$1()I", MethodInlineInfo(true, false,false)), + ("$init$()V", MethodInlineInfo(false,false,false))), None // warning ) - assert(info == expect, info) + + assert(infoT == expectT, mapDiff(expectT.methodInfos, infoT.methodInfos) + infoT) + + val infoC = inlineInfo(c) + val expectC = InlineInfo(false, None, Map( + "O()LT$O$;" -> MethodInlineInfo(true ,false,false), + "f1()I" -> MethodInlineInfo(false,false,false), + "f3()I" -> MethodInlineInfo(false,false,false), + "f4()Ljava/lang/String;" -> MethodInlineInfo(false,true ,false), + "f5()I" -> 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), + "y2()I" -> MethodInlineInfo(false,false,false), + "y2_$eq(I)V" -> MethodInlineInfo(false,false,false), + "x3()I" -> MethodInlineInfo(false,false,false), + "x3_$eq(I)V" -> MethodInlineInfo(false,false,false), + "x4$lzycompute()I" -> MethodInlineInfo(true ,false,false), + "x4()I" -> MethodInlineInfo(false,false,false), + "x5()I" -> MethodInlineInfo(true ,false,false), + "T$$super$toString()Ljava/lang/String;" -> MethodInlineInfo(true ,false,false), + "<init>()V" -> MethodInlineInfo(false,false,false)), + None) + + assert(infoC == expectC, mapDiff(expectC.methodInfos, infoC.methodInfos) + infoC) } @Test |