Use proper coroutine class descriptor for extension receiver generation
Before this commit context.getThisDescriptor() has been used, that was quite correct until suspension happens inside inlined lambda (it has different this-descriptor)
This commit is contained in:
@@ -2714,14 +2714,16 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
|
|||||||
private StackValue generateExtensionReceiver(@NotNull CallableDescriptor descriptor) {
|
private StackValue generateExtensionReceiver(@NotNull CallableDescriptor descriptor) {
|
||||||
KotlinType coroutineControllerType = CoroutineUtilKt.getControllerTypeIfCoroutine(descriptor);
|
KotlinType coroutineControllerType = CoroutineUtilKt.getControllerTypeIfCoroutine(descriptor);
|
||||||
if (coroutineControllerType != null) {
|
if (coroutineControllerType != null) {
|
||||||
ClassDescriptor thisDescriptor = context.getThisDescriptor();
|
ClassDescriptor classDescriptor = bindingContext.get(CodegenBinding.CLASS_FOR_CALLABLE, descriptor);
|
||||||
|
assert classDescriptor != null : "class descriptor for coroutine " + descriptor + " should not be null";
|
||||||
|
|
||||||
|
StackValue coroutineReceiver = StackValue.thisOrOuter(this, classDescriptor, /* isSuper =*/ false, /* castReceiver */ false);
|
||||||
return StackValue.field(
|
return StackValue.field(
|
||||||
FieldInfo.createForHiddenField(
|
FieldInfo.createForHiddenField(
|
||||||
typeMapper.mapClass(thisDescriptor),
|
typeMapper.mapClass(classDescriptor),
|
||||||
typeMapper.mapType(coroutineControllerType),
|
typeMapper.mapType(coroutineControllerType),
|
||||||
CoroutineCodegenUtilKt.COROUTINE_CONTROLLER_FIELD_NAME),
|
CoroutineCodegenUtilKt.COROUTINE_CONTROLLER_FIELD_NAME),
|
||||||
StackValue.thisOrOuter(this, thisDescriptor, /* isSuper =*/ false, /* castReceiver */ false));
|
coroutineReceiver);
|
||||||
}
|
}
|
||||||
|
|
||||||
return context.generateReceiver(descriptor, state, false);
|
return context.generateReceiver(descriptor, state, false);
|
||||||
|
|||||||
@@ -0,0 +1,31 @@
|
|||||||
|
class Controller {
|
||||||
|
suspend fun suspendHere(v: Int, x: Continuation<Int>) {
|
||||||
|
x.resume(v * 2)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun builder(coroutine c: Controller.() -> Continuation<Unit>) {
|
||||||
|
c(Controller()).resume(Unit)
|
||||||
|
}
|
||||||
|
|
||||||
|
inline fun foo(x: (Int) -> Unit) {
|
||||||
|
for (i in 1..2) {
|
||||||
|
x(i)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun box(): String {
|
||||||
|
var result = ""
|
||||||
|
|
||||||
|
builder {
|
||||||
|
result += "-"
|
||||||
|
foo {
|
||||||
|
result += suspendHere(it).toString()
|
||||||
|
}
|
||||||
|
result += "+"
|
||||||
|
}
|
||||||
|
|
||||||
|
if (result != "-24+") return "fail: $result"
|
||||||
|
|
||||||
|
return "OK"
|
||||||
|
}
|
||||||
@@ -4147,6 +4147,12 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest {
|
|||||||
doTest(fileName);
|
doTest(fileName);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("suspendFromInlineLambda.kt")
|
||||||
|
public void testSuspendFromInlineLambda() throws Exception {
|
||||||
|
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/coroutines/suspendFromInlineLambda.kt");
|
||||||
|
doTest(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("suspendInCycle.kt")
|
@TestMetadata("suspendInCycle.kt")
|
||||||
public void testSuspendInCycle() throws Exception {
|
public void testSuspendInCycle() throws Exception {
|
||||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/coroutines/suspendInCycle.kt");
|
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/coroutines/suspendInCycle.kt");
|
||||||
|
|||||||
Reference in New Issue
Block a user