diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/checkers/coroutineCallChecker.kt b/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/checkers/coroutineCallChecker.kt index bd199a42932..00b86c91c8c 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/checkers/coroutineCallChecker.kt +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/checkers/coroutineCallChecker.kt @@ -30,6 +30,7 @@ import org.jetbrains.kotlin.resolve.BindingContext import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall import org.jetbrains.kotlin.resolve.descriptorUtil.hasRestrictsSuspensionAnnotation import org.jetbrains.kotlin.resolve.inline.InlineUtil +import org.jetbrains.kotlin.resolve.scopes.HierarchicalScope import org.jetbrains.kotlin.resolve.scopes.LexicalScope import org.jetbrains.kotlin.resolve.scopes.LexicalScopeKind import org.jetbrains.kotlin.resolve.scopes.receivers.ExpressionReceiver @@ -60,6 +61,9 @@ object CoroutineSuspendCallChecker : CallChecker { if (!InlineUtil.checkNonLocalReturnUsage(enclosingSuspendFunction, callElement, context.resolutionContext)) { context.trace.report(Errors.NON_LOCAL_SUSPENSION_POINT.on(reportOn)) } + else if (context.scope.parentsWithSelf.any { it.isScopeForDefaultParameterValuesOf(enclosingSuspendFunction) }) { + context.trace.report(Errors.UNSUPPORTED.on(reportOn, "suspend function calls in a context of default parameter value")) + } context.trace.record(BindingContext.ENCLOSING_SUSPEND_FUNCTION_FOR_SUSPEND_FUNCTION_CALL, resolvedCall.call, enclosingSuspendFunction) @@ -72,6 +76,9 @@ object CoroutineSuspendCallChecker : CallChecker { } } +private fun HierarchicalScope.isScopeForDefaultParameterValuesOf(enclosingSuspendFunction: FunctionDescriptor) = + this is LexicalScope && this.kind == LexicalScopeKind.DEFAULT_VALUE && this.ownerDescriptor == enclosingSuspendFunction + object BuilderFunctionsCallChecker : CallChecker { override fun check(resolvedCall: ResolvedCall<*>, reportOn: PsiElement, context: CallCheckerContext) { val descriptor = resolvedCall.candidateDescriptor as? FunctionDescriptor ?: return diff --git a/compiler/testData/diagnostics/testsWithStdLib/coroutines/suspesionInDefaultValue.kt b/compiler/testData/diagnostics/testsWithStdLib/coroutines/suspesionInDefaultValue.kt new file mode 100644 index 00000000000..72cf8bce832 --- /dev/null +++ b/compiler/testData/diagnostics/testsWithStdLib/coroutines/suspesionInDefaultValue.kt @@ -0,0 +1,17 @@ +// !DIAGNOSTICS: -UNUSED_PARAMETER +// SKIP_TXT + +suspend fun foo() = 1 + +suspend fun bar( + x: Int = 2 + foo(), + y: suspend () -> Int = { foo() }, + z: () -> Int = { foo() }, + w: Int = myInline { foo() }, + v: Any? = object { + fun x() = foo() + suspend fun y() = foo() + } +) {} + +inline fun myInline(x: () -> Unit) = 1 diff --git a/compiler/tests/org/jetbrains/kotlin/checkers/DiagnosticsTestWithStdLibGenerated.java b/compiler/tests/org/jetbrains/kotlin/checkers/DiagnosticsTestWithStdLibGenerated.java index 3a503034ad1..a624d42747a 100644 --- a/compiler/tests/org/jetbrains/kotlin/checkers/DiagnosticsTestWithStdLibGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/checkers/DiagnosticsTestWithStdLibGenerated.java @@ -827,6 +827,12 @@ public class DiagnosticsTestWithStdLibGenerated extends AbstractDiagnosticsTestW doTest(fileName); } + @TestMetadata("suspesionInDefaultValue.kt") + public void testSuspesionInDefaultValue() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/testsWithStdLib/coroutines/suspesionInDefaultValue.kt"); + doTest(fileName); + } + @TestMetadata("tryCatchLambda.kt") public void testTryCatchLambda() throws Exception { String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/testsWithStdLib/coroutines/tryCatchLambda.kt");