Files
kotlin-fork/compiler/testData/codegen/boxInline/suspend/inlineUsedAsNoinline/inlineOnly.kt
T
Ilmir Usmanov 8a5ae16947 Generate separate methods for inline and noinline uses of inline suspend functions
Previously, inline suspend functions were effectively inline only,
but ordinary inline functions can be used as noinline.
To fix the issue, I generate two functions: one for inline with suffix
$$forInline and without state machine; and the other one without any
suffix and state machine for direct calls.
This change does not affect effectively inline only suspend functions,
i.e. functions with reified generics, annotated with @InlineOnly
annotation and functions with crossinline parameters.
 #KT-20219: Fixed
2018-06-13 15:08:19 +03:00

71 lines
1.6 KiB
Kotlin
Vendored

// FILE: inlined.kt
// WITH_RUNTIME
// NO_CHECK_LAMBDA_INLINING
import kotlin.coroutines.experimental.*
import kotlin.coroutines.experimental.intrinsics.*
var result = "FAIL"
var i = 0
var finished = false
var proceed: () -> Unit = {}
suspend fun suspendHere() = suspendCoroutine<Unit> {
i++
proceed = { it.resume(Unit) }
}
@Suppress("INVISIBLE_MEMBER", "INVISIBLE_REFERENCE")
@kotlin.internal.InlineOnly
inline suspend fun inlineMe() {
suspendHere()
suspendHere()
suspendHere()
suspendHere()
suspendHere()
}
// FILE: inlineSite.kt
import kotlin.coroutines.experimental.*
import kotlin.coroutines.experimental.intrinsics.*
fun builder(c: suspend () -> Unit) {
val continuation = object: Continuation<Unit> {
override val context: CoroutineContext
get() = EmptyCoroutineContext
override fun resume(value: Unit) {
proceed = {
result = "OK"
finished = true
}
}
override fun resumeWithException(exception: Throwable) {
throw exception
}
}
c.startCoroutine(continuation)
}
suspend fun inlineSite() {
inlineMe()
inlineMe()
}
fun box(): String {
builder {
inlineSite()
}
for (counter in 0 until 10) {
if (i != counter + 1) return "Expected ${counter + 1}, got $i"
proceed()
}
if (i != 10) return "FAIL $i"
if (finished) return "resume on root continuation is called"
proceed()
if (!finished) return "resume on root continuation is not called"
return result
}