Skip inline lambdas in 'InlineCallSite' parameter calculation; Fix for KT-10679: Wrong outer after inline
#KT-10679 Fixed
This commit is contained in:
@@ -23,10 +23,7 @@ import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.kotlin.backend.common.CodegenUtil;
|
||||
import org.jetbrains.kotlin.codegen.*;
|
||||
import org.jetbrains.kotlin.codegen.context.CodegenContext;
|
||||
import org.jetbrains.kotlin.codegen.context.FieldOwnerContext;
|
||||
import org.jetbrains.kotlin.codegen.context.MethodContext;
|
||||
import org.jetbrains.kotlin.codegen.context.PackageContext;
|
||||
import org.jetbrains.kotlin.codegen.context.*;
|
||||
import org.jetbrains.kotlin.codegen.state.GenerationState;
|
||||
import org.jetbrains.kotlin.codegen.state.JetTypeMapper;
|
||||
import org.jetbrains.kotlin.descriptors.*;
|
||||
@@ -307,8 +304,17 @@ public class InlineCodegen extends CallGenerator {
|
||||
}
|
||||
|
||||
private InlineCallSiteInfo getInlineCallSiteInfo() {
|
||||
MemberCodegen<?> parentCodegen = codegen.getParentCodegen();
|
||||
MethodContext context = codegen.getContext();
|
||||
MemberCodegen<?> parentCodegen = codegen.getParentCodegen();
|
||||
while (context instanceof InlineLambdaContext) {
|
||||
CodegenContext closureContext = context.getParentContext();
|
||||
assert closureContext instanceof ClosureContext : "Parent context of inline lambda should be closure context";
|
||||
assert closureContext.getParentContext() instanceof MethodContext : "Closure context should appear in method context";
|
||||
context = (MethodContext) closureContext.getParentContext();
|
||||
assert parentCodegen instanceof FakeMemberCodegen : "Parent codegen of inlined lambda should be FakeMemberCodegen";
|
||||
parentCodegen = ((FakeMemberCodegen) parentCodegen).delegate;
|
||||
}
|
||||
|
||||
JvmMethodSignature signature = typeMapper.mapSignature(context.getFunctionDescriptor(), context.getContextKind());
|
||||
return new InlineCallSiteInfo(parentCodegen.getClassName(), signature.getAsmMethod().getName(), signature.getAsmMethod().getDescriptor());
|
||||
}
|
||||
@@ -389,7 +395,7 @@ public class InlineCodegen extends CallGenerator {
|
||||
|
||||
private static class FakeMemberCodegen extends MemberCodegen {
|
||||
|
||||
private final MemberCodegen delegate;
|
||||
@NotNull final MemberCodegen delegate;
|
||||
@NotNull private final String className;
|
||||
|
||||
public FakeMemberCodegen(@NotNull MemberCodegen wrapped, @NotNull KtElement declaration, @NotNull FieldOwnerContext codegenContext, @NotNull String className) {
|
||||
|
||||
@@ -0,0 +1,15 @@
|
||||
import test.*
|
||||
|
||||
fun box(): String {
|
||||
val res = call {
|
||||
{ "OK" }
|
||||
}
|
||||
|
||||
var enclosingMethod = res.javaClass.enclosingMethod
|
||||
if (enclosingMethod?.name != "box") return "fail 1: ${enclosingMethod?.name}"
|
||||
|
||||
var enclosingClass = res.javaClass.enclosingClass
|
||||
if (enclosingClass?.name != "AnonymousInLambda_1Kt") return "fail 2: ${enclosingClass?.name}"
|
||||
|
||||
return res()
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
package test
|
||||
|
||||
inline fun <R> call(s: () -> R) = s()
|
||||
@@ -0,0 +1,27 @@
|
||||
import test.*
|
||||
|
||||
fun box(): String {
|
||||
val res = call {
|
||||
test { "OK" }
|
||||
}
|
||||
|
||||
var enclosingMethod = res.javaClass.enclosingMethod
|
||||
if (enclosingMethod?.name != "box") return "fail 1: ${enclosingMethod?.name}"
|
||||
|
||||
var enclosingClass = res.javaClass.enclosingClass
|
||||
if (enclosingClass?.name != "InlineChain_1Kt") return "fail 2: ${enclosingClass?.name}"
|
||||
|
||||
val res2 = call {
|
||||
call {
|
||||
test { "OK" }
|
||||
}
|
||||
}
|
||||
|
||||
enclosingMethod = res2.javaClass.enclosingMethod
|
||||
if (enclosingMethod?.name != "box") return "fail 1: ${enclosingMethod?.name}"
|
||||
|
||||
enclosingClass = res2.javaClass.enclosingClass
|
||||
if (enclosingClass?.name != "InlineChain_1Kt") return "fail 2: ${enclosingClass?.name}"
|
||||
|
||||
return res2()
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
package test
|
||||
|
||||
inline fun <R> call(s: () -> R) = s()
|
||||
|
||||
inline fun test(crossinline z: () -> String) = { z() }
|
||||
@@ -0,0 +1,27 @@
|
||||
import test.*
|
||||
|
||||
fun box(): String {
|
||||
val res = call {
|
||||
test { "OK" }
|
||||
}
|
||||
|
||||
var enclosingMethod = res.javaClass.enclosingMethod
|
||||
if (enclosingMethod?.name != "invoke") return "fail 1: ${enclosingMethod?.name}"
|
||||
|
||||
var enclosingClass = res.javaClass.enclosingClass
|
||||
if (enclosingClass?.name != "InlineChain2_1Kt\$box$\$inlined\$call$1") return "fail 2: ${enclosingClass?.name}"
|
||||
|
||||
val res2 = call {
|
||||
call {
|
||||
test { "OK" }
|
||||
}
|
||||
}
|
||||
|
||||
enclosingMethod = res2.javaClass.enclosingMethod
|
||||
if (enclosingMethod?.name != "invoke") return "fail 1: ${enclosingMethod?.name}"
|
||||
|
||||
enclosingClass = res2.javaClass.enclosingClass
|
||||
if (enclosingClass?.name != "InlineChain2_1Kt\$box$\$inlined\$call\$lambda\$lambda$2") return "fail 2: ${enclosingClass?.name}"
|
||||
|
||||
return res2()
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
package test
|
||||
|
||||
inline fun <R> call(crossinline s: () -> R) = { s() }()
|
||||
|
||||
inline fun test(crossinline z: () -> String) = { z() }
|
||||
+18
@@ -595,6 +595,24 @@ public class BlackBoxInlineCodegenTestGenerated extends AbstractBlackBoxInlineCo
|
||||
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/codegen/boxInline/enclosingInfo"), Pattern.compile("^(.+)\\.1.kt$"), true);
|
||||
}
|
||||
|
||||
@TestMetadata("anonymousInLambda.1.kt")
|
||||
public void testAnonymousInLambda() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/boxInline/enclosingInfo/anonymousInLambda.1.kt");
|
||||
doTestMultiFileWithInlineCheck(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("inlineChain.1.kt")
|
||||
public void testInlineChain() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/boxInline/enclosingInfo/inlineChain.1.kt");
|
||||
doTestMultiFileWithInlineCheck(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("inlineChain2.1.kt")
|
||||
public void testInlineChain2() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/boxInline/enclosingInfo/inlineChain2.1.kt");
|
||||
doTestMultiFileWithInlineCheck(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("objectInInlineFun.1.kt")
|
||||
public void testObjectInInlineFun() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/boxInline/enclosingInfo/objectInInlineFun.1.kt");
|
||||
|
||||
+18
@@ -595,6 +595,24 @@ public class CompileKotlinAgainstInlineKotlinTestGenerated extends AbstractCompi
|
||||
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/codegen/boxInline/enclosingInfo"), Pattern.compile("^(.+)\\.1.kt$"), true);
|
||||
}
|
||||
|
||||
@TestMetadata("anonymousInLambda.1.kt")
|
||||
public void testAnonymousInLambda() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/boxInline/enclosingInfo/anonymousInLambda.1.kt");
|
||||
doBoxTestWithInlineCheck(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("inlineChain.1.kt")
|
||||
public void testInlineChain() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/boxInline/enclosingInfo/inlineChain.1.kt");
|
||||
doBoxTestWithInlineCheck(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("inlineChain2.1.kt")
|
||||
public void testInlineChain2() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/boxInline/enclosingInfo/inlineChain2.1.kt");
|
||||
doBoxTestWithInlineCheck(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("objectInInlineFun.1.kt")
|
||||
public void testObjectInInlineFun() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/boxInline/enclosingInfo/objectInInlineFun.1.kt");
|
||||
|
||||
Reference in New Issue
Block a user