JVM: Mark suspend lambda receiver as used if callable reference
accesses it. #KT-44131 Fixed
This commit is contained in:
+6
@@ -8562,6 +8562,12 @@ public class FirBlackBoxCodegenTestGenerated extends AbstractFirBlackBoxCodegenT
|
||||
runTest("compiler/testData/codegen/box/coroutines/featureIntersection/callableReference/fromJava.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("lambdaParameterUsed.kt")
|
||||
public void testLambdaParameterUsed() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/coroutines/featureIntersection/callableReference/lambdaParameterUsed.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("longArgs.kt")
|
||||
public void testLongArgs() throws Exception {
|
||||
|
||||
@@ -864,7 +864,9 @@ class ControlFlowInformationProvider private constructor(
|
||||
}
|
||||
|
||||
private fun markImplicitReceiverOfSuspendLambda(instruction: Instruction) {
|
||||
if (instruction !is MagicInstruction || instruction.kind != MagicKind.IMPLICIT_RECEIVER) return
|
||||
if (instruction !is MagicInstruction ||
|
||||
(instruction.kind != MagicKind.IMPLICIT_RECEIVER && instruction.kind != MagicKind.UNBOUND_CALLABLE_REFERENCE)
|
||||
) return
|
||||
|
||||
fun CallableDescriptor?.markIfNeeded() {
|
||||
if (this is AnonymousFunctionDescriptor && isSuspend) {
|
||||
@@ -872,31 +874,36 @@ class ControlFlowInformationProvider private constructor(
|
||||
}
|
||||
}
|
||||
|
||||
if (instruction.element is KtDestructuringDeclarationEntry || instruction.element is KtCallExpression) {
|
||||
val visited = mutableSetOf<Instruction>()
|
||||
fun dfs(insn: Instruction) {
|
||||
if (!visited.add(insn)) return
|
||||
if (insn is CallInstruction && insn.element == instruction.element) {
|
||||
for ((_, receiver) in insn.receiverValues) {
|
||||
(receiver as? ExtensionReceiver)?.declarationDescriptor?.apply { markIfNeeded() }
|
||||
when (val element = instruction.element) {
|
||||
is KtDestructuringDeclarationEntry, is KtCallExpression -> {
|
||||
val visited = mutableSetOf<Instruction>()
|
||||
fun dfs(insn: Instruction) {
|
||||
if (!visited.add(insn)) return
|
||||
if (insn is CallInstruction && insn.element == element) {
|
||||
for ((_, receiver) in insn.receiverValues) {
|
||||
(receiver as? ExtensionReceiver)?.declarationDescriptor?.apply { markIfNeeded() }
|
||||
}
|
||||
}
|
||||
for (next in insn.nextInstructions) {
|
||||
dfs(next)
|
||||
}
|
||||
}
|
||||
for (next in insn.nextInstructions) {
|
||||
dfs(next)
|
||||
}
|
||||
}
|
||||
|
||||
instruction.next?.let { dfs(it) }
|
||||
} else if (instruction.element is KtNameReferenceExpression || instruction.element is KtBinaryExpression ||
|
||||
instruction.element is KtUnaryExpression
|
||||
) {
|
||||
val call = instruction.element.getResolvedCall(trace.bindingContext)
|
||||
if (call is VariableAsFunctionResolvedCall) {
|
||||
(call.variableCall.dispatchReceiver as? ExtensionReceiver)?.declarationDescriptor?.apply { markIfNeeded() }
|
||||
(call.variableCall.extensionReceiver as? ExtensionReceiver)?.declarationDescriptor?.apply { markIfNeeded() }
|
||||
instruction.next?.let { dfs(it) }
|
||||
}
|
||||
is KtNameReferenceExpression, is KtBinaryExpression, is KtUnaryExpression -> {
|
||||
val call = element.getResolvedCall(trace.bindingContext)
|
||||
if (call is VariableAsFunctionResolvedCall) {
|
||||
(call.variableCall.dispatchReceiver as? ExtensionReceiver)?.declarationDescriptor?.apply { markIfNeeded() }
|
||||
(call.variableCall.extensionReceiver as? ExtensionReceiver)?.declarationDescriptor?.apply { markIfNeeded() }
|
||||
}
|
||||
(call?.dispatchReceiver as? ExtensionReceiver)?.declarationDescriptor?.apply { markIfNeeded() }
|
||||
(call?.extensionReceiver as? ExtensionReceiver)?.declarationDescriptor?.apply { markIfNeeded() }
|
||||
}
|
||||
is KtCallableReferenceExpression -> {
|
||||
val resolvedCall = element.callableReference.getResolvedCall(trace.bindingContext)
|
||||
(resolvedCall?.dispatchReceiver as? ExtensionReceiver)?.declarationDescriptor?.apply { markIfNeeded() }
|
||||
}
|
||||
(call?.dispatchReceiver as? ExtensionReceiver)?.declarationDescriptor?.apply { markIfNeeded() }
|
||||
(call?.extensionReceiver as? ExtensionReceiver)?.declarationDescriptor?.apply { markIfNeeded() }
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+20
@@ -0,0 +1,20 @@
|
||||
// WITH_RUNTIME
|
||||
// KJS_WITH_FULL_RUNTIME
|
||||
|
||||
import kotlin.coroutines.*
|
||||
|
||||
fun box(): String = a { (::write)() }
|
||||
|
||||
fun builder(c: suspend () -> Unit) {
|
||||
c.startCoroutine(Continuation(EmptyCoroutineContext) {})
|
||||
}
|
||||
|
||||
fun a(a: suspend Writer.() -> String): String {
|
||||
var res = ""
|
||||
builder { res = Writer().a() }
|
||||
return res
|
||||
}
|
||||
|
||||
class Writer {
|
||||
fun write(): String = "OK"
|
||||
}
|
||||
+6
@@ -8562,6 +8562,12 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest {
|
||||
runTest("compiler/testData/codegen/box/coroutines/featureIntersection/callableReference/fromJava.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("lambdaParameterUsed.kt")
|
||||
public void testLambdaParameterUsed() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/coroutines/featureIntersection/callableReference/lambdaParameterUsed.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("longArgs.kt")
|
||||
public void testLongArgs() throws Exception {
|
||||
|
||||
+6
@@ -8562,6 +8562,12 @@ public class IrBlackBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTes
|
||||
runTest("compiler/testData/codegen/box/coroutines/featureIntersection/callableReference/fromJava.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("lambdaParameterUsed.kt")
|
||||
public void testLambdaParameterUsed() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/coroutines/featureIntersection/callableReference/lambdaParameterUsed.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("longArgs.kt")
|
||||
public void testLongArgs() throws Exception {
|
||||
|
||||
+5
@@ -7461,6 +7461,11 @@ public class LightAnalysisModeTestGenerated extends AbstractLightAnalysisModeTes
|
||||
runTest("compiler/testData/codegen/box/coroutines/featureIntersection/callableReference/fromJava.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("lambdaParameterUsed.kt")
|
||||
public void testLambdaParameterUsed() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/coroutines/featureIntersection/callableReference/lambdaParameterUsed.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("longArgs.kt")
|
||||
public void testLongArgs() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/coroutines/featureIntersection/callableReference/longArgs.kt");
|
||||
|
||||
js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/es6/semantics/IrJsCodegenBoxES6TestGenerated.java
Generated
+5
@@ -6196,6 +6196,11 @@ public class IrJsCodegenBoxES6TestGenerated extends AbstractIrJsCodegenBoxES6Tes
|
||||
runTest("compiler/testData/codegen/box/coroutines/featureIntersection/callableReference/bigArity.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("lambdaParameterUsed.kt")
|
||||
public void testLambdaParameterUsed() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/coroutines/featureIntersection/callableReference/lambdaParameterUsed.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("longArgs.kt")
|
||||
public void testLongArgs() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/coroutines/featureIntersection/callableReference/longArgs.kt");
|
||||
|
||||
Generated
+5
@@ -6196,6 +6196,11 @@ public class IrJsCodegenBoxTestGenerated extends AbstractIrJsCodegenBoxTest {
|
||||
runTest("compiler/testData/codegen/box/coroutines/featureIntersection/callableReference/bigArity.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("lambdaParameterUsed.kt")
|
||||
public void testLambdaParameterUsed() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/coroutines/featureIntersection/callableReference/lambdaParameterUsed.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("longArgs.kt")
|
||||
public void testLongArgs() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/coroutines/featureIntersection/callableReference/longArgs.kt");
|
||||
|
||||
Generated
+5
@@ -6196,6 +6196,11 @@ public class JsCodegenBoxTestGenerated extends AbstractJsCodegenBoxTest {
|
||||
runTest("compiler/testData/codegen/box/coroutines/featureIntersection/callableReference/bigArity.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("lambdaParameterUsed.kt")
|
||||
public void testLambdaParameterUsed() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/coroutines/featureIntersection/callableReference/lambdaParameterUsed.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("longArgs.kt")
|
||||
public void testLongArgs() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/coroutines/featureIntersection/callableReference/longArgs.kt");
|
||||
|
||||
Reference in New Issue
Block a user