From 3327bed5bd4610dffb59a6eb09d5f04ab8380904 Mon Sep 17 00:00:00 2001 From: Brian Norman Date: Tue, 31 Oct 2023 11:25:39 -0500 Subject: [PATCH] [FIR] Report more occurrences of NON_LOCAL_RETURN_NOT_ALLOWED When an inline lambda is invoked or passed to another inline function, make sure non-local returns are allowed by all surrounding declarations. Otherwise, NON_LOCAL_RETURN_NOT_ALLOWED must be reported. ^KT-59884 Fixed ^KT-55319 Fixed --- .../FirInlineDeclarationChecker.kt | 76 +++++++++++++++++-- ...nlineLambdaInDefaultInlineParameter.fir.kt | 6 +- .../nonLocalReturns/anonymousObjects.fir.kt | 23 ------ .../nonLocalReturns/anonymousObjects.kt | 1 + .../anonymousObjectsNested.fir.kt | 48 ------------ .../nonLocalReturns/anonymousObjectsNested.kt | 1 + ...WithGlobalReturnsInsideOnlyLocalOne.fir.kt | 9 --- ...mbdaWithGlobalReturnsInsideOnlyLocalOne.kt | 1 + .../inline/nonLocalReturns/localFun.fir.kt | 15 ---- .../tests/inline/nonLocalReturns/localFun.kt | 1 + .../nonLocalReturns/noInlineLambda.fir.kt | 13 ---- .../inline/nonLocalReturns/noInlineLambda.kt | 1 + .../nonLocalReturns/nonInlinedClass.fir.kt | 23 ------ .../inline/nonLocalReturns/nonInlinedClass.kt | 1 + .../inlineOrdinaryOfOrdinary.fir.kt | 4 +- .../inlineOrdinaryOfSuspend.fir.kt | 40 ---------- .../inlineOrdinaryOfSuspend.kt | 1 + .../inlineSuspendOfOrdinary.fir.kt | 4 +- .../inlineSuspendOfSuspend.fir.kt | 4 +- 19 files changed, 84 insertions(+), 188 deletions(-) delete mode 100644 compiler/testData/diagnostics/tests/inline/nonLocalReturns/anonymousObjects.fir.kt delete mode 100644 compiler/testData/diagnostics/tests/inline/nonLocalReturns/anonymousObjectsNested.fir.kt delete mode 100644 compiler/testData/diagnostics/tests/inline/nonLocalReturns/lambdaWithGlobalReturnsInsideOnlyLocalOne.fir.kt delete mode 100644 compiler/testData/diagnostics/tests/inline/nonLocalReturns/localFun.fir.kt delete mode 100644 compiler/testData/diagnostics/tests/inline/nonLocalReturns/noInlineLambda.fir.kt delete mode 100644 compiler/testData/diagnostics/tests/inline/nonLocalReturns/nonInlinedClass.fir.kt delete mode 100644 compiler/testData/diagnostics/testsWithStdLib/coroutines/inlineCrossinline/inlineOrdinaryOfSuspend.fir.kt diff --git a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/declaration/FirInlineDeclarationChecker.kt b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/declaration/FirInlineDeclarationChecker.kt index e56a7dc7dce..04dc75b0be7 100644 --- a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/declaration/FirInlineDeclarationChecker.kt +++ b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/declaration/FirInlineDeclarationChecker.kt @@ -21,13 +21,10 @@ import org.jetbrains.kotlin.fir.analysis.checkers.inlineCheckerExtension import org.jetbrains.kotlin.fir.analysis.checkers.isInlineOnly import org.jetbrains.kotlin.fir.analysis.checkers.unsubstitutedScope import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors -import org.jetbrains.kotlin.fir.declarations.FirCallableDeclaration -import org.jetbrains.kotlin.fir.declarations.FirFunction -import org.jetbrains.kotlin.fir.declarations.FirPropertyAccessor -import org.jetbrains.kotlin.fir.declarations.FirSimpleFunction +import org.jetbrains.kotlin.fir.declarations.* import org.jetbrains.kotlin.fir.declarations.utils.* import org.jetbrains.kotlin.fir.expressions.* -import org.jetbrains.kotlin.fir.references.FirSuperReference +import org.jetbrains.kotlin.fir.references.* import org.jetbrains.kotlin.fir.resolve.toSymbol import org.jetbrains.kotlin.fir.resolve.transformers.publishedApiEffectiveVisibility import org.jetbrains.kotlin.fir.scopes.getDirectOverriddenMembers @@ -145,8 +142,10 @@ object FirInlineDeclarationChecker : FirFunctionChecker() { valueParameter.isNoinline -> { FirErrors.USAGE_IS_NOT_INLINABLE } - valueParameter.isCrossinline && !valueParameterOfOriginalInlineFunction.isCrossinline - -> FirErrors.NON_LOCAL_RETURN_NOT_ALLOWED + !valueParameterOfOriginalInlineFunction.isCrossinline && + (valueParameter.isCrossinline || !isNonLocalReturnAllowed(context, inlineFunction)) -> { + FirErrors.NON_LOCAL_RETURN_NOT_ALLOWED + } else -> continue } else -> FirErrors.USAGE_IS_NOT_INLINABLE @@ -164,7 +163,7 @@ object FirInlineDeclarationChecker : FirFunctionChecker() { reporter: DiagnosticReporter, ) { if (receiverExpression == null) return - val receiverSymbol = receiverExpression.toResolvedCallableSymbol() ?: return + val receiverSymbol = receiverExpression.toResolvedCallableSymbol() as? FirValueParameterSymbol ?: return if (receiverSymbol in inlinableParameters) { if (!isInvokeOrInlineExtension(targetSymbol)) { reporter.reportOn( @@ -173,6 +172,13 @@ object FirInlineDeclarationChecker : FirFunctionChecker() { receiverSymbol, context ) + } else if (!receiverSymbol.isCrossinline && !isNonLocalReturnAllowed(context, inlineFunction)) { + reporter.reportOn( + receiverExpression.source ?: qualifiedAccessExpression.source, + FirErrors.NON_LOCAL_RETURN_NOT_ALLOWED, + receiverSymbol, + context, + ) } } } @@ -474,6 +480,60 @@ object FirInlineDeclarationChecker : FirFunctionChecker() { reporter.reportOn(declaration.source, FirErrors.OVERRIDE_BY_INLINE, context) } } + + private fun isNonLocalReturnAllowed(context: CheckerContext, inlineFunction: FirFunction): Boolean { + val declarations = context.containingDeclarations + val inlineFunctionIndex = declarations.indexOf(inlineFunction) + if (inlineFunctionIndex == -1) return true + + for (i in (inlineFunctionIndex + 1) until declarations.size) { + val declaration = declarations[i] + + // Only consider containers which can change locality. + if (declaration !is FirFunction && declaration !is FirClass) continue + + // Anonymous functions are allowed if they are an argument to an inline function call, + // and the associated anonymous function parameter allows non-local returns. Everything + // else changes locality, and must not be allowed. + val anonymousFunction = declaration as? FirAnonymousFunction ?: return false + val (call, parameter) = extractCallAndParameter(context, anonymousFunction) ?: return false + val callable = call.toResolvedCallableSymbol() as? FirFunctionSymbol<*> ?: return false + if (!callable.isInline && !callable.isArrayLambdaConstructor()) return false + if (parameter.isNoinline || parameter.isCrossinline) return false + } + + return true + } + + private fun extractCallAndParameter( + context: CheckerContext, + anonymousFunction: FirAnonymousFunction, + ): Pair? { + for (call in context.callsOrAssignments) { + if (call is FirFunctionCall) { + val mapping = call.resolvedArgumentMapping ?: continue + for ((argument, parameter) in mapping) { + if ((argument.unwrapArgument() as? FirAnonymousFunctionExpression)?.anonymousFunction === anonymousFunction) { + return call to parameter + } + } + } + } + return null + } + + /** + * @return true if the symbol is the constructor of one of 9 array classes (`Array`, + * `IntArray`, `FloatArray`, ...) which takes the size and an initializer lambda as parameters. + * Such constructors are marked as `inline` but they are not loaded as such because the `inline` + * flag is not stored for constructors in the binary metadata. Therefore, we pretend that they + * are inline. + */ + private fun FirFunctionSymbol<*>.isArrayLambdaConstructor(): Boolean { + return this is FirConstructorSymbol && + valueParameterSymbols.size == 2 && + resolvedReturnType.isArrayOrPrimitiveArray + } } fun createInlineFunctionBodyContext(function: FirFunction, session: FirSession): FirInlineDeclarationChecker.InlineFunctionBodyContext { diff --git a/compiler/testData/diagnostics/tests/inline/inlineLambdaInDefaultInlineParameter.fir.kt b/compiler/testData/diagnostics/tests/inline/inlineLambdaInDefaultInlineParameter.fir.kt index 4d0fe451b8d..b749296c586 100644 --- a/compiler/testData/diagnostics/tests/inline/inlineLambdaInDefaultInlineParameter.fir.kt +++ b/compiler/testData/diagnostics/tests/inline/inlineLambdaInDefaultInlineParameter.fir.kt @@ -20,11 +20,11 @@ inline fun default0(lambda: () -> String, dlambda: () -> String = { noInlineFun lambda() + dlambda() } -inline fun default1_0(lambda: () -> String, dlambda: () -> String = { lambda() }) { +inline fun default1_0(lambda: () -> String, dlambda: () -> String = { lambda() }) { lambda() + dlambda() } -inline fun default1_1(lambda: () -> String, noinline dlambda: () -> String = { lambda() }) { +inline fun default1_1(lambda: () -> String, noinline dlambda: () -> String = { lambda() }) { lambda() + dlambda() } @@ -41,7 +41,7 @@ inline fun default1_3(noinline lambda: () -> String, noinline dlambda: () -> Str } -inline fun default2_1(lambda: () -> String, noinline dlambda: () -> String = { inlineFun(lambda) }) { +inline fun default2_1(lambda: () -> String, noinline dlambda: () -> String = { inlineFun(lambda) }) { lambda() + dlambda() } diff --git a/compiler/testData/diagnostics/tests/inline/nonLocalReturns/anonymousObjects.fir.kt b/compiler/testData/diagnostics/tests/inline/nonLocalReturns/anonymousObjects.fir.kt deleted file mode 100644 index 39a8ec3d9cb..00000000000 --- a/compiler/testData/diagnostics/tests/inline/nonLocalReturns/anonymousObjects.fir.kt +++ /dev/null @@ -1,23 +0,0 @@ -// !DIAGNOSTICS: -UNUSED_EXPRESSION -UNUSED_PARAMETER -UNUSED_VARIABLE -NOTHING_TO_INLINE - -inline fun inlineFunOnlyLocal(crossinline p: () -> R) { - val s = object { - - val z = p() - - fun a() { - p() - } - } -} - -inline fun inlineFun(p: () -> R) { - val s = object { - - val z = p() - - fun a() { - p() - } - } -} diff --git a/compiler/testData/diagnostics/tests/inline/nonLocalReturns/anonymousObjects.kt b/compiler/testData/diagnostics/tests/inline/nonLocalReturns/anonymousObjects.kt index 60cff430f8b..6db1b3e8483 100644 --- a/compiler/testData/diagnostics/tests/inline/nonLocalReturns/anonymousObjects.kt +++ b/compiler/testData/diagnostics/tests/inline/nonLocalReturns/anonymousObjects.kt @@ -1,3 +1,4 @@ +// FIR_IDENTICAL // !DIAGNOSTICS: -UNUSED_EXPRESSION -UNUSED_PARAMETER -UNUSED_VARIABLE -NOTHING_TO_INLINE inline fun inlineFunOnlyLocal(crossinline p: () -> R) { diff --git a/compiler/testData/diagnostics/tests/inline/nonLocalReturns/anonymousObjectsNested.fir.kt b/compiler/testData/diagnostics/tests/inline/nonLocalReturns/anonymousObjectsNested.fir.kt deleted file mode 100644 index e068f2a91d5..00000000000 --- a/compiler/testData/diagnostics/tests/inline/nonLocalReturns/anonymousObjectsNested.fir.kt +++ /dev/null @@ -1,48 +0,0 @@ -// !DIAGNOSTICS: -UNUSED_EXPRESSION -UNUSED_PARAMETER -UNUSED_VARIABLE -NOTHING_TO_INLINE - -inline fun inlineFunOnlyLocal(crossinline p: () -> R) { - val s = object { - - val z = p(); - - init { - doCall { - p() - } - } - - fun a() { - doCall { - p() - } - - p() - } - } -} - -inline fun inlineFun(p: () -> R) { - val s = object { - - val z = p() - - init { - doCall { - p() - } - } - - - fun a() { - doCall { - p() - } - - p() - } - } -} - -inline fun doCall(p: () -> R) { - p() -} diff --git a/compiler/testData/diagnostics/tests/inline/nonLocalReturns/anonymousObjectsNested.kt b/compiler/testData/diagnostics/tests/inline/nonLocalReturns/anonymousObjectsNested.kt index 91e637ce58f..61de7334271 100644 --- a/compiler/testData/diagnostics/tests/inline/nonLocalReturns/anonymousObjectsNested.kt +++ b/compiler/testData/diagnostics/tests/inline/nonLocalReturns/anonymousObjectsNested.kt @@ -1,3 +1,4 @@ +// FIR_IDENTICAL // !DIAGNOSTICS: -UNUSED_EXPRESSION -UNUSED_PARAMETER -UNUSED_VARIABLE -NOTHING_TO_INLINE inline fun inlineFunOnlyLocal(crossinline p: () -> R) { diff --git a/compiler/testData/diagnostics/tests/inline/nonLocalReturns/lambdaWithGlobalReturnsInsideOnlyLocalOne.fir.kt b/compiler/testData/diagnostics/tests/inline/nonLocalReturns/lambdaWithGlobalReturnsInsideOnlyLocalOne.fir.kt deleted file mode 100644 index 37a7935c201..00000000000 --- a/compiler/testData/diagnostics/tests/inline/nonLocalReturns/lambdaWithGlobalReturnsInsideOnlyLocalOne.fir.kt +++ /dev/null @@ -1,9 +0,0 @@ - -inline fun testSameCaptured(lambdaWithResultCaptured: () -> Unit) : String { - doWork({lambdaWithResultCaptured()}) - return "OK" -} - -inline fun doWork(crossinline job: ()-> R) : R { - return job() -} diff --git a/compiler/testData/diagnostics/tests/inline/nonLocalReturns/lambdaWithGlobalReturnsInsideOnlyLocalOne.kt b/compiler/testData/diagnostics/tests/inline/nonLocalReturns/lambdaWithGlobalReturnsInsideOnlyLocalOne.kt index 6d43d939408..0ce41d11611 100644 --- a/compiler/testData/diagnostics/tests/inline/nonLocalReturns/lambdaWithGlobalReturnsInsideOnlyLocalOne.kt +++ b/compiler/testData/diagnostics/tests/inline/nonLocalReturns/lambdaWithGlobalReturnsInsideOnlyLocalOne.kt @@ -1,3 +1,4 @@ +// FIR_IDENTICAL inline fun testSameCaptured(lambdaWithResultCaptured: () -> Unit) : String { doWork({lambdaWithResultCaptured()}) diff --git a/compiler/testData/diagnostics/tests/inline/nonLocalReturns/localFun.fir.kt b/compiler/testData/diagnostics/tests/inline/nonLocalReturns/localFun.fir.kt deleted file mode 100644 index b97e005c8ae..00000000000 --- a/compiler/testData/diagnostics/tests/inline/nonLocalReturns/localFun.fir.kt +++ /dev/null @@ -1,15 +0,0 @@ -// !DIAGNOSTICS: -UNUSED_EXPRESSION -UNUSED_PARAMETER -UNUSED_VARIABLE -NOTHING_TO_INLINE - -inline fun inlineFunOnlyLocal(crossinline p: () -> R) { - fun a() { - val z = p() - } - a() -} - -inline fun inlineFun(p: () -> R) { - fun a() { - p() - } - a() -} diff --git a/compiler/testData/diagnostics/tests/inline/nonLocalReturns/localFun.kt b/compiler/testData/diagnostics/tests/inline/nonLocalReturns/localFun.kt index 412a635203c..d5cb5e14569 100644 --- a/compiler/testData/diagnostics/tests/inline/nonLocalReturns/localFun.kt +++ b/compiler/testData/diagnostics/tests/inline/nonLocalReturns/localFun.kt @@ -1,3 +1,4 @@ +// FIR_IDENTICAL // !DIAGNOSTICS: -UNUSED_EXPRESSION -UNUSED_PARAMETER -UNUSED_VARIABLE -NOTHING_TO_INLINE inline fun inlineFunOnlyLocal(crossinline p: () -> R) { diff --git a/compiler/testData/diagnostics/tests/inline/nonLocalReturns/noInlineLambda.fir.kt b/compiler/testData/diagnostics/tests/inline/nonLocalReturns/noInlineLambda.fir.kt deleted file mode 100644 index 24277028a18..00000000000 --- a/compiler/testData/diagnostics/tests/inline/nonLocalReturns/noInlineLambda.fir.kt +++ /dev/null @@ -1,13 +0,0 @@ -// !DIAGNOSTICS: -UNUSED_EXPRESSION -UNUSED_PARAMETER -UNUSED_VARIABLE -NOTHING_TO_INLINE - -inline fun inlineFunOnlyLocal(crossinline p: () -> R) { - { - p() - }() -} - -inline fun inlineFun(p: () -> R) { - { - p() - }() -} diff --git a/compiler/testData/diagnostics/tests/inline/nonLocalReturns/noInlineLambda.kt b/compiler/testData/diagnostics/tests/inline/nonLocalReturns/noInlineLambda.kt index ac736c17d81..e77e4971647 100644 --- a/compiler/testData/diagnostics/tests/inline/nonLocalReturns/noInlineLambda.kt +++ b/compiler/testData/diagnostics/tests/inline/nonLocalReturns/noInlineLambda.kt @@ -1,3 +1,4 @@ +// FIR_IDENTICAL // !DIAGNOSTICS: -UNUSED_EXPRESSION -UNUSED_PARAMETER -UNUSED_VARIABLE -NOTHING_TO_INLINE inline fun inlineFunOnlyLocal(crossinline p: () -> R) { diff --git a/compiler/testData/diagnostics/tests/inline/nonLocalReturns/nonInlinedClass.fir.kt b/compiler/testData/diagnostics/tests/inline/nonLocalReturns/nonInlinedClass.fir.kt deleted file mode 100644 index 2eb76075e4d..00000000000 --- a/compiler/testData/diagnostics/tests/inline/nonLocalReturns/nonInlinedClass.fir.kt +++ /dev/null @@ -1,23 +0,0 @@ -// !DIAGNOSTICS: -UNUSED_EXPRESSION -UNUSED_PARAMETER -UNUSED_VARIABLE -NOTHING_TO_INLINE - -inline fun inlineFunOnlyLocal(crossinline p: () -> R) { - class A { - - val z = p() - - fun a() { - p() - } - } -} - -inline fun inlineFun(p: () -> R) { - class A { - - val z = p() - - fun a() { - p() - } - } -} diff --git a/compiler/testData/diagnostics/tests/inline/nonLocalReturns/nonInlinedClass.kt b/compiler/testData/diagnostics/tests/inline/nonLocalReturns/nonInlinedClass.kt index 065f8daf4bf..0a460eb047d 100644 --- a/compiler/testData/diagnostics/tests/inline/nonLocalReturns/nonInlinedClass.kt +++ b/compiler/testData/diagnostics/tests/inline/nonLocalReturns/nonInlinedClass.kt @@ -1,3 +1,4 @@ +// FIR_IDENTICAL // !DIAGNOSTICS: -UNUSED_EXPRESSION -UNUSED_PARAMETER -UNUSED_VARIABLE -NOTHING_TO_INLINE inline fun inlineFunOnlyLocal(crossinline p: () -> R) { diff --git a/compiler/testData/diagnostics/testsWithStdLib/coroutines/inlineCrossinline/inlineOrdinaryOfOrdinary.fir.kt b/compiler/testData/diagnostics/testsWithStdLib/coroutines/inlineCrossinline/inlineOrdinaryOfOrdinary.fir.kt index 3d1b6c64f55..a33d5c17e0c 100644 --- a/compiler/testData/diagnostics/testsWithStdLib/coroutines/inlineCrossinline/inlineOrdinaryOfOrdinary.fir.kt +++ b/compiler/testData/diagnostics/testsWithStdLib/coroutines/inlineCrossinline/inlineOrdinaryOfOrdinary.fir.kt @@ -18,10 +18,10 @@ inline fun test(c: () -> Unit) { c() val o = object : Runnable { override fun run() { - c() + c() } } - val l = { c() } + val l = { c() } c.startCoroutine(EmptyContinuation) } diff --git a/compiler/testData/diagnostics/testsWithStdLib/coroutines/inlineCrossinline/inlineOrdinaryOfSuspend.fir.kt b/compiler/testData/diagnostics/testsWithStdLib/coroutines/inlineCrossinline/inlineOrdinaryOfSuspend.fir.kt deleted file mode 100644 index 754d7c89c85..00000000000 --- a/compiler/testData/diagnostics/testsWithStdLib/coroutines/inlineCrossinline/inlineOrdinaryOfSuspend.fir.kt +++ /dev/null @@ -1,40 +0,0 @@ -// !LANGUAGE: +ForbidExtensionCallsOnInlineFunctionalParameters -// !DIAGNOSTICS: -UNUSED_VARIABLE -NOTHING_TO_INLINE -UNUSED_PARAMETER -// SKIP_TXT -// WITH_COROUTINES -import kotlin.coroutines.* -import kotlin.coroutines.intrinsics.* -import helpers.* - -interface SuspendRunnable { - suspend fun run() -} - -// Function is NOT suspend -// parameter is inline -// parameter is suspend -// Block is NOT allowed to be called inside the body of owner inline function -// Block is NOT allowed to be called from nested classes/lambdas (as common crossinlines) -// It is NOT possible to call startCoroutine on the parameter -// suspend calls possible inside lambda matching to the parameter - -inline fun test(c: suspend () -> Unit) { - c() - val o = object: SuspendRunnable { - override suspend fun run() { - c() - } - } - val l: suspend () -> Unit = { c() } - c.startCoroutine(EmptyContinuation) -} - -fun builder(c: suspend () -> Unit) {} - -suspend fun calculate() = "OK" - -fun box() { - test { - calculate() - } -} diff --git a/compiler/testData/diagnostics/testsWithStdLib/coroutines/inlineCrossinline/inlineOrdinaryOfSuspend.kt b/compiler/testData/diagnostics/testsWithStdLib/coroutines/inlineCrossinline/inlineOrdinaryOfSuspend.kt index b8ffd08e273..1f7d0fd33d1 100644 --- a/compiler/testData/diagnostics/testsWithStdLib/coroutines/inlineCrossinline/inlineOrdinaryOfSuspend.kt +++ b/compiler/testData/diagnostics/testsWithStdLib/coroutines/inlineCrossinline/inlineOrdinaryOfSuspend.kt @@ -1,3 +1,4 @@ +// FIR_IDENTICAL // !LANGUAGE: +ForbidExtensionCallsOnInlineFunctionalParameters // !DIAGNOSTICS: -UNUSED_VARIABLE -NOTHING_TO_INLINE -UNUSED_PARAMETER // SKIP_TXT diff --git a/compiler/testData/diagnostics/testsWithStdLib/coroutines/inlineCrossinline/inlineSuspendOfOrdinary.fir.kt b/compiler/testData/diagnostics/testsWithStdLib/coroutines/inlineCrossinline/inlineSuspendOfOrdinary.fir.kt index 79180ae7052..04d603160d6 100644 --- a/compiler/testData/diagnostics/testsWithStdLib/coroutines/inlineCrossinline/inlineSuspendOfOrdinary.fir.kt +++ b/compiler/testData/diagnostics/testsWithStdLib/coroutines/inlineCrossinline/inlineSuspendOfOrdinary.fir.kt @@ -16,10 +16,10 @@ suspend inline fun test(c: () -> Unit) { c() val o = object: Runnable { override fun run() { - c() + c() } } - val l = { c() } + val l = { c() } c.startCoroutine(EmptyContinuation) } diff --git a/compiler/testData/diagnostics/testsWithStdLib/coroutines/inlineCrossinline/inlineSuspendOfSuspend.fir.kt b/compiler/testData/diagnostics/testsWithStdLib/coroutines/inlineCrossinline/inlineSuspendOfSuspend.fir.kt index 52875b08838..8a9bf24c6b2 100644 --- a/compiler/testData/diagnostics/testsWithStdLib/coroutines/inlineCrossinline/inlineSuspendOfSuspend.fir.kt +++ b/compiler/testData/diagnostics/testsWithStdLib/coroutines/inlineCrossinline/inlineSuspendOfSuspend.fir.kt @@ -21,10 +21,10 @@ suspend inline fun test(c: suspend () -> Unit) { c() val o = object: SuspendRunnable { override suspend fun run() { - c() + c() } } - val l: suspend () -> Unit = { c() } + val l: suspend () -> Unit = { c() } c.startCoroutine(EmptyContinuation) }