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
This commit is contained in:
-1
@@ -1,6 +1,5 @@
|
||||
// IGNORE_BACKEND: JS_IR
|
||||
// IGNORE_BACKEND: NATIVE
|
||||
// IGNORE_BACKEND: JVM
|
||||
// WITH_COROUTINES
|
||||
// WITH_RUNTIME
|
||||
// COMMON_COROUTINES_TEST
|
||||
|
||||
+18
-2
@@ -23,13 +23,29 @@ final class InlineWithStateMachineKt$mainSuspend$1 {
|
||||
synthetic final method setLabel(p0: int): void
|
||||
}
|
||||
|
||||
@kotlin.Metadata
|
||||
public final class InlineWithStateMachineKt$suspendHere$1 {
|
||||
field L$0: java.lang.Object
|
||||
field L$1: java.lang.Object
|
||||
synthetic field data: java.lang.Object
|
||||
synthetic field exception: java.lang.Throwable
|
||||
inner class InlineWithStateMachineKt$suspendHere$1
|
||||
public method <init>(p0: COROUTINES_PACKAGE.Continuation): void
|
||||
public final @org.jetbrains.annotations.Nullable method doResume(@org.jetbrains.annotations.Nullable p0: java.lang.Object, @org.jetbrains.annotations.Nullable p1: java.lang.Throwable): java.lang.Object
|
||||
synthetic final method getLabel(): int
|
||||
synthetic final method setLabel(p0: int): void
|
||||
}
|
||||
|
||||
@kotlin.Metadata
|
||||
public final class InlineWithStateMachineKt {
|
||||
inner class InlineWithStateMachineKt$box$1
|
||||
inner class InlineWithStateMachineKt$mainSuspend$1
|
||||
inner class InlineWithStateMachineKt$suspendHere$1
|
||||
public final static @org.jetbrains.annotations.NotNull method box(): java.lang.String
|
||||
public final static method builder(@org.jetbrains.annotations.NotNull p0: kotlin.jvm.functions.Function1): void
|
||||
public final static @org.jetbrains.annotations.Nullable method mainSuspend(@org.jetbrains.annotations.NotNull p0: COROUTINES_PACKAGE.Continuation): java.lang.Object
|
||||
private final static method suspendHere(p0: COROUTINES_PACKAGE.Continuation): java.lang.Object
|
||||
private final static method suspendThere(p0: java.lang.String, p1: COROUTINES_PACKAGE.Continuation): java.lang.Object
|
||||
private final static @org.jetbrains.annotations.Nullable method suspendHere$$forInline(@org.jetbrains.annotations.NotNull p0: COROUTINES_PACKAGE.Continuation): java.lang.Object
|
||||
public final static @org.jetbrains.annotations.Nullable method suspendHere(@org.jetbrains.annotations.NotNull p0: COROUTINES_PACKAGE.Continuation): java.lang.Object
|
||||
private final static @org.jetbrains.annotations.Nullable method suspendThere$$forInline(@org.jetbrains.annotations.NotNull p0: java.lang.String, @org.jetbrains.annotations.NotNull p1: COROUTINES_PACKAGE.Continuation): java.lang.Object
|
||||
public final static @org.jetbrains.annotations.Nullable method suspendThere(@org.jetbrains.annotations.NotNull p0: java.lang.String, @org.jetbrains.annotations.NotNull p1: COROUTINES_PACKAGE.Continuation): java.lang.Object
|
||||
}
|
||||
|
||||
Vendored
+2
-1
@@ -31,5 +31,6 @@ public final class InlineWithoutStateMachineKt {
|
||||
public final static method builder(@org.jetbrains.annotations.NotNull p0: kotlin.jvm.functions.Function1): void
|
||||
public final static @org.jetbrains.annotations.Nullable method complexSuspend(@org.jetbrains.annotations.NotNull p0: COROUTINES_PACKAGE.Continuation): java.lang.Object
|
||||
public final static @org.jetbrains.annotations.Nullable method suspendHere(@org.jetbrains.annotations.NotNull p0: COROUTINES_PACKAGE.Continuation): java.lang.Object
|
||||
private final static method suspendThere(p0: java.lang.String, p1: COROUTINES_PACKAGE.Continuation): java.lang.Object
|
||||
private final static @org.jetbrains.annotations.Nullable method suspendThere$$forInline(@org.jetbrains.annotations.NotNull p0: java.lang.String, @org.jetbrains.annotations.NotNull p1: COROUTINES_PACKAGE.Continuation): java.lang.Object
|
||||
public final static @org.jetbrains.annotations.Nullable method suspendThere(@org.jetbrains.annotations.NotNull p0: java.lang.String, @org.jetbrains.annotations.NotNull p1: COROUTINES_PACKAGE.Continuation): java.lang.Object
|
||||
}
|
||||
|
||||
+71
@@ -0,0 +1,71 @@
|
||||
// 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
|
||||
}
|
||||
+69
@@ -0,0 +1,69 @@
|
||||
// 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) }
|
||||
}
|
||||
|
||||
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
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
// WITH_RUNTIME
|
||||
|
||||
suspend inline fun simple() {}
|
||||
|
||||
suspend inline fun <T> generic() {}
|
||||
|
||||
suspend inline fun <T, reified U> genericWithReified() {}
|
||||
|
||||
suspend inline fun Unit.simple() {}
|
||||
|
||||
suspend inline fun <T> T.generic() {}
|
||||
|
||||
suspend inline fun <T, reified U> T.genericWithReified() {}
|
||||
|
||||
@Suppress("INVISIBLE_MEMBER", "INVISIBLE_REFERENCE")
|
||||
@kotlin.internal.InlineOnly
|
||||
suspend inline fun shouldNotHaveSuffix() {}
|
||||
|
||||
suspend inline fun acceptsCrossinline(crossinline c: () -> Unit) {}
|
||||
|
||||
class Foo {
|
||||
suspend inline fun simple() {}
|
||||
|
||||
suspend inline fun <T> generic() {}
|
||||
|
||||
suspend inline fun <T, reified U> genericWithReified() {}
|
||||
|
||||
suspend inline fun Unit.simple() {}
|
||||
|
||||
suspend inline fun <T> T.generic() {}
|
||||
|
||||
suspend inline fun <T, reified U> T.genericWithReified() {}
|
||||
|
||||
@Suppress("INVISIBLE_MEMBER", "INVISIBLE_REFERENCE")
|
||||
@kotlin.internal.InlineOnly
|
||||
suspend inline fun shouldNotHaveSuffix() {}
|
||||
|
||||
suspend inline fun acceptsCrossinline(crossinline c: () -> Unit) {}
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
@kotlin.Metadata
|
||||
public final class Foo {
|
||||
public method <init>(): void
|
||||
private final method acceptsCrossinline(p0: kotlin.jvm.functions.Function0, p1: kotlin.coroutines.experimental.Continuation): java.lang.Object
|
||||
private final @org.jetbrains.annotations.Nullable method generic$$forInline(@org.jetbrains.annotations.NotNull p0: kotlin.coroutines.experimental.Continuation): java.lang.Object
|
||||
private final @org.jetbrains.annotations.Nullable method generic$$forInline(p0: java.lang.Object, @org.jetbrains.annotations.NotNull p1: kotlin.coroutines.experimental.Continuation): java.lang.Object
|
||||
public final @org.jetbrains.annotations.Nullable method generic(@org.jetbrains.annotations.NotNull p0: kotlin.coroutines.experimental.Continuation): java.lang.Object
|
||||
public final @org.jetbrains.annotations.Nullable method generic(p0: java.lang.Object, @org.jetbrains.annotations.NotNull p1: kotlin.coroutines.experimental.Continuation): java.lang.Object
|
||||
private final method genericWithReified(p0: java.lang.Object, p1: kotlin.coroutines.experimental.Continuation): java.lang.Object
|
||||
private final method genericWithReified(p0: kotlin.coroutines.experimental.Continuation): java.lang.Object
|
||||
private final @kotlin.internal.InlineOnly method shouldNotHaveSuffix(p0: kotlin.coroutines.experimental.Continuation): java.lang.Object
|
||||
private final @org.jetbrains.annotations.Nullable method simple$$forInline(@org.jetbrains.annotations.NotNull p0: kotlin.Unit, @org.jetbrains.annotations.NotNull p1: kotlin.coroutines.experimental.Continuation): java.lang.Object
|
||||
private final @org.jetbrains.annotations.Nullable method simple$$forInline(@org.jetbrains.annotations.NotNull p0: kotlin.coroutines.experimental.Continuation): java.lang.Object
|
||||
public final @org.jetbrains.annotations.Nullable method simple(@org.jetbrains.annotations.NotNull p0: kotlin.Unit, @org.jetbrains.annotations.NotNull p1: kotlin.coroutines.experimental.Continuation): java.lang.Object
|
||||
public final @org.jetbrains.annotations.Nullable method simple(@org.jetbrains.annotations.NotNull p0: kotlin.coroutines.experimental.Continuation): java.lang.Object
|
||||
}
|
||||
|
||||
@kotlin.Metadata
|
||||
public final class SimpleNamedKt {
|
||||
private final static method acceptsCrossinline(p0: kotlin.jvm.functions.Function0, p1: kotlin.coroutines.experimental.Continuation): java.lang.Object
|
||||
private final static @org.jetbrains.annotations.Nullable method generic$$forInline(@org.jetbrains.annotations.NotNull p0: kotlin.coroutines.experimental.Continuation): java.lang.Object
|
||||
private final static @org.jetbrains.annotations.Nullable method generic$$forInline(p0: java.lang.Object, @org.jetbrains.annotations.NotNull p1: kotlin.coroutines.experimental.Continuation): java.lang.Object
|
||||
public final static @org.jetbrains.annotations.Nullable method generic(@org.jetbrains.annotations.NotNull p0: kotlin.coroutines.experimental.Continuation): java.lang.Object
|
||||
public final static @org.jetbrains.annotations.Nullable method generic(p0: java.lang.Object, @org.jetbrains.annotations.NotNull p1: kotlin.coroutines.experimental.Continuation): java.lang.Object
|
||||
private final static method genericWithReified(p0: java.lang.Object, p1: kotlin.coroutines.experimental.Continuation): java.lang.Object
|
||||
private final static method genericWithReified(p0: kotlin.coroutines.experimental.Continuation): java.lang.Object
|
||||
private final static @kotlin.internal.InlineOnly method shouldNotHaveSuffix(p0: kotlin.coroutines.experimental.Continuation): java.lang.Object
|
||||
private final static @org.jetbrains.annotations.Nullable method simple$$forInline(@org.jetbrains.annotations.NotNull p0: kotlin.Unit, @org.jetbrains.annotations.NotNull p1: kotlin.coroutines.experimental.Continuation): java.lang.Object
|
||||
private final static @org.jetbrains.annotations.Nullable method simple$$forInline(@org.jetbrains.annotations.NotNull p0: kotlin.coroutines.experimental.Continuation): java.lang.Object
|
||||
public final static @org.jetbrains.annotations.Nullable method simple(@org.jetbrains.annotations.NotNull p0: kotlin.Unit, @org.jetbrains.annotations.NotNull p1: kotlin.coroutines.experimental.Continuation): java.lang.Object
|
||||
public final static @org.jetbrains.annotations.Nullable method simple(@org.jetbrains.annotations.NotNull p0: kotlin.coroutines.experimental.Continuation): java.lang.Object
|
||||
}
|
||||
Reference in New Issue
Block a user