FE: forbid extension calls on inline functional parameters

Extension receivers are currently implicitly noinline, and changing that
would require modifying the syntax to allow marking them noinline or
crossinline.

^KT-5837 Open
^KT-25787 Fixed
^KT-47965 Fixed
^KT-50107 Fixed
^KT-52403 Fixed
This commit is contained in:
pyos
2022-05-19 13:09:52 +02:00
committed by Space
parent efa267bf86
commit fad35b95d4
32 changed files with 59 additions and 356 deletions
@@ -21,7 +21,7 @@ inline fun test(crossinline c: () -> Unit) {
}
}
val l = { c() }
c.<!USAGE_IS_NOT_INLINABLE!>startCoroutine<!>(EmptyContinuation)
<!USAGE_IS_NOT_INLINABLE!>c<!>.startCoroutine(EmptyContinuation)
}
suspend fun calculate() = "OK"
@@ -1,37 +0,0 @@
// !DIAGNOSTICS: -UNUSED_VARIABLE -UNUSED_PARAMETER -NOTHING_TO_INLINE
// SKIP_TXT
// WITH_COROUTINES
import kotlin.coroutines.*
import kotlin.coroutines.intrinsics.*
import helpers.*
interface SuspendRunnable {
suspend fun run()
}
// Function is NOT suspend
// parameter is crossinline
// parameter is suspend
// Block is NOT allowed to be called inside the body of owner inline function
// Block is 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(crossinline c: suspend () -> Unit) {
<!ILLEGAL_SUSPEND_FUNCTION_CALL!>c<!>()
val o = object : SuspendRunnable {
override suspend fun run() {
c()
}
}
val l: suspend () -> Unit = { c() }
c.<!USAGE_IS_NOT_INLINABLE!>startCoroutine<!>(EmptyContinuation)
}
suspend fun calculate() = "OK"
fun box() {
test {
calculate()
}
}
@@ -1,3 +1,4 @@
// FIR_IDENTICAL
// !DIAGNOSTICS: -UNUSED_VARIABLE -UNUSED_PARAMETER -NOTHING_TO_INLINE
// SKIP_TXT
// WITH_COROUTINES
@@ -21,7 +21,7 @@ inline fun test(c: () -> Unit) {
}
}
val l = { c() }
c.<!USAGE_IS_NOT_INLINABLE!>startCoroutine<!>(EmptyContinuation)
<!USAGE_IS_NOT_INLINABLE!>c<!>.startCoroutine(EmptyContinuation)
}
fun builder(c: suspend () -> Unit) {
@@ -25,7 +25,7 @@ inline fun test(<!INLINE_SUSPEND_FUNCTION_TYPE_UNSUPPORTED!>c: suspend () -> Uni
}
}
val l: suspend () -> Unit = { c() }
c.<!USAGE_IS_NOT_INLINABLE!>startCoroutine<!>(EmptyContinuation)
<!USAGE_IS_NOT_INLINABLE!>c<!>.startCoroutine(EmptyContinuation)
}
fun builder(c: suspend () -> Unit) {}
@@ -20,7 +20,7 @@ suspend inline fun test(crossinline c: () -> Unit) {
}
}
val l = { c() }
c.<!USAGE_IS_NOT_INLINABLE!>startCoroutine<!>(EmptyContinuation)
<!USAGE_IS_NOT_INLINABLE!>c<!>.startCoroutine(EmptyContinuation)
}
fun builder(c: suspend () -> Unit) {
@@ -1,40 +0,0 @@
// !DIAGNOSTICS: -UNUSED_VARIABLE -UNUSED_PARAMETER -NOTHING_TO_INLINE
// SKIP_TXT
// WITH_COROUTINES
import kotlin.coroutines.*
import kotlin.coroutines.intrinsics.*
import helpers.*
interface SuspendRunnable {
suspend fun run()
}
// Function is suspend
// parameter is crossinline
// parameter is suspend
// Block is allowed to be called inside the body of owner inline function
// Block is 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
suspend inline fun test(crossinline c: suspend () -> Unit) {
c()
val o = object : SuspendRunnable {
override suspend fun run() {
c()
}
}
val l: suspend () -> Unit = { c() }
c.<!USAGE_IS_NOT_INLINABLE!>startCoroutine<!>(EmptyContinuation)
}
fun builder(c: suspend () -> Unit) {}
suspend fun calculate() = "OK"
fun box() {
builder {
test {
calculate()
}
}
}
@@ -1,3 +1,4 @@
// FIR_IDENTICAL
// !DIAGNOSTICS: -UNUSED_VARIABLE -UNUSED_PARAMETER -NOTHING_TO_INLINE
// SKIP_TXT
// WITH_COROUTINES
@@ -20,7 +20,7 @@ suspend inline fun test(c: () -> Unit) {
}
}
val l = { c() }
c.<!USAGE_IS_NOT_INLINABLE!>startCoroutine<!>(EmptyContinuation)
<!USAGE_IS_NOT_INLINABLE!>c<!>.startCoroutine(EmptyContinuation)
}
suspend fun calculate() = "OK"
@@ -24,7 +24,7 @@ suspend inline fun test(c: <!REDUNDANT_INLINE_SUSPEND_FUNCTION_TYPE!>suspend<!>
}
}
val l: suspend () -> Unit = { c() }
c.<!USAGE_IS_NOT_INLINABLE!>startCoroutine<!>(EmptyContinuation)
<!USAGE_IS_NOT_INLINABLE!>c<!>.startCoroutine(EmptyContinuation)
}
fun builder(c: suspend () -> Unit) {