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) {
|
||||
KotlinType coroutineControllerType = CoroutineUtilKt.getControllerTypeIfCoroutine(descriptor);
|
||||
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(
|
||||
FieldInfo.createForHiddenField(
|
||||
typeMapper.mapClass(thisDescriptor),
|
||||
FieldInfo.createForHiddenField(
|
||||
typeMapper.mapClass(classDescriptor),
|
||||
typeMapper.mapType(coroutineControllerType),
|
||||
CoroutineCodegenUtilKt.COROUTINE_CONTROLLER_FIELD_NAME),
|
||||
StackValue.thisOrOuter(this, thisDescriptor, /* isSuper =*/ false, /* castReceiver */ false));
|
||||
coroutineReceiver);
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
@TestMetadata("suspendFromInlineLambda.kt")
|
||||
public void testSuspendFromInlineLambda() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/coroutines/suspendFromInlineLambda.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("suspendInCycle.kt")
|
||||
public void testSuspendInCycle() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/coroutines/suspendInCycle.kt");
|
||||
|
||||
Reference in New Issue
Block a user