Calls for suspend functions imported from object should be checked in CoroutineSuspendCallChecker.

This commit is contained in:
Dmitry Petrov
2017-01-25 16:27:49 +03:00
parent 500667ff45
commit 9d4047f5e4
5 changed files with 46 additions and 4 deletions
@@ -42,7 +42,7 @@ import org.jetbrains.kotlin.utils.addToStdlib.safeAs
object CoroutineSuspendCallChecker : CallChecker {
override fun check(resolvedCall: ResolvedCall<*>, reportOn: PsiElement, context: CallCheckerContext) {
val descriptor = resolvedCall.candidateDescriptor as? SimpleFunctionDescriptor ?: return
val descriptor = resolvedCall.candidateDescriptor as? FunctionDescriptor ?: return
if (!descriptor.isSuspend) return
val enclosingSuspendFunction =
@@ -60,9 +60,7 @@ object CoroutineSuspendCallChecker : CallChecker {
context.trace.report(Errors.NON_LOCAL_SUSPENSION_POINT.on(reportOn))
}
context.trace.record(
BindingContext.ENCLOSING_SUSPEND_FUNCTION_FOR_SUSPEND_FUNCTION_CALL, resolvedCall.call, enclosingSuspendFunction
)
context.trace.record(BindingContext.ENCLOSING_SUSPEND_FUNCTION_FOR_SUSPEND_FUNCTION_CALL, resolvedCall.call, enclosingSuspendFunction)
checkRestrictsSuspension(enclosingSuspendFunction, resolvedCall, reportOn, context)
}
@@ -1,13 +1,22 @@
import Host.bar
object Host {
suspend fun bar() {}
}
suspend fun foo() {}
fun noSuspend() {
<!ILLEGAL_SUSPEND_FUNCTION_CALL!>foo<!>()
<!ILLEGAL_SUSPEND_FUNCTION_CALL!>bar<!>()
}
class A {
init {
<!ILLEGAL_SUSPEND_FUNCTION_CALL!>foo<!>()
<!ILLEGAL_SUSPEND_FUNCTION_CALL!>bar<!>()
}
}
val x = <!ILLEGAL_SUSPEND_FUNCTION_CALL!>foo<!>()
val y = <!ILLEGAL_SUSPEND_FUNCTION_CALL!>bar<!>()
@@ -1,6 +1,7 @@
package
public val x: kotlin.Unit
public val y: kotlin.Unit
public suspend fun foo(): kotlin.Unit
public fun noSuspend(): kotlin.Unit
@@ -10,3 +11,11 @@ public final class A {
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
}
public object Host {
private constructor Host()
public final suspend fun bar(): kotlin.Unit
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
}
@@ -1,8 +1,13 @@
// !DIAGNOSTICS: -UNUSED_PARAMETER
import Host.suspendFromObject
suspend fun suspendHere() = 1
suspend fun <T> another(a: T) = 1
object Host {
suspend fun suspendFromObject() = 1
}
fun <T> builder(c: suspend () -> Unit) { }
inline fun run(x: () -> Unit) {}
@@ -15,46 +20,59 @@ fun foo() {
var result = 1
builder<String> {
suspendHere()
suspendFromObject()
another("")
another(1)
result += suspendHere()
result += suspendFromObject()
run {
result += suspendHere()
result += suspendFromObject()
run {
suspendHere()
suspendFromObject()
}
}
runCross {
result += <!NON_LOCAL_SUSPENSION_POINT!>suspendHere<!>()
result += <!NON_LOCAL_SUSPENSION_POINT!>suspendFromObject<!>()
runCross {
<!NON_LOCAL_SUSPENSION_POINT!>suspendHere<!>()
<!NON_LOCAL_SUSPENSION_POINT!>suspendFromObject<!>()
}
}
noinline {
result += <!NON_LOCAL_SUSPENSION_POINT!>suspendHere<!>()
result += <!NON_LOCAL_SUSPENSION_POINT!>suspendFromObject<!>()
noinline {
<!NON_LOCAL_SUSPENSION_POINT!>suspendHere<!>()
<!NON_LOCAL_SUSPENSION_POINT!>suspendFromObject<!>()
}
}
class A {
fun bar() {
<!NON_LOCAL_SUSPENSION_POINT!>suspendHere<!>()
<!NON_LOCAL_SUSPENSION_POINT!>suspendFromObject<!>()
}
}
object : Any() {
fun baz() {
<!NON_LOCAL_SUSPENSION_POINT!>suspendHere<!>()
<!NON_LOCAL_SUSPENSION_POINT!>suspendFromObject<!>()
}
}
builder<Int> {
suspendHere()
suspendFromObject()
another(1)
another("")
@@ -7,3 +7,11 @@ public fun noinline(/*0*/ x: () -> kotlin.Unit): kotlin.Unit
public inline fun run(/*0*/ x: () -> kotlin.Unit): kotlin.Unit
public inline fun runCross(/*0*/ crossinline x: () -> kotlin.Unit): kotlin.Unit
public suspend fun suspendHere(): kotlin.Int
public object Host {
private constructor Host()
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
public final suspend fun suspendFromObject(): kotlin.Int
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
}