From f12409504ff27fc0634631e0ecb024bd2fde69ea Mon Sep 17 00:00:00 2001 From: Denis Zharkov Date: Thu, 12 Jan 2017 10:39:48 +0300 Subject: [PATCH] Prohibit callable references to suspend functions #KT-15662 Fixed --- .../DoubleColonExpressionResolver.kt | 14 ++++++++++ .../tests/coroutines/callableReferences.kt | 28 +++++++++++++++++++ .../tests/coroutines/callableReferences.txt | 14 ++++++++++ .../checkers/DiagnosticsTestGenerated.java | 6 ++++ 4 files changed, 62 insertions(+) create mode 100644 compiler/testData/diagnostics/tests/coroutines/callableReferences.kt create mode 100644 compiler/testData/diagnostics/tests/coroutines/callableReferences.txt diff --git a/compiler/frontend/src/org/jetbrains/kotlin/types/expressions/DoubleColonExpressionResolver.kt b/compiler/frontend/src/org/jetbrains/kotlin/types/expressions/DoubleColonExpressionResolver.kt index c1aabaa3432..24e3b9a0f0e 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/types/expressions/DoubleColonExpressionResolver.kt +++ b/compiler/frontend/src/org/jetbrains/kotlin/types/expressions/DoubleColonExpressionResolver.kt @@ -50,6 +50,7 @@ import org.jetbrains.kotlin.resolve.source.toSourceElement import org.jetbrains.kotlin.types.* import org.jetbrains.kotlin.types.TypeUtils.NO_EXPECTED_TYPE import org.jetbrains.kotlin.types.expressions.typeInfoFactory.createTypeInfo +import org.jetbrains.kotlin.utils.addToStdlib.safeAs import java.lang.UnsupportedOperationException import java.util.* import javax.inject.Inject @@ -574,9 +575,22 @@ class DoubleColonExpressionResolver( val resolutionResults = resolveCallableReferenceRHS(expression, lhsResult, context, resolveArgumentsMode) + reportUnsupportedReferenceToSuspendFunction(resolutionResults, expression, context) + return lhsResult to resolutionResults } + private fun reportUnsupportedReferenceToSuspendFunction( + resolutionResults: OverloadResolutionResults?, + expression: KtCallableReferenceExpression, + context: ExpressionTypingContext + ) { + if (resolutionResults?.isSingleResult == true && + resolutionResults.resultingDescriptor.safeAs()?.isSuspend == true) { + context.trace.report(UNSUPPORTED.on(expression.callableReference, "Callable references to suspend functions")) + } + } + private fun tryResolveRHSWithReceiver( traceTitle: String, receiver: Receiver?, diff --git a/compiler/testData/diagnostics/tests/coroutines/callableReferences.kt b/compiler/testData/diagnostics/tests/coroutines/callableReferences.kt new file mode 100644 index 00000000000..a41cee7d563 --- /dev/null +++ b/compiler/testData/diagnostics/tests/coroutines/callableReferences.kt @@ -0,0 +1,28 @@ +// !DIAGNOSTICS: -UNUSED_VARIABLE +suspend fun foo() {} + +class A { + suspend fun member() {} +} + +suspend fun A.ext() {} + +fun test1(a: A) { + val x = ::foo + + val y1 = a::member + val y2 = A::member + + val z1 = a::ext + val z2 = A::ext +} + +suspend fun test2(a: A) { + val x = ::foo + + val y1 = a::member + val y2 = A::member + + val z1 = a::ext + val z2 = A::ext +} diff --git a/compiler/testData/diagnostics/tests/coroutines/callableReferences.txt b/compiler/testData/diagnostics/tests/coroutines/callableReferences.txt new file mode 100644 index 00000000000..bbc546092f3 --- /dev/null +++ b/compiler/testData/diagnostics/tests/coroutines/callableReferences.txt @@ -0,0 +1,14 @@ +package + +public suspend fun foo(): kotlin.Unit +public fun test1(/*0*/ a: A): kotlin.Unit +public suspend fun test2(/*0*/ a: A): kotlin.Unit +public suspend fun A.ext(): kotlin.Unit + +public final class A { + public constructor A() + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int + public final suspend fun member(): kotlin.Unit + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String +} diff --git a/compiler/tests/org/jetbrains/kotlin/checkers/DiagnosticsTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/checkers/DiagnosticsTestGenerated.java index f65ee4e3c88..d1e6e5dfc66 100644 --- a/compiler/tests/org/jetbrains/kotlin/checkers/DiagnosticsTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/checkers/DiagnosticsTestGenerated.java @@ -4282,6 +4282,12 @@ public class DiagnosticsTestGenerated extends AbstractDiagnosticsTest { KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/diagnostics/tests/coroutines"), Pattern.compile("^(.+)\\.kt$"), TargetBackend.ANY, true); } + @TestMetadata("callableReferences.kt") + public void testCallableReferences() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/coroutines/callableReferences.kt"); + doTest(fileName); + } + @TestMetadata("coroutinesDisabled.kt") public void testCoroutinesDisabled() throws Exception { String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/coroutines/coroutinesDisabled.kt");