From 96186c621751e6b92d0817fadba5c81d7269ebaa Mon Sep 17 00:00:00 2001 From: Denis Zharkov Date: Thu, 29 Sep 2016 15:51:26 +0300 Subject: [PATCH] Prohibit star-projections in last parameter of suspend functions --- ChangeLog.md | 1 + .../jetbrains/kotlin/resolve/SuspendModifierChecker.kt | 9 +++++++-- .../diagnostics/tests/coroutines/suspendApplicability.kt | 6 +++++- .../tests/coroutines/suspendApplicability.txt | 3 ++- idea/testData/checker/infos/suspendApplicability.kt | 6 +++++- 5 files changed, 20 insertions(+), 5 deletions(-) diff --git a/ChangeLog.md b/ChangeLog.md index e85749059bb..ef2efc94365 100644 --- a/ChangeLog.md +++ b/ChangeLog.md @@ -35,6 +35,7 @@ - [`KT-13289`](https://youtrack.jetbrains.com/issue/KT-13289) Fix VerifyError with coroutines: Bad type on operand stack - [`KT-13409`](https://youtrack.jetbrains.com/issue/KT-13409) Fix generic variable spilling with coroutines - [`KT-13531`](https://youtrack.jetbrains.com/issue/KT-13531) Fix ClassCastException when coercion to Unit interacts with generic await() and coroutines +- Prohibit `Continuation<*>` as a last parameter of suspend functions #### Typealises related issues - [`KT-13200`](https://youtrack.jetbrains.com/issue/KT-13200) Fix incorrect number of required type arguments reported on typealias diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/SuspendModifierChecker.kt b/compiler/frontend/src/org/jetbrains/kotlin/resolve/SuspendModifierChecker.kt index 6dd790dd63b..1dd7bc6e243 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/SuspendModifierChecker.kt +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/SuspendModifierChecker.kt @@ -46,7 +46,7 @@ object SuspendModifierChecker : SimpleDeclarationChecker { val functionDescriptor = descriptor as? FunctionDescriptor ?: return if (!functionDescriptor.isSuspend) return - val suspendModifierElement = declaration.modifierList?.getModifier(KtTokens.SUSPEND_KEYWORD).sure { "${declaration.text}" } + val suspendModifierElement = declaration.modifierList?.getModifier(KtTokens.SUSPEND_KEYWORD).sure { declaration.text } fun report(message: String) { diagnosticHolder.report(Errors.INAPPLICABLE_MODIFIER.on(suspendModifierElement, KtTokens.SUSPEND_KEYWORD, message)) } @@ -70,11 +70,16 @@ object SuspendModifierChecker : SimpleDeclarationChecker { } } - val isValidContinuation = functionDescriptor.valueParameters.lastOrNull()?.type?.isValidContinuation() ?: false + val continuationParameterType = functionDescriptor.valueParameters.lastOrNull()?.type + val isValidContinuation = continuationParameterType?.isValidContinuation() ?: false if (!isValidContinuation) { report("last parameter of suspend function should have a type of Continuation") return } + + if (continuationParameterType?.arguments?.firstOrNull()?.isStarProjection == true) { + report("Continuation<*> is prohibited as a last parameter of suspend function") + } } } diff --git a/compiler/testData/diagnostics/tests/coroutines/suspendApplicability.kt b/compiler/testData/diagnostics/tests/coroutines/suspendApplicability.kt index 310fc6a7d8f..45d81fb151b 100644 --- a/compiler/testData/diagnostics/tests/coroutines/suspendApplicability.kt +++ b/compiler/testData/diagnostics/tests/coroutines/suspendApplicability.kt @@ -27,7 +27,11 @@ class Controller { } - suspend fun starProjection(vararg x: Continuation) { + suspend fun starProjection(x: Continuation<*>) { + + } + + suspend fun varargs(vararg x: Continuation) { } diff --git a/compiler/testData/diagnostics/tests/coroutines/suspendApplicability.txt b/compiler/testData/diagnostics/tests/coroutines/suspendApplicability.txt index 428a0dcdbe9..69b97159f46 100644 --- a/compiler/testData/diagnostics/tests/coroutines/suspendApplicability.txt +++ b/compiler/testData/diagnostics/tests/coroutines/suspendApplicability.txt @@ -10,9 +10,10 @@ public suspend fun kotlin.String.wrongExtension(/*0*/ x: kotlin.coroutines.Conti public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int public final inline suspend fun inlineFun(/*0*/ x: kotlin.coroutines.Continuation): kotlin.Unit public final suspend fun noParams(): kotlin.Unit - public final suspend fun starProjection(/*0*/ vararg x: kotlin.coroutines.Continuation /*kotlin.Array>*/): kotlin.Unit + public final suspend fun starProjection(/*0*/ x: kotlin.coroutines.Continuation<*>): kotlin.Unit public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String public final suspend fun valid(/*0*/ x: kotlin.coroutines.Continuation): kotlin.Unit + public final suspend fun varargs(/*0*/ vararg x: kotlin.coroutines.Continuation /*kotlin.Array>*/): kotlin.Unit public final suspend fun wrongParam(/*0*/ x: kotlin.collections.Collection): kotlin.Unit public final suspend fun kotlin.String.memberExtension(/*0*/ x: kotlin.coroutines.Continuation): kotlin.Unit } diff --git a/idea/testData/checker/infos/suspendApplicability.kt b/idea/testData/checker/infos/suspendApplicability.kt index 029a8c7d762..232fae1fe61 100644 --- a/idea/testData/checker/infos/suspendApplicability.kt +++ b/idea/testData/checker/infos/suspendApplicability.kt @@ -27,7 +27,11 @@ class Controller { } - suspend fun starProjection(vararg x: Continuation) { + suspend fun starProjection(x: Continuation<*>) { + + } + + suspend fun varargs(vararg x: Continuation) { }