diff --git a/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/diagnostic/compiler/based/DiagnosisCompilerTestFE10TestdataTestGenerated.java b/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/diagnostic/compiler/based/DiagnosisCompilerTestFE10TestdataTestGenerated.java index 1efc464e8c2..a9c863f1bd7 100644 --- a/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/diagnostic/compiler/based/DiagnosisCompilerTestFE10TestdataTestGenerated.java +++ b/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/diagnostic/compiler/based/DiagnosisCompilerTestFE10TestdataTestGenerated.java @@ -34617,6 +34617,12 @@ public class DiagnosisCompilerTestFE10TestdataTestGenerated extends AbstractDiag runTest("compiler/testData/diagnostics/testsWithStdLib/coroutines/nonModifierFormForBuiltInRenameOnImport.kt"); } + @Test + @TestMetadata("nonModifierFormForBuiltInWithFun.kt") + public void testNonModifierFormForBuiltInWithFun() throws Exception { + runTest("compiler/testData/diagnostics/testsWithStdLib/coroutines/nonModifierFormForBuiltInWithFun.kt"); + } + @Test @TestMetadata("operators.kt") public void testOperators() throws Exception { diff --git a/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirOldFrontendDiagnosticsTestGenerated.java b/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirOldFrontendDiagnosticsTestGenerated.java index 5474982f75d..769ba6edc9b 100644 --- a/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirOldFrontendDiagnosticsTestGenerated.java +++ b/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirOldFrontendDiagnosticsTestGenerated.java @@ -34617,6 +34617,12 @@ public class FirOldFrontendDiagnosticsTestGenerated extends AbstractFirDiagnosti runTest("compiler/testData/diagnostics/testsWithStdLib/coroutines/nonModifierFormForBuiltInRenameOnImport.kt"); } + @Test + @TestMetadata("nonModifierFormForBuiltInWithFun.kt") + public void testNonModifierFormForBuiltInWithFun() throws Exception { + runTest("compiler/testData/diagnostics/testsWithStdLib/coroutines/nonModifierFormForBuiltInWithFun.kt"); + } + @Test @TestMetadata("operators.kt") public void testOperators() throws Exception { diff --git a/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirOldFrontendDiagnosticsWithLightTreeTestGenerated.java b/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirOldFrontendDiagnosticsWithLightTreeTestGenerated.java index 031973c9035..e56aa15bf0b 100644 --- a/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirOldFrontendDiagnosticsWithLightTreeTestGenerated.java +++ b/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirOldFrontendDiagnosticsWithLightTreeTestGenerated.java @@ -34617,6 +34617,12 @@ public class FirOldFrontendDiagnosticsWithLightTreeTestGenerated extends Abstrac runTest("compiler/testData/diagnostics/testsWithStdLib/coroutines/nonModifierFormForBuiltInRenameOnImport.kt"); } + @Test + @TestMetadata("nonModifierFormForBuiltInWithFun.kt") + public void testNonModifierFormForBuiltInWithFun() throws Exception { + runTest("compiler/testData/diagnostics/testsWithStdLib/coroutines/nonModifierFormForBuiltInWithFun.kt"); + } + @Test @TestMetadata("operators.kt") public void testOperators() throws Exception { diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/checkers/LambdaWithSuspendModifierCallChecker.kt b/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/checkers/LambdaWithSuspendModifierCallChecker.kt index 4c9b625728f..4e0bf1fb0e0 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/checkers/LambdaWithSuspendModifierCallChecker.kt +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/checkers/LambdaWithSuspendModifierCallChecker.kt @@ -7,10 +7,7 @@ package org.jetbrains.kotlin.resolve.calls.checkers import com.intellij.psi.PsiElement import org.jetbrains.kotlin.diagnostics.Errors -import org.jetbrains.kotlin.psi.Call -import org.jetbrains.kotlin.psi.KtBinaryExpression -import org.jetbrains.kotlin.psi.KtLambdaExpression -import org.jetbrains.kotlin.psi.KtSimpleNameExpression +import org.jetbrains.kotlin.psi.* import org.jetbrains.kotlin.resolve.calls.util.isInfixCall import org.jetbrains.kotlin.resolve.calls.util.isCallableReference import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall @@ -31,22 +28,22 @@ object LambdaWithSuspendModifierCallChecker : CallChecker { when (descriptor.fqNameOrNull()) { KOTLIN_SUSPEND_BUILT_IN_FUNCTION_FQ_NAME -> { - if (calleeName != "suspend" || !call.hasFormOfSuspendModifierForLambda() || call.explicitReceiver != null) { + if (calleeName != "suspend" || !call.hasFormOfSuspendModifierForLambdaOrFun() || call.explicitReceiver != null) { context.trace.report(Errors.NON_MODIFIER_FORM_FOR_BUILT_IN_SUSPEND.on(reportOn)) } } else -> { - if ((calleeName == "suspend" || variableCalleeName == "suspend") && call.hasFormOfSuspendModifierForLambda()) { + if ((calleeName == "suspend" || variableCalleeName == "suspend") && call.hasFormOfSuspendModifierForLambdaOrFun()) { context.trace.report(Errors.MODIFIER_FORM_FOR_NON_BUILT_IN_SUSPEND.on(reportOn)) } } } } - private fun Call.hasFormOfSuspendModifierForLambda() = + private fun Call.hasFormOfSuspendModifierForLambdaOrFun() = !isCallableReference() && typeArguments.isEmpty() - && (hasNoArgumentListButDanglingLambdas() || isInfixWithRightLambda()) + && (hasNoArgumentListButDanglingLambdas() || isInfixWithRightLambdaOrFun()) private fun Call.referencedName() = calleeExpression?.safeAs()?.getReferencedName() @@ -54,7 +51,7 @@ object LambdaWithSuspendModifierCallChecker : CallChecker { private fun Call.hasNoArgumentListButDanglingLambdas() = valueArgumentList?.leftParenthesis == null && functionLiteralArguments.isNotEmpty() - private fun Call.isInfixWithRightLambda() = + private fun Call.isInfixWithRightLambdaOrFun() = isInfixCall(this) - && callElement.safeAs()?.right is KtLambdaExpression + && callElement.safeAs()?.right.let { it is KtLambdaExpression || it is KtNamedFunction } } diff --git a/compiler/testData/diagnostics/testsWithStdLib/coroutines/nonModifierFormForBuiltInWithFun.kt b/compiler/testData/diagnostics/testsWithStdLib/coroutines/nonModifierFormForBuiltInWithFun.kt new file mode 100644 index 00000000000..c37c7714e36 --- /dev/null +++ b/compiler/testData/diagnostics/testsWithStdLib/coroutines/nonModifierFormForBuiltInWithFun.kt @@ -0,0 +1,30 @@ +// FIR_IDENTICAL +// SKIP_TXT + +infix fun Int.suspend(c: () -> Unit) { c() } + +fun bar() { + 1 suspend fun() { + println() + } + + 1 @Ann suspend fun() { + println() + } + + 1 suspend @Ann fun() { + println() + } +} + +@Target(AnnotationTarget.EXPRESSION) +@Retention(AnnotationRetention.SOURCE) +annotation class Ann + +fun main(suspend: WLambdaInvoke) { + 1 suspend fun() {} +} + +class WLambdaInvoke { + operator fun Int.invoke(l: () -> Unit) {} +} diff --git a/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/DiagnosticTestGenerated.java b/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/DiagnosticTestGenerated.java index 0b042133368..ba60e33b315 100644 --- a/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/DiagnosticTestGenerated.java +++ b/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/DiagnosticTestGenerated.java @@ -34713,6 +34713,12 @@ public class DiagnosticTestGenerated extends AbstractDiagnosticTest { runTest("compiler/testData/diagnostics/testsWithStdLib/coroutines/nonModifierFormForBuiltInRenameOnImport.kt"); } + @Test + @TestMetadata("nonModifierFormForBuiltInWithFun.kt") + public void testNonModifierFormForBuiltInWithFun() throws Exception { + runTest("compiler/testData/diagnostics/testsWithStdLib/coroutines/nonModifierFormForBuiltInWithFun.kt"); + } + @Test @TestMetadata("operators.kt") public void testOperators() throws Exception {