From b23e9f771b3b1af68dfb6c2cda6d38fc9d24f2bc Mon Sep 17 00:00:00 2001 From: Mikhail Zarechenskiy Date: Fri, 4 May 2018 16:21:17 +0300 Subject: [PATCH] [NI] Fix checking for the same instance inside for suspend functions --- .../calls/checkers/coroutineCallChecker.kt | 15 +++++++++++++-- .../inference/CoroutineInferenceSession.kt | 6 +++--- .../tower/KotlinToResolvedCallTransformer.kt | 3 +++ .../ifExpressionInsideCoroutine.kt | 18 ++++++++++++++++++ .../ir/IrBlackBoxCodegenTestGenerated.java | 12 ++++++++++++ .../codegen/BlackBoxCodegenTestGenerated.java | 12 ++++++++++++ .../LightAnalysisModeTestGenerated.java | 12 ++++++++++++ .../kotlin/resolve/inlineClassesUtils.kt | 2 -- .../semantics/JsCodegenBoxTestGenerated.java | 6 ++++++ 9 files changed, 79 insertions(+), 7 deletions(-) create mode 100644 compiler/testData/codegen/box/coroutines/suspendFunctionAsCoroutine/ifExpressionInsideCoroutine.kt diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/checkers/coroutineCallChecker.kt b/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/checkers/coroutineCallChecker.kt index 028d8beff2e..5c0a45ecb66 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/checkers/coroutineCallChecker.kt +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/checkers/coroutineCallChecker.kt @@ -23,6 +23,7 @@ import org.jetbrains.kotlin.psi.KtThisExpression import org.jetbrains.kotlin.resolve.BindingContext import org.jetbrains.kotlin.resolve.DescriptorUtils import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall +import org.jetbrains.kotlin.resolve.calls.tower.NewResolvedCallImpl import org.jetbrains.kotlin.resolve.descriptorUtil.fqNameSafe import org.jetbrains.kotlin.resolve.inline.InlineUtil import org.jetbrains.kotlin.resolve.scopes.HierarchicalScope @@ -156,9 +157,19 @@ private fun checkRestrictsSuspension( if (!enclosingSuspendReceiverValue.isRestrictsSuspensionReceiver()) return // member of suspend receiver - if (enclosingSuspendReceiverValue sameInstance resolvedCall.dispatchReceiver) return + val (dispatchReceiver, extensionReceiver) = if (context.languageVersionSettings.supportsFeature(LanguageFeature.NewInference)) { + require(resolvedCall is NewResolvedCallImpl<*>) { + "Resolved call with enabled new inference should be instance of NewResolvedCallImpl" + } - if (enclosingSuspendReceiverValue sameInstance resolvedCall.extensionReceiver && + resolvedCall.originalDispatchReceiver() to resolvedCall.originalExtensionReceiver() + } else { + resolvedCall.dispatchReceiver to resolvedCall.extensionReceiver + } + + if (enclosingSuspendReceiverValue sameInstance dispatchReceiver) return + + if (enclosingSuspendReceiverValue sameInstance extensionReceiver && resolvedCall.candidateDescriptor.extensionReceiverParameter!!.value.isRestrictsSuspensionReceiver()) return context.trace.report(Errors.ILLEGAL_RESTRICTED_SUSPENDING_FUNCTION_CALL.on(reportOn)) diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/inference/CoroutineInferenceSession.kt b/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/inference/CoroutineInferenceSession.kt index 369fb3685f1..41df4d850f3 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/inference/CoroutineInferenceSession.kt +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/inference/CoroutineInferenceSession.kt @@ -153,9 +153,6 @@ class CoroutineInferenceSession( val nonFixedTypesToResultSubstitutor = ComposedSubstitutor(commonSystemSubstitutor, nonFixedToVariablesSubstitutor) - val lambdaAtomCompleter = createResolvedAtomCompleter(nonFixedTypesToResultSubstitutor, topLevelCallContext) - lambdaAtomCompleter.completeAll(lambda) - for (completedCall in suspendCompletedCalls + normalCompletedCalls) { val resultCallAtom = completedCall.callResolutionResult.resultCallAtom val call = resultCallAtom.atom.getResolvedPsiKotlinCall(trace) ?: continue @@ -167,6 +164,9 @@ class CoroutineInferenceSession( completedCall.context, trace, resultCallAtom, resultingDescriptor, commonSystem.diagnostics ) } + + val lambdaAtomCompleter = createResolvedAtomCompleter(nonFixedTypesToResultSubstitutor, topLevelCallContext) + lambdaAtomCompleter.completeAll(lambda) } private fun updateCall( diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/tower/KotlinToResolvedCallTransformer.kt b/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/tower/KotlinToResolvedCallTransformer.kt index 743a7d3c229..f609a0943ec 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/tower/KotlinToResolvedCallTransformer.kt +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/tower/KotlinToResolvedCallTransformer.kt @@ -534,6 +534,9 @@ class NewResolvedCallImpl( override fun getSmartCastDispatchReceiverType(): KotlinType? = smartCastDispatchReceiverType + internal fun originalExtensionReceiver(): ReceiverValue? = resolvedCallAtom.extensionReceiverArgument?.receiver?.receiverValue + internal fun originalDispatchReceiver(): ReceiverValue? = resolvedCallAtom.dispatchReceiverArgument?.receiver?.receiverValue + fun updateExtensionReceiverWithSmartCastIfNeeded(smartCastExtensionReceiverType: KotlinType) { if (extensionReceiver is ImplicitClassReceiver) { extensionReceiver = CastImplicitClassReceiver( diff --git a/compiler/testData/codegen/box/coroutines/suspendFunctionAsCoroutine/ifExpressionInsideCoroutine.kt b/compiler/testData/codegen/box/coroutines/suspendFunctionAsCoroutine/ifExpressionInsideCoroutine.kt new file mode 100644 index 00000000000..4f937b1155a --- /dev/null +++ b/compiler/testData/codegen/box/coroutines/suspendFunctionAsCoroutine/ifExpressionInsideCoroutine.kt @@ -0,0 +1,18 @@ +// WITH_RUNTIME +// WITH_COROUTINES +// COMMON_COROUTINES_TEST +import helpers.* +import COROUTINES_PACKAGE.* +import COROUTINES_PACKAGE.intrinsics.* + +val f = run { + buildSequence { + if (true) { + yield("OK") + } + }.toList() +} + +fun box(): String { + return f[0] +} diff --git a/compiler/tests-ir-jvm/tests/org/jetbrains/kotlin/codegen/ir/IrBlackBoxCodegenTestGenerated.java b/compiler/tests-ir-jvm/tests/org/jetbrains/kotlin/codegen/ir/IrBlackBoxCodegenTestGenerated.java index 20e2af68005..a484c741d12 100644 --- a/compiler/tests-ir-jvm/tests/org/jetbrains/kotlin/codegen/ir/IrBlackBoxCodegenTestGenerated.java +++ b/compiler/tests-ir-jvm/tests/org/jetbrains/kotlin/codegen/ir/IrBlackBoxCodegenTestGenerated.java @@ -7091,6 +7091,18 @@ public class IrBlackBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTes doTestWithCoroutinesPackageReplacement(fileName, "kotlin.coroutines"); } + @TestMetadata("ifExpressionInsideCoroutine.kt") + public void testIfExpressionInsideCoroutine_1_2() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/coroutines/suspendFunctionAsCoroutine/ifExpressionInsideCoroutine.kt"); + doTestWithCoroutinesPackageReplacement(fileName, "kotlin.coroutines.experimental"); + } + + @TestMetadata("ifExpressionInsideCoroutine.kt") + public void testIfExpressionInsideCoroutine_1_3() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/coroutines/suspendFunctionAsCoroutine/ifExpressionInsideCoroutine.kt"); + doTestWithCoroutinesPackageReplacement(fileName, "kotlin.coroutines"); + } + @TestMetadata("inlineTwoReceivers.kt") public void testInlineTwoReceivers_1_2() throws Exception { String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/coroutines/suspendFunctionAsCoroutine/inlineTwoReceivers.kt"); diff --git a/compiler/tests/org/jetbrains/kotlin/codegen/BlackBoxCodegenTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/codegen/BlackBoxCodegenTestGenerated.java index a1fac31a1b8..c982762bb42 100644 --- a/compiler/tests/org/jetbrains/kotlin/codegen/BlackBoxCodegenTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/codegen/BlackBoxCodegenTestGenerated.java @@ -7091,6 +7091,18 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest { doTestWithCoroutinesPackageReplacement(fileName, "kotlin.coroutines"); } + @TestMetadata("ifExpressionInsideCoroutine.kt") + public void testIfExpressionInsideCoroutine_1_2() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/coroutines/suspendFunctionAsCoroutine/ifExpressionInsideCoroutine.kt"); + doTestWithCoroutinesPackageReplacement(fileName, "kotlin.coroutines.experimental"); + } + + @TestMetadata("ifExpressionInsideCoroutine.kt") + public void testIfExpressionInsideCoroutine_1_3() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/coroutines/suspendFunctionAsCoroutine/ifExpressionInsideCoroutine.kt"); + doTestWithCoroutinesPackageReplacement(fileName, "kotlin.coroutines"); + } + @TestMetadata("inlineTwoReceivers.kt") public void testInlineTwoReceivers_1_2() throws Exception { String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/coroutines/suspendFunctionAsCoroutine/inlineTwoReceivers.kt"); diff --git a/compiler/tests/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java index 563ba5809a8..adbfed29cea 100644 --- a/compiler/tests/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java @@ -7091,6 +7091,18 @@ public class LightAnalysisModeTestGenerated extends AbstractLightAnalysisModeTes doTestWithCoroutinesPackageReplacement(fileName, "kotlin.coroutines"); } + @TestMetadata("ifExpressionInsideCoroutine.kt") + public void testIfExpressionInsideCoroutine_1_2() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/coroutines/suspendFunctionAsCoroutine/ifExpressionInsideCoroutine.kt"); + doTestWithCoroutinesPackageReplacement(fileName, "kotlin.coroutines.experimental"); + } + + @TestMetadata("ifExpressionInsideCoroutine.kt") + public void testIfExpressionInsideCoroutine_1_3() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/coroutines/suspendFunctionAsCoroutine/ifExpressionInsideCoroutine.kt"); + doTestWithCoroutinesPackageReplacement(fileName, "kotlin.coroutines"); + } + @TestMetadata("inlineTwoReceivers.kt") public void testInlineTwoReceivers_1_2() throws Exception { String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/coroutines/suspendFunctionAsCoroutine/inlineTwoReceivers.kt"); diff --git a/core/descriptors/src/org/jetbrains/kotlin/resolve/inlineClassesUtils.kt b/core/descriptors/src/org/jetbrains/kotlin/resolve/inlineClassesUtils.kt index f0356494020..b87821a23b5 100644 --- a/core/descriptors/src/org/jetbrains/kotlin/resolve/inlineClassesUtils.kt +++ b/core/descriptors/src/org/jetbrains/kotlin/resolve/inlineClassesUtils.kt @@ -12,8 +12,6 @@ import org.jetbrains.kotlin.incremental.components.NoLookupLocation import org.jetbrains.kotlin.types.KotlinType import org.jetbrains.kotlin.types.TypeUtils import org.jetbrains.kotlin.utils.addToStdlib.safeAs -import java.lang.reflect.ParameterizedType -import kotlin.reflect.KFunction1 fun ClassDescriptor.underlyingRepresentation(): ValueParameterDescriptor? { if (!isInline) return null diff --git a/js/js.tests/test/org/jetbrains/kotlin/js/test/semantics/JsCodegenBoxTestGenerated.java b/js/js.tests/test/org/jetbrains/kotlin/js/test/semantics/JsCodegenBoxTestGenerated.java index 8e871ad5a86..cd228777799 100644 --- a/js/js.tests/test/org/jetbrains/kotlin/js/test/semantics/JsCodegenBoxTestGenerated.java +++ b/js/js.tests/test/org/jetbrains/kotlin/js/test/semantics/JsCodegenBoxTestGenerated.java @@ -5907,6 +5907,12 @@ public class JsCodegenBoxTestGenerated extends AbstractJsCodegenBoxTest { doTestWithCoroutinesPackageReplacement(fileName, "kotlin.coroutines.experimental"); } + @TestMetadata("ifExpressionInsideCoroutine.kt") + public void testIfExpressionInsideCoroutine_1_2() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/coroutines/suspendFunctionAsCoroutine/ifExpressionInsideCoroutine.kt"); + doTestWithCoroutinesPackageReplacement(fileName, "kotlin.coroutines.experimental"); + } + @TestMetadata("inlineTwoReceivers.kt") public void testInlineTwoReceivers_1_2() throws Exception { String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/coroutines/suspendFunctionAsCoroutine/inlineTwoReceivers.kt");