Fix problem with missing handleResult call
At first we try to resolve 'handleResult' just as last expression in a lambda is first argument, then if results are unsuccessful try resolve 'handleResult' with fake Unit expression #KT-12969 Fixed
This commit is contained in:
@@ -72,21 +72,34 @@ fun FakeCallResolver.resolveCoroutineHandleResultCallIfNeeded(
|
|||||||
// should be Continuation<Nothing>
|
// should be Continuation<Nothing>
|
||||||
functionDescriptor.builtIns.nothingType)
|
functionDescriptor.builtIns.nothingType)
|
||||||
|
|
||||||
|
fun tryToResolveCall(firstArgument: KtExpression): Boolean {
|
||||||
|
val resolutionResults = resolveFakeCall(
|
||||||
|
context.replaceBindingTrace(temporaryBindingTrace), functionDescriptor.extensionReceiverParameter!!.value,
|
||||||
|
OperatorNameConventions.COROUTINE_HANDLE_RESULT, callElement, callElement, FakeCallKind.OTHER,
|
||||||
|
listOf(firstArgument, continuation))
|
||||||
|
|
||||||
|
if (resolutionResults.isSuccess && resolutionResults.resultingDescriptor.isOperator) {
|
||||||
|
context.trace.record(BindingContext.RETURN_HANDLE_RESULT_RESOLVED_CALL, callElement, resolutionResults.resultingCall)
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
val unitExpression = ExpressionTypingUtils.createFakeExpressionOfType(
|
||||||
|
callElement.project, temporaryBindingTrace, "unit", functionDescriptor.builtIns.unitType)
|
||||||
val firstArgument =
|
val firstArgument =
|
||||||
if (expressionToReturn == null || info != null && info.type != null && KotlinBuiltIns.isUnit(info.type))
|
if (expressionToReturn == null || info != null && info.type != null && KotlinBuiltIns.isUnit(info.type))
|
||||||
ExpressionTypingUtils.createFakeExpressionOfType(
|
unitExpression
|
||||||
callElement.project, temporaryBindingTrace, "unit", functionDescriptor.builtIns.unitType)
|
else
|
||||||
else expressionToReturn
|
expressionToReturn
|
||||||
|
|
||||||
val resolutionResults = resolveFakeCall(
|
if (!tryToResolveCall(firstArgument) && firstArgument === expressionToReturn) {
|
||||||
context.replaceBindingTrace(temporaryBindingTrace), functionDescriptor.extensionReceiverParameter!!.value,
|
tryToResolveCall(unitExpression)
|
||||||
OperatorNameConventions.COROUTINE_HANDLE_RESULT, callElement, callElement, FakeCallKind.OTHER,
|
|
||||||
listOf(firstArgument, continuation))
|
|
||||||
|
|
||||||
if (resolutionResults.isSuccess && resolutionResults.resultingDescriptor.isOperator) {
|
|
||||||
context.trace.record(BindingContext.RETURN_HANDLE_RESULT_RESOLVED_CALL, callElement, resolutionResults.resultingCall)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
fun KotlinType.isValidContinuation() =
|
fun KotlinType.isValidContinuation() =
|
||||||
(constructor.declarationDescriptor as? ClassDescriptor)?.fqNameUnsafe == DescriptorUtils.CONTINUATION_INTERFACE_FQ_NAME.toUnsafe()
|
(constructor.declarationDescriptor as? ClassDescriptor)?.fqNameUnsafe == DescriptorUtils.CONTINUATION_INTERFACE_FQ_NAME.toUnsafe()
|
||||||
|
|||||||
@@ -0,0 +1,28 @@
|
|||||||
|
class Controller {
|
||||||
|
var isCompleted = false
|
||||||
|
suspend fun suspendHere(x: Continuation<String>) {
|
||||||
|
x.resume("OK")
|
||||||
|
}
|
||||||
|
|
||||||
|
operator fun handleResult(x: Unit, y: Continuation<Nothing>) {
|
||||||
|
isCompleted = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun builder(coroutine c: Controller.() -> Continuation<Unit>) {
|
||||||
|
val controller = Controller()
|
||||||
|
c(controller).resume(Unit)
|
||||||
|
if (!controller.isCompleted) throw java.lang.RuntimeException("fail")
|
||||||
|
}
|
||||||
|
|
||||||
|
fun box(): String {
|
||||||
|
builder {
|
||||||
|
"OK"
|
||||||
|
}
|
||||||
|
|
||||||
|
builder {
|
||||||
|
suspendHere()
|
||||||
|
}
|
||||||
|
|
||||||
|
return "OK"
|
||||||
|
}
|
||||||
@@ -4189,6 +4189,12 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest {
|
|||||||
doTest(fileName);
|
doTest(fileName);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("handleResultNonUnitExpression.kt")
|
||||||
|
public void testHandleResultNonUnitExpression() throws Exception {
|
||||||
|
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/coroutines/handleResultNonUnitExpression.kt");
|
||||||
|
doTest(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("illegalState.kt")
|
@TestMetadata("illegalState.kt")
|
||||||
public void testIllegalState() throws Exception {
|
public void testIllegalState() throws Exception {
|
||||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/coroutines/illegalState.kt");
|
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/coroutines/illegalState.kt");
|
||||||
|
|||||||
Reference in New Issue
Block a user