[FIR] Prohibit suspend anonymous functions in statement position
^KT-62018 Fixed ^KT-62019
This commit is contained in:
committed by
Space Team
parent
cae6e0ee0f
commit
fb00c1dfb6
+6
@@ -1691,6 +1691,12 @@ internal val KT_DIAGNOSTIC_CONVERTER = KtDiagnosticConverterBuilder.buildConvert
|
||||
token,
|
||||
)
|
||||
}
|
||||
add(FirErrors.ANONYMOUS_SUSPEND_FUNCTION) { firDiagnostic ->
|
||||
AnonymousSuspendFunctionImpl(
|
||||
firDiagnostic as KtPsiDiagnostic,
|
||||
token,
|
||||
)
|
||||
}
|
||||
add(FirErrors.VALUE_CLASS_NOT_TOP_LEVEL) { firDiagnostic ->
|
||||
ValueClassNotTopLevelImpl(
|
||||
firDiagnostic as KtPsiDiagnostic,
|
||||
|
||||
+4
@@ -1220,6 +1220,10 @@ sealed interface KtFirDiagnostic<PSI : PsiElement> : KtDiagnosticWithPsi<PSI> {
|
||||
override val diagnosticClass get() = NoExplicitReturnTypeInApiModeWarning::class
|
||||
}
|
||||
|
||||
interface AnonymousSuspendFunction : KtFirDiagnostic<KtDeclaration> {
|
||||
override val diagnosticClass get() = AnonymousSuspendFunction::class
|
||||
}
|
||||
|
||||
interface ValueClassNotTopLevel : KtFirDiagnostic<KtDeclaration> {
|
||||
override val diagnosticClass get() = ValueClassNotTopLevel::class
|
||||
}
|
||||
|
||||
+5
@@ -1460,6 +1460,11 @@ internal class NoExplicitReturnTypeInApiModeWarningImpl(
|
||||
token: KtLifetimeToken,
|
||||
) : KtAbstractFirDiagnostic<KtDeclaration>(firDiagnostic, token), KtFirDiagnostic.NoExplicitReturnTypeInApiModeWarning
|
||||
|
||||
internal class AnonymousSuspendFunctionImpl(
|
||||
firDiagnostic: KtPsiDiagnostic,
|
||||
token: KtLifetimeToken,
|
||||
) : KtAbstractFirDiagnostic<KtDeclaration>(firDiagnostic, token), KtFirDiagnostic.AnonymousSuspendFunction
|
||||
|
||||
internal class ValueClassNotTopLevelImpl(
|
||||
firDiagnostic: KtPsiDiagnostic,
|
||||
token: KtLifetimeToken,
|
||||
|
||||
+6
@@ -2027,6 +2027,12 @@ public class DiagnosticCompilerTestFirTestdataTestGenerated extends AbstractDiag
|
||||
runTest("compiler/fir/analysis-tests/testData/resolve/diagnostics/supertypeInitializedWithoutPrimaryConstructor.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("suspendAnonymousFunction.kt")
|
||||
public void testSuspendAnonymousFunction() throws Exception {
|
||||
runTest("compiler/fir/analysis-tests/testData/resolve/diagnostics/suspendAnonymousFunction.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("testIllegalAnnotationClass.kt")
|
||||
public void testTestIllegalAnnotationClass() throws Exception {
|
||||
|
||||
+6
@@ -2027,6 +2027,12 @@ public class LLFirPreresolvedReversedDiagnosticCompilerFirTestDataTestGenerated
|
||||
runTest("compiler/fir/analysis-tests/testData/resolve/diagnostics/supertypeInitializedWithoutPrimaryConstructor.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("suspendAnonymousFunction.kt")
|
||||
public void testSuspendAnonymousFunction() throws Exception {
|
||||
runTest("compiler/fir/analysis-tests/testData/resolve/diagnostics/suspendAnonymousFunction.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("testIllegalAnnotationClass.kt")
|
||||
public void testTestIllegalAnnotationClass() throws Exception {
|
||||
|
||||
+13
@@ -0,0 +1,13 @@
|
||||
FILE: suspendAnonymousFunction.kt
|
||||
public final fun take(f: R|suspend () -> kotlin/Unit|): R|kotlin/Unit| {
|
||||
}
|
||||
public final fun test_1(): R|kotlin/Unit| {
|
||||
suspend fun <anonymous>(): R|kotlin/Unit| <inline=Unknown> {
|
||||
}
|
||||
|
||||
}
|
||||
public final fun test_2(): R|kotlin/Unit| {
|
||||
R|/take<Inapplicable(INAPPLICABLE_ARGUMENTS_MAPPING_ERROR): /take>#|(<Unresolved name: suspend>#, fun <anonymous>(): R|kotlin/Unit| <inline=Unknown> {
|
||||
}
|
||||
)
|
||||
}
|
||||
+11
@@ -0,0 +1,11 @@
|
||||
// ISSUE: KT-62018, KT-62019
|
||||
|
||||
fun take(f: suspend () -> Unit) {}
|
||||
|
||||
fun test_1() {
|
||||
<!ANONYMOUS_SUSPEND_FUNCTION!>suspend<!> fun() {}
|
||||
}
|
||||
|
||||
fun test_2() {
|
||||
take(<!UNRESOLVED_REFERENCE!>suspend<!><!SYNTAX!><!> <!TOO_MANY_ARGUMENTS!>fun () {}<!>)
|
||||
}
|
||||
+6
@@ -2027,6 +2027,12 @@ public class FirLightTreeDiagnosticsTestGenerated extends AbstractFirLightTreeDi
|
||||
runTest("compiler/fir/analysis-tests/testData/resolve/diagnostics/supertypeInitializedWithoutPrimaryConstructor.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("suspendAnonymousFunction.kt")
|
||||
public void testSuspendAnonymousFunction() throws Exception {
|
||||
runTest("compiler/fir/analysis-tests/testData/resolve/diagnostics/suspendAnonymousFunction.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("testIllegalAnnotationClass.kt")
|
||||
public void testTestIllegalAnnotationClass() throws Exception {
|
||||
|
||||
+6
@@ -2027,6 +2027,12 @@ public class FirPsiDiagnosticTestGenerated extends AbstractFirPsiDiagnosticTest
|
||||
runTest("compiler/fir/analysis-tests/testData/resolve/diagnostics/supertypeInitializedWithoutPrimaryConstructor.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("suspendAnonymousFunction.kt")
|
||||
public void testSuspendAnonymousFunction() throws Exception {
|
||||
runTest("compiler/fir/analysis-tests/testData/resolve/diagnostics/suspendAnonymousFunction.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("testIllegalAnnotationClass.kt")
|
||||
public void testTestIllegalAnnotationClass() throws Exception {
|
||||
|
||||
+2
@@ -516,6 +516,8 @@ object DIAGNOSTICS_LIST : DiagnosticList("FirErrors") {
|
||||
|
||||
val NO_EXPLICIT_RETURN_TYPE_IN_API_MODE by error<KtDeclaration>(PositioningStrategy.DECLARATION_NAME)
|
||||
val NO_EXPLICIT_RETURN_TYPE_IN_API_MODE_WARNING by warning<KtDeclaration>(PositioningStrategy.DECLARATION_NAME)
|
||||
|
||||
val ANONYMOUS_SUSPEND_FUNCTION by error<KtDeclaration>(PositioningStrategy.SUSPEND_MODIFIER)
|
||||
}
|
||||
|
||||
val VALUE_CLASSES by object : DiagnosticGroup("Value classes") {
|
||||
|
||||
+1
@@ -66,6 +66,7 @@ enum class PositioningStrategy(private val strategy: String? = null) {
|
||||
LATEINIT_MODIFIER,
|
||||
INLINE_OR_VALUE_MODIFIER,
|
||||
INNER_MODIFIER,
|
||||
SUSPEND_MODIFIER,
|
||||
SELECTOR_BY_QUALIFIED,
|
||||
REFERENCE_BY_QUALIFIED,
|
||||
REFERENCED_NAME_BY_QUALIFIED,
|
||||
|
||||
@@ -358,6 +358,7 @@ object FirErrors {
|
||||
val NO_EXPLICIT_VISIBILITY_IN_API_MODE_WARNING: KtDiagnosticFactory0 by warning0<KtDeclaration>(SourceElementPositioningStrategies.DECLARATION_START_TO_NAME)
|
||||
val NO_EXPLICIT_RETURN_TYPE_IN_API_MODE: KtDiagnosticFactory0 by error0<KtDeclaration>(SourceElementPositioningStrategies.DECLARATION_NAME)
|
||||
val NO_EXPLICIT_RETURN_TYPE_IN_API_MODE_WARNING: KtDiagnosticFactory0 by warning0<KtDeclaration>(SourceElementPositioningStrategies.DECLARATION_NAME)
|
||||
val ANONYMOUS_SUSPEND_FUNCTION: KtDiagnosticFactory0 by error0<KtDeclaration>(SourceElementPositioningStrategies.SUSPEND_MODIFIER)
|
||||
|
||||
// Value classes
|
||||
val VALUE_CLASS_NOT_TOP_LEVEL: KtDiagnosticFactory0 by error0<KtDeclaration>(SourceElementPositioningStrategies.INLINE_OR_VALUE_MODIFIER)
|
||||
|
||||
+1
@@ -209,6 +209,7 @@ val FIR_NON_SUPPRESSIBLE_ERROR_NAMES: Set<String> = setOf(
|
||||
"INAPPLICABLE_OPERATOR_MODIFIER",
|
||||
"NO_EXPLICIT_VISIBILITY_IN_API_MODE",
|
||||
"NO_EXPLICIT_RETURN_TYPE_IN_API_MODE",
|
||||
"ANONYMOUS_SUSPEND_FUNCTION",
|
||||
"VALUE_CLASS_NOT_TOP_LEVEL",
|
||||
"VALUE_CLASS_NOT_FINAL",
|
||||
"ABSENCE_OF_PRIMARY_CONSTRUCTOR_FOR_VALUE_CLASS",
|
||||
|
||||
+2
@@ -14,6 +14,7 @@ import org.jetbrains.kotlin.fir.analysis.checkers.expression.FirAnonymousFunctio
|
||||
import org.jetbrains.kotlin.fir.analysis.checkers.declaration.FirFiniteBoundRestrictionChecker
|
||||
import org.jetbrains.kotlin.fir.analysis.checkers.expression.FirInlinedLambdaNonSourceAnnotationsChecker
|
||||
import org.jetbrains.kotlin.fir.analysis.checkers.expression.FirMissingDependencySupertypeChecker
|
||||
import org.jetbrains.kotlin.fir.analysis.checkers.expression.FirSuspendAnonymousFunctionChecker
|
||||
import org.jetbrains.kotlin.fir.analysis.checkers.syntax.*
|
||||
|
||||
object CommonDeclarationCheckers : DeclarationCheckers() {
|
||||
@@ -195,6 +196,7 @@ object CommonDeclarationCheckers : DeclarationCheckers() {
|
||||
FirAnonymousFunctionParametersChecker,
|
||||
FirInlinedLambdaNonSourceAnnotationsChecker,
|
||||
FirAnonymousFunctionSyntaxChecker,
|
||||
FirSuspendAnonymousFunctionChecker,
|
||||
)
|
||||
|
||||
override val anonymousInitializerCheckers: Set<FirAnonymousInitializerChecker>
|
||||
|
||||
+22
@@ -0,0 +1,22 @@
|
||||
/*
|
||||
* Copyright 2010-2023 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.fir.analysis.checkers.expression
|
||||
|
||||
import org.jetbrains.kotlin.diagnostics.DiagnosticReporter
|
||||
import org.jetbrains.kotlin.diagnostics.reportOn
|
||||
import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext
|
||||
import org.jetbrains.kotlin.fir.analysis.checkers.declaration.FirAnonymousFunctionChecker
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors
|
||||
import org.jetbrains.kotlin.fir.declarations.FirAnonymousFunction
|
||||
import org.jetbrains.kotlin.fir.declarations.utils.isSuspend
|
||||
|
||||
object FirSuspendAnonymousFunctionChecker : FirAnonymousFunctionChecker() {
|
||||
override fun check(declaration: FirAnonymousFunction, context: CheckerContext, reporter: DiagnosticReporter) {
|
||||
if (!declaration.isLambda && declaration.isSuspend) {
|
||||
reporter.reportOn(declaration.source, FirErrors.ANONYMOUS_SUSPEND_FUNCTION, context)
|
||||
}
|
||||
}
|
||||
}
|
||||
+2
@@ -96,6 +96,7 @@ import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.ANNOTATION_USED_A
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.ANONYMOUS_FUNCTION_PARAMETER_WITH_DEFAULT_VALUE
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.ANONYMOUS_FUNCTION_WITH_NAME
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.ANONYMOUS_INITIALIZER_IN_INTERFACE
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.ANONYMOUS_SUSPEND_FUNCTION
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.API_NOT_AVAILABLE
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.ARGUMENT_PASSED_TWICE
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.ARGUMENT_TYPE_MISMATCH
|
||||
@@ -1155,6 +1156,7 @@ object FirErrorsDefaultMessages : BaseDiagnosticRendererFactory() {
|
||||
map.put(NO_EXPLICIT_RETURN_TYPE_IN_API_MODE, "Return type must be specified in explicit API mode.")
|
||||
map.put(NO_EXPLICIT_VISIBILITY_IN_API_MODE_WARNING, "Visibility must be specified in explicit API mode.")
|
||||
map.put(NO_EXPLICIT_RETURN_TYPE_IN_API_MODE_WARNING, "Return type must be specified in explicit API mode.")
|
||||
map.put(ANONYMOUS_SUSPEND_FUNCTION, "Anonymous suspend functions are prohibited.")
|
||||
|
||||
map.put(INCOMPATIBLE_MODIFIERS, "Modifier ''{0}'' is incompatible with ''{1}''.", TO_STRING, TO_STRING)
|
||||
map.put(REDUNDANT_OPEN_IN_INTERFACE, "Modifier 'open' is redundant for abstract interface members.")
|
||||
|
||||
@@ -0,0 +1,7 @@
|
||||
// ISSUE: KT-57991
|
||||
|
||||
fun foo() {
|
||||
<!ANONYMOUS_SUSPEND_FUNCTION!>suspend<!> fun() {
|
||||
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,3 @@
|
||||
// FIR_IDENTICAL
|
||||
// ISSUE: KT-57991
|
||||
|
||||
fun foo() {
|
||||
|
||||
+1
-1
@@ -4,6 +4,6 @@ fun <T> produce(arg: () -> T): T = arg()
|
||||
|
||||
fun main() {
|
||||
produce {
|
||||
<!ARGUMENT_TYPE_MISMATCH!>suspend fun() {}<!> // CCE
|
||||
<!ARGUMENT_TYPE_MISMATCH!><!ANONYMOUS_SUSPEND_FUNCTION!>suspend<!> fun() {}<!> // CCE
|
||||
}
|
||||
}
|
||||
|
||||
Vendored
+11
@@ -0,0 +1,11 @@
|
||||
// FIR_DUMP
|
||||
|
||||
fun foo() {
|
||||
<!ANONYMOUS_SUSPEND_FUNCTION!>suspend<!> fun() {
|
||||
bar()
|
||||
}
|
||||
}
|
||||
|
||||
suspend fun bar() {
|
||||
|
||||
}
|
||||
Vendored
+1
-1
@@ -1,4 +1,4 @@
|
||||
FILE: suspendCallFromAnonymousSuspend.kt
|
||||
FILE: suspendCallFromAnonymousSuspend.fir.kt
|
||||
public final fun foo(): R|kotlin/Unit| {
|
||||
suspend fun <anonymous>(): R|kotlin/Unit| <inline=Unknown> {
|
||||
R|/bar|()
|
||||
|
||||
-1
@@ -1,4 +1,3 @@
|
||||
// FIR_IDENTICAL
|
||||
// FIR_DUMP
|
||||
|
||||
fun foo() {
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
// FIR_IDENTICAL
|
||||
// IGNORE_BACKEND_K2: ANY
|
||||
// Ignore reasons: anonymous suspend functions are prohibited, KT-62018
|
||||
// ISSUE: KT-58332
|
||||
|
||||
fun foo() {
|
||||
|
||||
Reference in New Issue
Block a user