// This isn't actually testing much, because no warning is emitted in versions // before the fix which comes with this because the method isn't even considered // for inlining due to the bug. class A { private var debug = false @inline private def ifelse[T](cond: => Boolean, ifPart: => T, elsePart: => T): T = if (cond) ifPart else elsePart final def bob1() = ifelse(debug, 1, 2) final def bob2() = if (debug) 1 else 2 } // Cool: // // % ls -1 /tmp/2901/ // A$$anonfun$bob1$1.class // A$$anonfun$bob1$2.class // A$$anonfun$bob1$3.class // A.class // % ls -1 /tmp/trunk // A.class // // Observations: // // (1) The inlined version accesses the field: the explicit one calls the accessor. // (2) The inlined version fails to eliminate boxing. With reference types it emits // an unneeded checkcast. // (3) The private var debug is mangled to A$$debug, but after inlining it is never accessed // from outside of the class and doesn't need mangling. // (4) We could forego emitting bytecode for ifelse entirely if it has been // inlined at all sites. // // Generated bytecode for the above: // // public final int bob1(); // Code: // Stack=1, Locals=1, Args_size=1 // 0: aload_0 // 1: getfield #11; //Field A$$debug:Z // 4: ifeq 14 // 7: iconst_1 // 8: invokestatic #41; //Method scala/runtime/BoxesRunTime.boxToInteger:(I)Ljava/lang/Integer; // 11: goto 18 // 14: iconst_2 // 15: invokestatic #41; //Method scala/runtime/BoxesRunTime.boxToInteger:(I)Ljava/lang/Integer; // 18: invokestatic #45; //Method scala/runtime/BoxesRunTime.unboxToInt:(Ljava/lang/Object;)I // 21: ireturn // // public final int bob2(); // Code: // Stack=1, Locals=1, Args_size=1 // 0: aload_0 // 1: invokevirtual #48; //Method A$$debug:()Z // 4: ifeq 11 // 7: iconst_1 // 8: goto 12 // 11: iconst_2 // 12: ireturn