From 6471080c481ddf65472b4cca8b76c1dbca39b611 Mon Sep 17 00:00:00 2001 From: "Anastasia.Nekrasova" Date: Thu, 23 Nov 2023 09:29:07 +0000 Subject: [PATCH] [K2] Disappeared UNSUPPORTED Mark as UNSUPPORTED suspension points in default parameters ^KT-59881 --- .../expression/FirSuspendCallChecker.kt | 26 ++++++++++++++++--- .../coroutines/suspesionInDefaultValue.fir.kt | 6 +++-- .../coroutines/suspesionInDefaultValue.kt | 2 ++ 3 files changed, 28 insertions(+), 6 deletions(-) diff --git a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/expression/FirSuspendCallChecker.kt b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/expression/FirSuspendCallChecker.kt index adc404706a3..9dbda509be8 100644 --- a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/expression/FirSuspendCallChecker.kt +++ b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/expression/FirSuspendCallChecker.kt @@ -12,10 +12,8 @@ import org.jetbrains.kotlin.fir.FirSession import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors import org.jetbrains.kotlin.fir.analysis.getChild -import org.jetbrains.kotlin.fir.declarations.FirAnonymousFunction -import org.jetbrains.kotlin.fir.declarations.FirFunction -import org.jetbrains.kotlin.fir.declarations.FirSimpleFunction -import org.jetbrains.kotlin.fir.declarations.getAnnotationByClassId +import org.jetbrains.kotlin.fir.declarations.* +import org.jetbrains.kotlin.fir.declarations.utils.isInline import org.jetbrains.kotlin.fir.declarations.utils.isSuspend import org.jetbrains.kotlin.fir.expressions.* import org.jetbrains.kotlin.fir.references.FirResolvedCallableReference @@ -64,6 +62,14 @@ object FirSuspendCallChecker : FirQualifiedAccessExpressionChecker() { if (!checkNonLocalReturnUsage(enclosingSuspendFunction, context)) { reporter.reportOn(expression.source, FirErrors.NON_LOCAL_SUSPENSION_POINT, context) } + if (isInScopeForDefaultParameterValues(enclosingSuspendFunction, context)) { + reporter.reportOn( + expression.source, + FirErrors.UNSUPPORTED, + "suspend function calls in a context of default parameter value", + context + ) + } if (!checkRestrictsSuspension(expression, enclosingSuspendFunction, symbol, context)) { reporter.reportOn(expression.source, FirErrors.ILLEGAL_RESTRICTED_SUSPENDING_FUNCTION_CALL, context) } @@ -139,6 +145,18 @@ object FirSuspendCallChecker : FirQualifiedAccessExpressionChecker() { } as? FirFunction } + private fun isInScopeForDefaultParameterValues(enclosingSuspendFunction: FirFunction, context: CheckerContext): Boolean { + val valueParameters = enclosingSuspendFunction.valueParameters + for (declaration in context.containingDeclarations.asReversed()) { + when { + declaration is FirValueParameter && declaration in valueParameters && declaration.defaultValue != null -> return true + declaration is FirAnonymousFunction && declaration.inlineStatus == InlineStatus.Inline -> continue + declaration is FirFunction && !declaration.isInline -> return false + } + } + return false + } + private fun checkNonLocalReturnUsage(enclosingSuspendFunction: FirFunction, context: CheckerContext): Boolean { val containingFunction = context.containingDeclarations.lastIsInstanceOrNull() ?: return false return if (containingFunction is FirAnonymousFunction && enclosingSuspendFunction !== containingFunction) { diff --git a/compiler/testData/diagnostics/testsWithStdLib/coroutines/suspesionInDefaultValue.fir.kt b/compiler/testData/diagnostics/testsWithStdLib/coroutines/suspesionInDefaultValue.fir.kt index 89d0a0ced04..8cbef6028c5 100644 --- a/compiler/testData/diagnostics/testsWithStdLib/coroutines/suspesionInDefaultValue.fir.kt +++ b/compiler/testData/diagnostics/testsWithStdLib/coroutines/suspesionInDefaultValue.fir.kt @@ -4,10 +4,11 @@ suspend fun foo() = 1 suspend fun bar( - x: Int = 2 + foo(), + x: Int = 2 + foo(), y: suspend () -> Int = { foo() }, z: () -> Int = { foo() }, - w: Int = myInline { foo() }, + w: Int = myInline { foo() }, + q: Int = myInline2 { foo() }, v: Any? = object { fun x() = foo() suspend fun y() = foo() @@ -15,3 +16,4 @@ suspend fun bar( ) {} inline fun myInline(x: () -> Unit) = 1 +inline fun myInline2(crossinline x: () -> Unit) = 1 diff --git a/compiler/testData/diagnostics/testsWithStdLib/coroutines/suspesionInDefaultValue.kt b/compiler/testData/diagnostics/testsWithStdLib/coroutines/suspesionInDefaultValue.kt index 72cf8bce832..7642e5984cf 100644 --- a/compiler/testData/diagnostics/testsWithStdLib/coroutines/suspesionInDefaultValue.kt +++ b/compiler/testData/diagnostics/testsWithStdLib/coroutines/suspesionInDefaultValue.kt @@ -8,6 +8,7 @@ suspend fun bar( y: suspend () -> Int = { foo() }, z: () -> Int = { foo() }, w: Int = myInline { foo() }, + q: Int = myInline2 { foo() }, v: Any? = object { fun x() = foo() suspend fun y() = foo() @@ -15,3 +16,4 @@ suspend fun bar( ) {} inline fun myInline(x: () -> Unit) = 1 +inline fun myInline2(crossinline x: () -> Unit) = 1