Treat extension receiver as noinline parameter

#KT-9574 Fixed
This commit is contained in:
Denis Zharkov
2016-01-28 19:03:11 +03:00
parent 2cd88b8cbc
commit 505dc61611
20 changed files with 66 additions and 53 deletions
@@ -63,14 +63,6 @@ class InlineChecker implements CallChecker {
inlinableParameters.add(param);
}
}
//add extension receiver as inlinable
ReceiverParameterDescriptor receiverParameter = descriptor.getExtensionReceiverParameter();
if (receiverParameter != null) {
if (isInlinableParameter(receiverParameter)) {
inlinableParameters.add(receiverParameter);
}
}
}
@Override
@@ -117,12 +117,6 @@ public class InlineAnalyzerExtension implements FunctionAnalyzerExtension.Analyz
for (ValueParameterDescriptor parameter : parameters) {
hasInlinable |= checkInlinableParameter(parameter, function.getValueParameters().get(index++), functionDescriptor, trace);
}
ReceiverParameterDescriptor receiverParameter = functionDescriptor.getExtensionReceiverParameter();
if (receiverParameter != null) {
KtTypeReference receiver = function.getReceiverTypeReference();
assert receiver != null : "Descriptor has a receiver but psi doesn't " + function.getText();
hasInlinable |= checkInlinableParameter(receiverParameter, receiver, functionDescriptor, trace);
}
hasInlinable |= InlineUtil.containsReifiedTypeParameters(functionDescriptor);
@@ -0,0 +1,11 @@
//NO_CHECK_LAMBDA_INLINING
fun box(): String {
val res = { "OK" }.test()()
if (res != "OKOKOK") return "fail 1: $res"
val res2 = { "OK" }.extensionNoInline().subSequence(0, 2)
if (res2 != "OK") return "fail 2: $res2"
return "OK"
}
@@ -0,0 +1,4 @@
inline fun (() -> String).test(): (() -> String) = { invoke() + this.invoke() + this() }
// call this.hashCode() guarantees that extension receiver is noinline by default
inline fun (() -> String).extensionNoInline(): String = this() + (this.hashCode().toString())
+2 -2
View File
@@ -9,6 +9,6 @@ inline fun inlineFunWithInvoke(s: (p: Int) -> Unit, ext: Int.(p: Int) -> Unit) {
inline fun Function1<Int, Unit>.inlineExt() {
var d = <!USAGE_IS_NOT_INLINABLE!>this<!>
d = <!USAGE_IS_NOT_INLINABLE!>this<!>
var d = this
d = this
}
@@ -12,6 +12,6 @@ inline fun inlineFunWithInvokeNonInline(noinline s: (p: Int) -> Unit, ext: Int.(
inline fun Function1<Int, Unit>.inlineExt() {
invoke(11)
<!USAGE_IS_NOT_INLINABLE!>this<!> && <!USAGE_IS_NOT_INLINABLE!>this<!>
<!USAGE_IS_NOT_INLINABLE!>this<!> || <!USAGE_IS_NOT_INLINABLE!>this<!>
this && this
this || this
}
@@ -8,8 +8,8 @@ inline <!INAPPLICABLE_OPERATOR_MODIFIER!>operator<!> fun <T, U> Function1<T, U>.
}
inline operator fun <T, U> Function1<T, U>.plusAssign(p: Function1<T, U>) {
<!USAGE_IS_NOT_INLINABLE!>this<!> -= <!USAGE_IS_NOT_INLINABLE!>p<!>
<!USAGE_IS_NOT_INLINABLE!>p<!> -= <!USAGE_IS_NOT_INLINABLE!>this<!>
this -= <!USAGE_IS_NOT_INLINABLE!>p<!>
<!USAGE_IS_NOT_INLINABLE!>p<!> -= this
}
operator fun <T, U, V> @ExtensionFunctionType Function2<T, U, V>.minusAssign(ext : @ExtensionFunctionType Function2<T, U, V>) {}
@@ -20,8 +20,8 @@ inline <!INAPPLICABLE_OPERATOR_MODIFIER!>operator<!> fun <T, U, V> @ExtensionFun
}
inline operator fun <T, U, V> @ExtensionFunctionType Function2<T, U, V>.plusAssign(ext : @ExtensionFunctionType Function2<T, U, V>) {
<!USAGE_IS_NOT_INLINABLE!>this<!> -= <!USAGE_IS_NOT_INLINABLE!>ext<!>
<!USAGE_IS_NOT_INLINABLE!>ext<!> -= <!USAGE_IS_NOT_INLINABLE!>this<!>
this -= <!USAGE_IS_NOT_INLINABLE!>ext<!>
<!USAGE_IS_NOT_INLINABLE!>ext<!> -= this
}
inline fun <T, U, V> inlineFunWithInvoke(s: (p: T) -> U, ext: T.(p: U) -> V) {
@@ -8,11 +8,11 @@ operator fun <T, U, V> @ExtensionFunctionType Function2<T, U, V>.minus(p: T.(p:
}
inline operator fun <T, U> Function1<T, U>.plus(p: Function1<T, U>) {
<!USAGE_IS_NOT_INLINABLE!>this<!> - <!USAGE_IS_NOT_INLINABLE!>p<!>
this - <!USAGE_IS_NOT_INLINABLE!>p<!>
}
inline operator fun <T, U, V> @ExtensionFunctionType Function2<T, U, V>.plus(p: T.(p: U) -> V) {
<!USAGE_IS_NOT_INLINABLE!>this<!> - <!USAGE_IS_NOT_INLINABLE!>p<!>
this - <!USAGE_IS_NOT_INLINABLE!>p<!>
}
inline fun <T, U, V> inlineFunWithInvoke(s: (p: T) -> U, ext: T.(p: U) -> V) {
+4 -4
View File
@@ -4,10 +4,10 @@ infix fun Function1<Int, Unit>.noInlineExt(p: Int) {}
inline infix fun Function1<Int, Unit>.inlineExt2(p: Int) {
{
<!USAGE_IS_NOT_INLINABLE!>noInlineExt<!>(11)
<!USAGE_IS_NOT_INLINABLE!>this<!>.noInlineExt(11)
<!USAGE_IS_NOT_INLINABLE!>this<!> noInlineExt 11
<!USAGE_IS_NOT_INLINABLE!>this<!>
noInlineExt(11)
this.noInlineExt(11)
this noInlineExt 11
this
}()
}
@@ -3,10 +3,10 @@
infix fun Function1<Int, Unit>.noInlineExt(p: Int) {}
inline infix fun Function1<Int, Unit>.inlineExt2(p: Int) {
<!USAGE_IS_NOT_INLINABLE!>noInlineExt<!>(11)
<!USAGE_IS_NOT_INLINABLE!>this<!>.noInlineExt(11)
<!USAGE_IS_NOT_INLINABLE!>this<!> noInlineExt 11
<!USAGE_IS_NOT_INLINABLE!>this<!>
noInlineExt(11)
this.noInlineExt(11)
this noInlineExt 11
this
}
inline fun Function1<Int, Unit>.inlineExt() {
@@ -4,10 +4,10 @@ inline fun String.submit(action: Function1<Int, Int>) {
}
inline fun Function1<Int, Int>.submit() {
<!USAGE_IS_NOT_INLINABLE!>this<!>?.invoke(11)
<!USAGE_IS_NOT_INLINABLE!>this<!>!!.invoke(11)
this?.invoke(11)
this!!.invoke(11)
submit(<!USAGE_IS_NOT_INLINABLE!>this<!>!!)
submit(this!!)
}
inline fun submit(action: Function1<Int, Int>) {
@@ -1,6 +1,6 @@
// !DIAGNOSTICS: -UNUSED_EXPRESSION -UNUSED_PARAMETER -UNUSED_VARIABLE -CONFLICTING_JVM_DECLARATIONS
public inline fun <T> <!NULLABLE_INLINE_PARAMETER!>Function1<Int, Int>?<!>.submit(action: ()->T) {
public inline fun <T> Function1<Int, Int>?.submit(action: ()->T) {
this?.invoke(11)
}
@@ -12,7 +12,7 @@ public inline fun <T> submitNoInline(noinline action: Function1<Int, Int>?, s: (
action?.invoke(10)
}
public <!NOTHING_TO_INLINE!>inline<!> fun <T> <!NULLABLE_INLINE_PARAMETER!>Function1<Int, Int>?<!>.submit() {
public <!NOTHING_TO_INLINE!>inline<!> fun <T> Function1<Int, Int>?.submit() {
}
@@ -7,11 +7,11 @@ inline fun inlineFunWithInvoke(s: (p: Int) -> Unit) {
(<!USAGE_IS_NOT_INLINABLE, UNUSED_EXPRESSION!>s<!>)
}
inline fun Function1<Int, Unit>.inlineExt() {
<!NOTHING_TO_INLINE!>inline<!> fun Function1<Int, Unit>.inlineExt() {
(this).invoke(11)
(this) <!INFIX_MODIFIER_REQUIRED!>invoke<!> 11
(this)(11)
(<!USAGE_IS_NOT_INLINABLE, UNUSED_EXPRESSION!>this<!>)
(<!UNUSED_EXPRESSION!>this<!>)
}
inline fun inlineFunWithInvoke2(s: (p: Int) -> Unit) {
+1 -1
View File
@@ -24,7 +24,7 @@ inline fun inlineFunWithInvokeClosureNoinline(noinline s: (p: Int) -> Unit, noin
//ext function
inline fun Function1<Int, Unit>.inlineExt(ext: Int.(p: Int) -> Unit) {
subInline(this, ext)
subNoInline(<!USAGE_IS_NOT_INLINABLE!>this<!>, <!USAGE_IS_NOT_INLINABLE!>ext<!>)
subNoInline(this, <!USAGE_IS_NOT_INLINABLE!>ext<!>)
}
inline fun Function1<Int, Unit>.inlineExtWithClosure(ext: Int.(p: Int) -> Unit) {
+3 -3
View File
@@ -13,8 +13,8 @@ inline fun inlineFunWithExt2(ext: Int.(p: Int) -> Unit) : Int.(p: Int) -> Unit =
inline fun Function1<Int, Unit>.inlineExt(): Function1<Int, Unit> {
return <!USAGE_IS_NOT_INLINABLE!>this<!>
<!NOTHING_TO_INLINE!>inline<!> fun Function1<Int, Unit>.inlineExt(): Function1<Int, Unit> {
return this
}
inline fun Function1<Int, Unit>.inlineExt2(): Function1<Int, Unit> = <!USAGE_IS_NOT_INLINABLE!>this<!>
<!NOTHING_TO_INLINE!>inline<!> fun Function1<Int, Unit>.inlineExt2(): Function1<Int, Unit> = this
+2 -2
View File
@@ -44,14 +44,14 @@ inline fun inlineFunWithInvokeNonInline(noinline s: (p: Int) -> Unit, ext: Int.(
}
}
inline fun Function1<Int, Unit>.inlineExt() {
<!NOTHING_TO_INLINE!>inline<!> fun Function1<Int, Unit>.inlineExt() {
Test().test(){
invoke(11)
this.invoke(11)
this <!INFIX_MODIFIER_REQUIRED!>invoke<!> 11
this(11)
<!USAGE_IS_NOT_INLINABLE, UNUSED_EXPRESSION!>this<!>
<!UNUSED_EXPRESSION!>this<!>
11
}
@@ -1,13 +1,13 @@
// !DIAGNOSTICS: -UNUSED_EXPRESSION -UNUSED_PARAMETER -UNUSED_VARIABLE -NOTHING_TO_INLINE -ASSIGNED_BUT_NEVER_ACCESSED_VARIABLE -UNUSED_VALUE -VAL_REASSIGNMENT -UNUSED_CHANGED_VALUE -VARIABLE_EXPECTED
inline operator fun <T, V> Function1<T, V>.unaryPlus() = <!USAGE_IS_NOT_INLINABLE!>this<!>
inline operator fun <T, V> Function1<T, V>.unaryPlus() = this
operator fun <T, V> Function1<T, V>.unaryMinus() = this
inline operator fun <T, V> Function1<T, V>.inc() = <!USAGE_IS_NOT_INLINABLE!>this<!>
inline operator fun <T, V> Function1<T, V>.inc() = this
operator fun <T, V> Function1<T, V>.dec() = this
inline operator fun <T, V> @ExtensionFunctionType Function2<T, T, V>.unaryPlus(){}
operator fun <T, V> @ExtensionFunctionType Function2<T, T, V>.unaryMinus(){}
inline operator fun <T, V> @ExtensionFunctionType Function2<T, T, V>.inc() = <!USAGE_IS_NOT_INLINABLE!>this<!>
inline operator fun <T, V> @ExtensionFunctionType Function2<T, T, V>.inc() = this
operator fun <T, V> @ExtensionFunctionType Function2<T, T, V>.dec() = this
inline fun <T, V> inlineFunWithInvoke(s: (p: T) -> V, ext: T.(p: T) -> V) {
@@ -27,9 +27,9 @@ inline fun <T, V> inlineFunWithInvoke(s: (p: T) -> V, ext: T.(p: T) -> V) {
inline fun <T, V> Function1<T, V>.inlineFunWithInvoke() {
+this
-<!USAGE_IS_NOT_INLINABLE!>this<!>
-this
this++
++this
<!USAGE_IS_NOT_INLINABLE!>this<!>--
--<!USAGE_IS_NOT_INLINABLE!>this<!>
this--
--this
}
+2 -2
View File
@@ -6,8 +6,8 @@ inline fun inlineFun(s: (p: Int) -> Unit, noinline b: (p: Int) -> Unit) {
}
inline fun Function1<Int, Unit>.inlineExt(s: (p: Int) -> Unit, noinline b: (p: Int) -> Unit) {
subInline(<!USAGE_IS_NOT_INLINABLE!>this<!>, <!USAGE_IS_NOT_INLINABLE!>s<!>, b)
subNoInline(<!USAGE_IS_NOT_INLINABLE!>this<!>, <!USAGE_IS_NOT_INLINABLE!>s<!>, b)
subInline(this, <!USAGE_IS_NOT_INLINABLE!>s<!>, b)
subNoInline(this, <!USAGE_IS_NOT_INLINABLE!>s<!>, b)
}
@@ -823,6 +823,12 @@ public class BlackBoxInlineCodegenTestGenerated extends AbstractBlackBoxInlineCo
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/codegen/boxInline/noInline"), Pattern.compile("^(.+)\\.1.kt$"), true);
}
@TestMetadata("extensionReceiver.1.kt")
public void testExtensionReceiver() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/boxInline/noInline/extensionReceiver.1.kt");
doTestMultiFileWithInlineCheck(fileName);
}
@TestMetadata("lambdaAsGeneric.1.kt")
public void testLambdaAsGeneric() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/boxInline/noInline/lambdaAsGeneric.1.kt");
@@ -823,6 +823,12 @@ public class CompileKotlinAgainstInlineKotlinTestGenerated extends AbstractCompi
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/codegen/boxInline/noInline"), Pattern.compile("^(.+)\\.1.kt$"), true);
}
@TestMetadata("extensionReceiver.1.kt")
public void testExtensionReceiver() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/boxInline/noInline/extensionReceiver.1.kt");
doBoxTestWithInlineCheck(fileName);
}
@TestMetadata("lambdaAsGeneric.1.kt")
public void testLambdaAsGeneric() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/boxInline/noInline/lambdaAsGeneric.1.kt");