diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/coroutines/CoroutineCodegen.kt b/compiler/backend/src/org/jetbrains/kotlin/codegen/coroutines/CoroutineCodegen.kt
index f6aff56026e..fcfe41aa36d 100644
--- a/compiler/backend/src/org/jetbrains/kotlin/codegen/coroutines/CoroutineCodegen.kt
+++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/coroutines/CoroutineCodegen.kt
@@ -475,7 +475,8 @@ class CoroutineCodegenForLambda private constructor(
shouldPreserveClassInitialization = constructorCallNormalizationMode.shouldPreserveClassInitialization,
containingClassInternalName = v.thisName,
isForNamedFunction = false,
- languageVersionSettings = languageVersionSettings
+ languageVersionSettings = languageVersionSettings,
+ disableTailCallOptimizationForFunctionReturningUnit = false
)
return if (forInline) AddEndLabelMethodVisitor(
MethodNodeCopyingMethodVisitor(
diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/coroutines/CoroutineTransformerMethodVisitor.kt b/compiler/backend/src/org/jetbrains/kotlin/codegen/coroutines/CoroutineTransformerMethodVisitor.kt
index 5f739b05b87..8d3e993dfe6 100644
--- a/compiler/backend/src/org/jetbrains/kotlin/codegen/coroutines/CoroutineTransformerMethodVisitor.kt
+++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/coroutines/CoroutineTransformerMethodVisitor.kt
@@ -63,6 +63,10 @@ class CoroutineTransformerMethodVisitor(
// These two are needed to report diagnostics about suspension points inside critical section
private val element: KtElement,
private val diagnostics: DiagnosticSink,
+ // Since tail-call optimization of functions with Unit return type relies on ability of call-site to recognize them,
+ // in order to ignore return value and push Unit, when we cannot ensure this ability, for example, when the function overrides function,
+ // returning Any, we need to disable tail-call optimization for these functions.
+ private val disableTailCallOptimizationForFunctionReturningUnit: Boolean,
// It's only matters for named functions, may differ from '!isStatic(access)' in case of DefaultImpls
private val needDispatchReceiver: Boolean = false,
// May differ from containingClassInternalName in case of DefaultImpls
@@ -111,7 +115,8 @@ class CoroutineTransformerMethodVisitor(
val examiner = MethodNodeExaminer(
languageVersionSettings,
containingClassInternalName,
- methodNode
+ methodNode,
+ disableTailCallOptimizationForFunctionReturningUnit
)
if (examiner.allSuspensionPointsAreTailCalls(suspensionPoints)) {
examiner.replacePopsBeforeSafeUnitInstancesWithCoroutineSuspendedChecks()
@@ -899,7 +904,8 @@ class CoroutineTransformerMethodVisitor(
private class MethodNodeExaminer(
val languageVersionSettings: LanguageVersionSettings,
val containingClassInternalName: String,
- val methodNode: MethodNode
+ val methodNode: MethodNode,
+ disableTailCallOptimizationForFunctionReturningUnit: Boolean
) {
private val sourceFrames: Array?> =
MethodTransformer.analyze(containingClassInternalName, methodNode, IgnoringCopyOperationSourceInterpreter())
@@ -912,25 +918,27 @@ private class MethodNodeExaminer(
private val meaningfulPredecessorsCache = hashMapOf>()
init {
- // retrieve all POP insns
- val pops = methodNode.instructions.asSequence().filter { it.opcode == Opcodes.POP }
- // for each of them check that all successors are PUSH Unit
- val popsBeforeUnitInstances = pops.map { it to it.meaningfulSuccessors() }
- .filter { (_, succs) -> succs.all { it.isUnitInstance() } }
- .map { it.first }.toList()
- for (pop in popsBeforeUnitInstances) {
- val units = pop.meaningfulSuccessors()
- val allUnitsAreSafe = units.all { unit ->
- // check no other predecessor exists
- unit.meaningfulPredecessors().all { it in popsBeforeUnitInstances } &&
- // check they have only returns among successors
- unit.meaningfulSuccessors().all { it.opcode == Opcodes.ARETURN }
+ if (!disableTailCallOptimizationForFunctionReturningUnit) {
+ // retrieve all POP insns
+ val pops = methodNode.instructions.asSequence().filter { it.opcode == Opcodes.POP }
+ // for each of them check that all successors are PUSH Unit
+ val popsBeforeUnitInstances = pops.map { it to it.meaningfulSuccessors() }
+ .filter { (_, succs) -> succs.all { it.isUnitInstance() } }
+ .map { it.first }.toList()
+ for (pop in popsBeforeUnitInstances) {
+ val units = pop.meaningfulSuccessors()
+ val allUnitsAreSafe = units.all { unit ->
+ // check no other predecessor exists
+ unit.meaningfulPredecessors().all { it in popsBeforeUnitInstances } &&
+ // check they have only returns among successors
+ unit.meaningfulSuccessors().all { it.opcode == Opcodes.ARETURN }
+ }
+ if (!allUnitsAreSafe) continue
+ // save them all to the properties
+ popsBeforeSafeUnitInstances += pop
+ safeUnitInstances += units
+ units.flatMapTo(areturnsAfterSafeUnitInstances) { it.meaningfulSuccessors() }
}
- if (!allUnitsAreSafe) continue
- // save them all to the properties
- popsBeforeSafeUnitInstances += pop
- safeUnitInstances += units
- units.flatMapTo(areturnsAfterSafeUnitInstances) { it.meaningfulSuccessors() }
}
}
diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/coroutines/SuspendFunctionGenerationStrategy.kt b/compiler/backend/src/org/jetbrains/kotlin/codegen/coroutines/SuspendFunctionGenerationStrategy.kt
index e557003142f..e8ff4783de7 100644
--- a/compiler/backend/src/org/jetbrains/kotlin/codegen/coroutines/SuspendFunctionGenerationStrategy.kt
+++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/coroutines/SuspendFunctionGenerationStrategy.kt
@@ -19,6 +19,7 @@ import org.jetbrains.kotlin.psi.KtFunction
import org.jetbrains.kotlin.psi.psiUtil.getElementTextWithContext
import org.jetbrains.kotlin.resolve.jvm.diagnostics.OtherOrigin
import org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodSignature
+import org.jetbrains.kotlin.types.typeUtil.isUnit
import org.jetbrains.kotlin.utils.addToStdlib.safeAs
import org.jetbrains.kotlin.utils.sure
import org.jetbrains.org.objectweb.asm.MethodVisitor
@@ -100,10 +101,27 @@ open class SuspendFunctionGenerationStrategy(
shouldPreserveClassInitialization = constructorCallNormalizationMode.shouldPreserveClassInitialization,
needDispatchReceiver = originalSuspendDescriptor.dispatchReceiverParameter != null,
internalNameForDispatchReceiver = containingClassInternalNameOrNull(),
- languageVersionSettings = languageVersionSettings
+ languageVersionSettings = languageVersionSettings,
+ disableTailCallOptimizationForFunctionReturningUnit = originalSuspendDescriptor.returnType?.isUnit() == true &&
+ originalSuspendDescriptor.overriddenDescriptors.isNotEmpty() &&
+ !originalSuspendDescriptor.allOverriddenFunctionsReturnUnit()
)
}
+ private fun FunctionDescriptor.allOverriddenFunctionsReturnUnit(): Boolean {
+ val visited = mutableSetOf()
+
+ fun bfs(descriptor: FunctionDescriptor): Boolean {
+ if (!visited.add(descriptor)) return true
+ if (descriptor.original.returnType?.isUnit() != true) return false
+ for (parent in descriptor.overriddenDescriptors) {
+ if (!bfs(parent)) return false
+ }
+ return true
+ }
+ return bfs(this)
+ }
+
private fun containingClassInternalNameOrNull() =
originalSuspendDescriptor.containingDeclaration.safeAs()?.let(state.typeMapper::mapClass)?.internalName
diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/coroutines/CoroutineTransformer.kt b/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/coroutines/CoroutineTransformer.kt
index bceae4fe982..103f4aa0a8c 100644
--- a/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/coroutines/CoroutineTransformer.kt
+++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/coroutines/CoroutineTransformer.kt
@@ -17,11 +17,20 @@ import org.jetbrains.kotlin.codegen.optimization.transformer.MethodTransformer
import org.jetbrains.kotlin.config.isReleaseCoroutines
import org.jetbrains.kotlin.descriptors.ClassDescriptor
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
+import org.jetbrains.kotlin.load.java.JvmAnnotationNames
+import org.jetbrains.kotlin.load.kotlin.FileBasedKotlinClass
+import org.jetbrains.kotlin.load.kotlin.header.KotlinClassHeader
+import org.jetbrains.kotlin.load.kotlin.header.ReadKotlinClassHeaderAnnotationVisitor
+import org.jetbrains.kotlin.metadata.ProtoBuf
+import org.jetbrains.kotlin.metadata.deserialization.*
+import org.jetbrains.kotlin.metadata.jvm.deserialization.JvmProtoBufUtil
+import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.psi.KtElement
import org.jetbrains.kotlin.resolve.jvm.diagnostics.JvmDeclarationOrigin
+import org.jetbrains.kotlin.serialization.deserialization.getClassId
+import org.jetbrains.kotlin.serialization.deserialization.getName
import org.jetbrains.kotlin.utils.addToStdlib.cast
-import org.jetbrains.org.objectweb.asm.MethodVisitor
-import org.jetbrains.org.objectweb.asm.Opcodes
+import org.jetbrains.org.objectweb.asm.*
import org.jetbrains.org.objectweb.asm.tree.*
import org.jetbrains.org.objectweb.asm.tree.analysis.Frame
import org.jetbrains.org.objectweb.asm.tree.analysis.SourceInterpreter
@@ -108,7 +117,8 @@ class CoroutineTransformer(
languageVersionSettings = state.languageVersionSettings,
shouldPreserveClassInitialization = state.constructorCallNormalizationMode.shouldPreserveClassInitialization,
containingClassInternalName = classBuilder.thisName,
- isForNamedFunction = false
+ isForNamedFunction = false,
+ disableTailCallOptimizationForFunctionReturningUnit = false
)
)
@@ -137,6 +147,8 @@ class CoroutineTransformer(
ArrayUtil.toStringArray(node.exceptions)
)
) {
+ // If the node already has state-machine, it is safer to generate state-machine.
+ val disableTailCallOptimization = methods.find { it.name == name && it.desc == node.desc }?.let { isStateMachine(it) } ?: false
val stateMachineBuilder = surroundNoinlineCallsWithMarkers(
node,
CoroutineTransformerMethodVisitor(
@@ -149,7 +161,8 @@ class CoroutineTransformer(
containingClassInternalName = classBuilder.thisName,
isForNamedFunction = true,
needDispatchReceiver = true,
- internalNameForDispatchReceiver = classBuilder.thisName
+ internalNameForDispatchReceiver = classBuilder.thisName,
+ disableTailCallOptimizationForFunctionReturningUnit = disableTailCallOptimization
)
)
diff --git a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/codegen/CoroutineCodegen.kt b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/codegen/CoroutineCodegen.kt
index 3881a944104..a17c1f04954 100644
--- a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/codegen/CoroutineCodegen.kt
+++ b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/codegen/CoroutineCodegen.kt
@@ -32,6 +32,7 @@ import org.jetbrains.kotlin.ir.expressions.impl.IrGetValueImpl
import org.jetbrains.kotlin.ir.symbols.impl.IrSimpleFunctionSymbolImpl
import org.jetbrains.kotlin.ir.types.createType
import org.jetbrains.kotlin.ir.types.impl.makeTypeProjection
+import org.jetbrains.kotlin.ir.types.isUnit
import org.jetbrains.kotlin.ir.util.*
import org.jetbrains.kotlin.ir.visitors.IrElementTransformerVoid
import org.jetbrains.kotlin.ir.visitors.transformChildrenVoid
@@ -40,6 +41,7 @@ import org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodGenericSignature
import org.jetbrains.kotlin.serialization.deserialization.descriptors.DescriptorWithContainerSource
import org.jetbrains.kotlin.types.Variance
import org.jetbrains.org.objectweb.asm.MethodVisitor
+import org.jetbrains.org.objectweb.asm.Opcodes
internal fun generateStateMachineForNamedFunction(
irFunction: IrFunction,
@@ -58,7 +60,7 @@ internal fun generateStateMachineForNamedFunction(
val languageVersionSettings = state.languageVersionSettings
assert(languageVersionSettings.isReleaseCoroutines()) { "Experimental coroutines are unsupported in JVM_IR backend" }
return CoroutineTransformerMethodVisitor(
- methodVisitor, access, signature.asmMethod.name, signature.asmMethod.descriptor, null, null,
+ methodVisitor, access, signature.asmMethod.name, signature.asmMethod.descriptor, signature.genericsSignature, null,
obtainClassBuilderForCoroutineState = { continuationClassBuilder!! },
element = element,
diagnostics = state.diagnostics,
@@ -69,7 +71,11 @@ internal fun generateStateMachineForNamedFunction(
needDispatchReceiver = irFunction.dispatchReceiverParameter != null
|| irFunction.origin == JvmLoweredDeclarationOrigin.SUSPEND_IMPL_STATIC_FUNCTION,
internalNameForDispatchReceiver = classCodegen.visitor.thisName,
- putContinuationParameterToLvt = false
+ putContinuationParameterToLvt = false,
+ disableTailCallOptimizationForFunctionReturningUnit = irFunction.returnType.isUnit() &&
+ (irFunction as? IrSimpleFunction)?.overriddenSymbols?.let { symbols ->
+ symbols.isNotEmpty() && symbols.any { !it.owner.returnType.isUnit() }
+ } == true
)
}
@@ -84,14 +90,15 @@ internal fun generateStateMachineForLambda(
val languageVersionSettings = state.languageVersionSettings
assert(languageVersionSettings.isReleaseCoroutines()) { "Experimental coroutines are unsupported in JVM_IR backend" }
return CoroutineTransformerMethodVisitor(
- methodVisitor, access, signature.asmMethod.name, signature.asmMethod.descriptor, null, null,
+ methodVisitor, access, signature.asmMethod.name, signature.asmMethod.descriptor, signature.genericsSignature, null,
obtainClassBuilderForCoroutineState = { classCodegen.visitor },
element = element,
diagnostics = state.diagnostics,
languageVersionSettings = languageVersionSettings,
shouldPreserveClassInitialization = state.constructorCallNormalizationMode.shouldPreserveClassInitialization,
containingClassInternalName = classCodegen.visitor.thisName,
- isForNamedFunction = false
+ isForNamedFunction = false,
+ disableTailCallOptimizationForFunctionReturningUnit = false
)
}
diff --git a/compiler/testData/codegen/box/coroutines/tailCallOptimizations/unit/override.kt b/compiler/testData/codegen/box/coroutines/tailCallOptimizations/unit/override.kt
new file mode 100644
index 00000000000..e70a8df6413
--- /dev/null
+++ b/compiler/testData/codegen/box/coroutines/tailCallOptimizations/unit/override.kt
@@ -0,0 +1,42 @@
+// IGNORE_BACKEND_FIR: JVM_IR
+// TARGET_BACKEND: JVM
+// IGNORE_BACKEND: JVM_IR
+// FULL_JDK
+// WITH_RUNTIME
+// WITH_COROUTINES
+
+import helpers.*
+import kotlin.coroutines.*
+
+var c: Continuation<*>? = null
+
+suspend fun tx(lambda: () -> T): T = suspendCoroutine { c = it; lambda() }
+
+object Dummy
+
+interface Base {
+ suspend fun generic(): T
+}
+
+class Derived: Base {
+ override suspend fun generic(): Unit {
+ tx { Dummy }
+ }
+}
+
+fun builder(c: suspend () -> Unit) {
+ c.startCoroutine(EmptyContinuation)
+}
+
+fun box(): String {
+ var res: Any? = null
+
+ builder {
+ val base: Base<*> = Derived()
+ res = base.generic()
+ }
+
+ (c as? Continuation)?.resume(Dummy)
+
+ return if (res != Unit) "$res" else "OK"
+}
diff --git a/compiler/testData/codegen/box/coroutines/tailCallOptimizations/unit/override2.kt b/compiler/testData/codegen/box/coroutines/tailCallOptimizations/unit/override2.kt
new file mode 100644
index 00000000000..4a18e1c9b4d
--- /dev/null
+++ b/compiler/testData/codegen/box/coroutines/tailCallOptimizations/unit/override2.kt
@@ -0,0 +1,44 @@
+// IGNORE_BACKEND_FIR: JVM_IR
+// TARGET_BACKEND: JVM
+// IGNORE_BACKEND: JVM_IR
+// FULL_JDK
+// WITH_RUNTIME
+// WITH_COROUTINES
+
+import helpers.*
+import kotlin.coroutines.*
+
+var c: Continuation<*>? = null
+
+suspend fun tx(lambda: () -> T): T = suspendCoroutine { c = it; lambda() }
+
+object Dummy
+
+interface Base {
+ suspend fun generic(): T
+}
+
+abstract class Derived1: Base {
+}
+
+class Derived2: Derived1() {
+ override suspend fun generic(): Unit {
+ tx { Dummy }
+ }
+}
+fun builder(c: suspend () -> Unit) {
+ c.startCoroutine(EmptyContinuation)
+}
+
+fun box(): String {
+ var res: Any? = null
+
+ builder {
+ val base: Base<*> = Derived2()
+ res = base.generic()
+ }
+
+ (c as? Continuation)?.resume(Dummy)
+
+ return if (res != Unit) "$res" else "OK"
+}
diff --git a/compiler/testData/codegen/box/coroutines/tailCallOptimizations/unit/override3.kt b/compiler/testData/codegen/box/coroutines/tailCallOptimizations/unit/override3.kt
new file mode 100644
index 00000000000..948463c0100
--- /dev/null
+++ b/compiler/testData/codegen/box/coroutines/tailCallOptimizations/unit/override3.kt
@@ -0,0 +1,46 @@
+// IGNORE_BACKEND_FIR: JVM_IR
+// TARGET_BACKEND: JVM
+// IGNORE_BACKEND: JVM_IR
+// FULL_JDK
+// WITH_RUNTIME
+// WITH_COROUTINES
+
+import helpers.*
+import kotlin.coroutines.*
+
+var c: Continuation<*>? = null
+
+suspend fun tx(lambda: () -> T): T = suspendCoroutine { c = it; lambda() }
+
+object Dummy
+
+interface Foo {
+ suspend fun generic(): Any
+}
+
+interface Base {
+ suspend fun generic(): Unit
+}
+
+class Derived: Base, Foo {
+ override suspend fun generic(): Unit {
+ tx { Dummy }
+ }
+}
+
+fun builder(c: suspend () -> Unit) {
+ c.startCoroutine(EmptyContinuation)
+}
+
+fun box(): String {
+ var res: Any? = null
+
+ builder {
+ val foo: Foo = Derived()
+ res = foo.generic()
+ }
+
+ (c as? Continuation)?.resume(Dummy)
+
+ return if (res != Unit) "$res" else "OK"
+}
diff --git a/compiler/testData/codegen/box/coroutines/tailCallOptimizations/unit/override4.kt b/compiler/testData/codegen/box/coroutines/tailCallOptimizations/unit/override4.kt
new file mode 100644
index 00000000000..7a53634ef7d
--- /dev/null
+++ b/compiler/testData/codegen/box/coroutines/tailCallOptimizations/unit/override4.kt
@@ -0,0 +1,40 @@
+// IGNORE_BACKEND_FIR: JVM_IR
+// TARGET_BACKEND: JVM
+// IGNORE_BACKEND: JVM_IR
+// FULL_JDK
+// WITH_RUNTIME
+// WITH_COROUTINES
+// CHECK_TAIL_CALL_OPTIMIZATION
+
+import helpers.*
+import kotlin.coroutines.*
+
+var c: Continuation<*>? = null
+
+suspend fun suspendHere() = TailCallOptimizationChecker.saveStackTrace()
+
+interface Base {
+ suspend fun generic(): T
+}
+
+inline fun inlineMe(crossinline c: suspend () -> Unit) = object : Base {
+ override suspend fun generic(): Unit {
+ c()
+ suspendHere()
+ }
+}
+
+fun builder(c: suspend () -> Unit) {
+ c.startCoroutine(EmptyContinuation)
+}
+
+fun box(): String {
+ builder {
+ inlineMe { }.generic()
+ }
+
+ // TODO: There should be no state-machine. Should fix in IR_BE
+ TailCallOptimizationChecker.checkStateMachineIn("generic")
+
+ return "OK"
+}
diff --git a/compiler/testData/codegen/box/coroutines/tailCallOptimizations/unit/override5.kt b/compiler/testData/codegen/box/coroutines/tailCallOptimizations/unit/override5.kt
new file mode 100644
index 00000000000..c9bd9c70e1f
--- /dev/null
+++ b/compiler/testData/codegen/box/coroutines/tailCallOptimizations/unit/override5.kt
@@ -0,0 +1,35 @@
+// IGNORE_BACKEND_FIR: JVM_IR
+// TARGET_BACKEND: JVM
+// IGNORE_BACKEND: JVM_IR
+// FULL_JDK
+// WITH_RUNTIME
+// WITH_COROUTINES
+// CHECK_BYTECODE_LISTING
+
+import helpers.*
+import kotlin.coroutines.*
+
+var c: Continuation<*>? = null
+
+interface Base {
+ suspend fun generic(): T
+}
+
+inline fun inlineMe(crossinline c: suspend () -> Unit) = object : Base {
+ override suspend fun generic(): Unit {
+ c();
+ {}()
+ }
+}
+
+fun builder(c: suspend () -> Unit) {
+ c.startCoroutine(EmptyContinuation)
+}
+
+fun box(): String {
+ builder {
+ inlineMe { }.generic()
+ }
+
+ return "OK"
+}
diff --git a/compiler/testData/codegen/box/coroutines/tailCallOptimizations/unit/override5.txt b/compiler/testData/codegen/box/coroutines/tailCallOptimizations/unit/override5.txt
new file mode 100644
index 00000000000..f72b5f9bcf7
--- /dev/null
+++ b/compiler/testData/codegen/box/coroutines/tailCallOptimizations/unit/override5.txt
@@ -0,0 +1,70 @@
+@kotlin.Metadata
+public interface Base {
+ public abstract @org.jetbrains.annotations.Nullable method generic(@org.jetbrains.annotations.NotNull p0: kotlin.coroutines.Continuation): java.lang.Object
+}
+
+@kotlin.Metadata
+public final class Override5Kt$box$1$invokeSuspend$$inlined$inlineMe$1 {
+ inner class Override5Kt$box$1$invokeSuspend$$inlined$inlineMe$1
+ inner class Override5Kt$inlineMe$1$generic$2
+ public method (): void
+ public @org.jetbrains.annotations.Nullable method generic(@org.jetbrains.annotations.NotNull p0: kotlin.coroutines.Continuation): java.lang.Object
+}
+
+@kotlin.coroutines.jvm.internal.DebugMetadata
+@kotlin.Metadata
+final class Override5Kt$box$1 {
+ field label: int
+ inner class Override5Kt$box$1
+ method (p0: kotlin.coroutines.Continuation): void
+ public final @org.jetbrains.annotations.NotNull method create(@org.jetbrains.annotations.NotNull p0: kotlin.coroutines.Continuation): kotlin.coroutines.Continuation
+ public final method invoke(p0: java.lang.Object): java.lang.Object
+ public final @org.jetbrains.annotations.Nullable method invokeSuspend(@org.jetbrains.annotations.NotNull p0: java.lang.Object): java.lang.Object
+}
+
+@kotlin.Metadata
+@kotlin.coroutines.jvm.internal.DebugMetadata
+public final class Override5Kt$inlineMe$1$generic$1 {
+ field L$0: java.lang.Object
+ field label: int
+ synthetic field result: java.lang.Object
+ synthetic final field this$0: Override5Kt$inlineMe$1
+ inner class Override5Kt$inlineMe$1
+ inner class Override5Kt$inlineMe$1$generic$1
+ public method (p0: Override5Kt$inlineMe$1, p1: kotlin.coroutines.Continuation): void
+ public final @org.jetbrains.annotations.Nullable method invokeSuspend(@org.jetbrains.annotations.NotNull p0: java.lang.Object): java.lang.Object
+}
+
+@kotlin.Metadata
+public final class Override5Kt$inlineMe$1$generic$2 {
+ public final static field INSTANCE: Override5Kt$inlineMe$1$generic$2
+ inner class Override5Kt$inlineMe$1
+ inner class Override5Kt$inlineMe$1$generic$2
+ static method (): void
+ public method (): void
+ public synthetic method invoke(): java.lang.Object
+ public final method invoke(): void
+}
+
+@kotlin.Metadata
+public final class Override5Kt$inlineMe$1 {
+ synthetic final field $c: kotlin.jvm.functions.Function1
+ inner class Override5Kt$inlineMe$1
+ inner class Override5Kt$inlineMe$1$generic$1
+ inner class Override5Kt$inlineMe$1$generic$2
+ public method (p0: kotlin.jvm.functions.Function1): void
+ public @org.jetbrains.annotations.Nullable method generic$$forInline(@org.jetbrains.annotations.NotNull p0: kotlin.coroutines.Continuation): java.lang.Object
+ public @org.jetbrains.annotations.Nullable method generic(@org.jetbrains.annotations.NotNull p0: kotlin.coroutines.Continuation): java.lang.Object
+}
+
+@kotlin.Metadata
+public final class Override5Kt {
+ private static @org.jetbrains.annotations.Nullable field c: kotlin.coroutines.Continuation
+ inner class Override5Kt$box$1
+ inner class Override5Kt$inlineMe$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 getC(): kotlin.coroutines.Continuation
+ public final static @org.jetbrains.annotations.NotNull method inlineMe(@org.jetbrains.annotations.NotNull p0: kotlin.jvm.functions.Function1): Base
+ public final static method setC(@org.jetbrains.annotations.Nullable p0: kotlin.coroutines.Continuation): void
+}
diff --git a/compiler/testData/codegen/box/coroutines/tailCallOptimizations/unit/override6.kt b/compiler/testData/codegen/box/coroutines/tailCallOptimizations/unit/override6.kt
new file mode 100644
index 00000000000..ecae95eb9a6
--- /dev/null
+++ b/compiler/testData/codegen/box/coroutines/tailCallOptimizations/unit/override6.kt
@@ -0,0 +1,38 @@
+// IGNORE_BACKEND_FIR: JVM_IR
+// TARGET_BACKEND: JVM
+// IGNORE_BACKEND: JVM_IR
+// FULL_JDK
+// WITH_RUNTIME
+// WITH_COROUTINES
+// CHECK_TAIL_CALL_OPTIMIZATION
+
+import helpers.*
+import kotlin.coroutines.*
+
+var c: Continuation<*>? = null
+
+suspend fun suspendHere() = TailCallOptimizationChecker.saveStackTrace()
+
+interface Base {
+ suspend fun generic(): T
+}
+
+inline fun inlineMe(crossinline c: suspend () -> Unit) = object : Base {
+ override suspend fun generic(): Unit {
+ c()
+ }
+}
+
+fun builder(c: suspend () -> Unit) {
+ c.startCoroutine(EmptyContinuation)
+}
+
+fun box(): String {
+ builder {
+ inlineMe { suspendHere() }.generic()
+ }
+
+ TailCallOptimizationChecker.checkStateMachineIn("generic")
+
+ return "OK"
+}
diff --git a/compiler/testData/codegen/box/coroutines/tailCallOptimizations/unit/overrideCrossinline.kt b/compiler/testData/codegen/box/coroutines/tailCallOptimizations/unit/overrideCrossinline.kt
new file mode 100644
index 00000000000..469541625b6
--- /dev/null
+++ b/compiler/testData/codegen/box/coroutines/tailCallOptimizations/unit/overrideCrossinline.kt
@@ -0,0 +1,53 @@
+// IGNORE_BACKEND_FIR: JVM_IR
+// TARGET_BACKEND: JVM
+// IGNORE_BACKEND: JVM_IR
+// FULL_JDK
+// WITH_RUNTIME
+// WITH_COROUTINES
+
+import helpers.*
+import kotlin.coroutines.*
+
+var c: Continuation<*>? = null
+
+suspend fun tx(lambda: () -> T): T = suspendCoroutine { c = it; lambda() }
+
+object Dummy
+
+interface Base {
+ suspend fun callMe(a: IntArray): Unit
+ suspend fun callMe(s: String): Unit
+ suspend fun callMe(a: Array): Unit
+ suspend fun callMe(a: Int): T
+}
+
+inline fun inlineMe(crossinline c: suspend () -> Unit): Base<*> {
+ return object: Base {
+ override suspend fun callMe(a: IntArray) {}
+
+ override suspend fun callMe(a: Int): Unit {
+ c()
+ }
+
+ override suspend fun callMe(s: String) {}
+ override suspend fun callMe(a: Array) {}
+ }
+}
+
+fun builder(c: suspend () -> Unit) {
+ c.startCoroutine(EmptyContinuation)
+}
+
+fun box(): String {
+ var res: Any? = null
+
+ builder {
+ res = inlineMe {
+ tx { Dummy }
+ }.callMe(1)
+ }
+
+ (c as? Continuation)?.resume(Dummy)
+
+ return if (res != Unit) "$res" else "OK"
+}
diff --git a/compiler/testData/codegen/box/coroutines/tailCallOptimizations/unit/overrideOverriden.kt b/compiler/testData/codegen/box/coroutines/tailCallOptimizations/unit/overrideOverriden.kt
new file mode 100644
index 00000000000..5bf9d302cdc
--- /dev/null
+++ b/compiler/testData/codegen/box/coroutines/tailCallOptimizations/unit/overrideOverriden.kt
@@ -0,0 +1,45 @@
+// IGNORE_BACKEND_FIR: JVM_IR
+// TARGET_BACKEND: JVM
+// IGNORE_BACKEND: JVM_IR
+// FULL_JDK
+// WITH_RUNTIME
+// WITH_COROUTINES
+
+import helpers.*
+import kotlin.coroutines.*
+
+var c: Continuation<*>? = null
+
+suspend fun tx(lambda: () -> T): T = suspendCoroutine { c = it; lambda() }
+
+object Dummy
+
+interface Base {
+ suspend fun generic(): T
+}
+
+open class Derived1: Base {
+ override suspend fun generic() {}
+}
+
+class Derived2: Derived1() {
+ override suspend fun generic(): Unit {
+ tx { Dummy }
+ }
+}
+fun builder(c: suspend () -> Unit) {
+ c.startCoroutine(EmptyContinuation)
+}
+
+fun box(): String {
+ var res: Any? = null
+
+ builder {
+ val base: Base<*> = Derived2()
+ res = base.generic()
+ }
+
+ (c as? Continuation)?.resume(Dummy)
+
+ return if (res != Unit) "$res" else "OK"
+}
diff --git a/compiler/testData/codegen/box/coroutines/tailCallOptimizations/unitFunReturnsNonUnitCallSuspend.kt b/compiler/testData/codegen/box/coroutines/tailCallOptimizations/unit/reflection.kt
similarity index 100%
rename from compiler/testData/codegen/box/coroutines/tailCallOptimizations/unitFunReturnsNonUnitCallSuspend.kt
rename to compiler/testData/codegen/box/coroutines/tailCallOptimizations/unit/reflection.kt
diff --git a/compiler/testData/codegen/box/coroutines/tailCallOptimizations/unitFunReturnsNonUnit.kt b/compiler/testData/codegen/box/coroutines/tailCallOptimizations/unit/simple.kt
similarity index 100%
rename from compiler/testData/codegen/box/coroutines/tailCallOptimizations/unitFunReturnsNonUnit.kt
rename to compiler/testData/codegen/box/coroutines/tailCallOptimizations/unit/simple.kt
diff --git a/compiler/tests/org/jetbrains/kotlin/codegen/BlackBoxCodegenTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/codegen/BlackBoxCodegenTestGenerated.java
index 3bdfa9f0713..1eb5937c45b 100644
--- a/compiler/tests/org/jetbrains/kotlin/codegen/BlackBoxCodegenTestGenerated.java
+++ b/compiler/tests/org/jetbrains/kotlin/codegen/BlackBoxCodegenTestGenerated.java
@@ -8549,16 +8549,6 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest {
runTestWithPackageReplacement("compiler/testData/codegen/box/coroutines/tailCallOptimizations/tryCatch.kt", "kotlin.coroutines");
}
- @TestMetadata("unitFunReturnsNonUnit.kt")
- public void testUnitFunReturnsNonUnit() throws Exception {
- runTest("compiler/testData/codegen/box/coroutines/tailCallOptimizations/unitFunReturnsNonUnit.kt");
- }
-
- @TestMetadata("unitFunReturnsNonUnitCallSuspend.kt")
- public void testUnitFunReturnsNonUnitCallSuspend() throws Exception {
- runTest("compiler/testData/codegen/box/coroutines/tailCallOptimizations/unitFunReturnsNonUnitCallSuspend.kt");
- }
-
@TestMetadata("unreachable.kt")
public void testUnreachable() throws Exception {
runTest("compiler/testData/codegen/box/coroutines/tailCallOptimizations/unreachable.kt");
@@ -8568,6 +8558,69 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest {
public void testWhenUnit() throws Exception {
runTest("compiler/testData/codegen/box/coroutines/tailCallOptimizations/whenUnit.kt");
}
+
+ @TestMetadata("compiler/testData/codegen/box/coroutines/tailCallOptimizations/unit")
+ @TestDataPath("$PROJECT_ROOT")
+ @RunWith(JUnit3RunnerWithInners.class)
+ public static class Unit extends AbstractBlackBoxCodegenTest {
+ private void runTest(String testDataFilePath) throws Exception {
+ KotlinTestUtils.runTest(this::doTest, TargetBackend.JVM, testDataFilePath);
+ }
+
+ public void testAllFilesPresentInUnit() throws Exception {
+ KotlinTestUtils.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/box/coroutines/tailCallOptimizations/unit"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JVM, true);
+ }
+
+ @TestMetadata("override.kt")
+ public void testOverride() throws Exception {
+ runTest("compiler/testData/codegen/box/coroutines/tailCallOptimizations/unit/override.kt");
+ }
+
+ @TestMetadata("override2.kt")
+ public void testOverride2() throws Exception {
+ runTest("compiler/testData/codegen/box/coroutines/tailCallOptimizations/unit/override2.kt");
+ }
+
+ @TestMetadata("override3.kt")
+ public void testOverride3() throws Exception {
+ runTest("compiler/testData/codegen/box/coroutines/tailCallOptimizations/unit/override3.kt");
+ }
+
+ @TestMetadata("override4.kt")
+ public void testOverride4() throws Exception {
+ runTest("compiler/testData/codegen/box/coroutines/tailCallOptimizations/unit/override4.kt");
+ }
+
+ @TestMetadata("override5.kt")
+ public void testOverride5() throws Exception {
+ runTest("compiler/testData/codegen/box/coroutines/tailCallOptimizations/unit/override5.kt");
+ }
+
+ @TestMetadata("override6.kt")
+ public void testOverride6() throws Exception {
+ runTest("compiler/testData/codegen/box/coroutines/tailCallOptimizations/unit/override6.kt");
+ }
+
+ @TestMetadata("overrideCrossinline.kt")
+ public void testOverrideCrossinline() throws Exception {
+ runTest("compiler/testData/codegen/box/coroutines/tailCallOptimizations/unit/overrideCrossinline.kt");
+ }
+
+ @TestMetadata("overrideOverriden.kt")
+ public void testOverrideOverriden() throws Exception {
+ runTest("compiler/testData/codegen/box/coroutines/tailCallOptimizations/unit/overrideOverriden.kt");
+ }
+
+ @TestMetadata("reflection.kt")
+ public void testReflection() throws Exception {
+ runTest("compiler/testData/codegen/box/coroutines/tailCallOptimizations/unit/reflection.kt");
+ }
+
+ @TestMetadata("simple.kt")
+ public void testSimple() throws Exception {
+ runTest("compiler/testData/codegen/box/coroutines/tailCallOptimizations/unit/simple.kt");
+ }
+ }
}
@TestMetadata("compiler/testData/codegen/box/coroutines/tailOperations")
diff --git a/compiler/tests/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java
index 1acd241c1a3..8e30108a1ca 100644
--- a/compiler/tests/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java
+++ b/compiler/tests/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java
@@ -8549,16 +8549,6 @@ public class LightAnalysisModeTestGenerated extends AbstractLightAnalysisModeTes
runTestWithPackageReplacement("compiler/testData/codegen/box/coroutines/tailCallOptimizations/tryCatch.kt", "kotlin.coroutines");
}
- @TestMetadata("unitFunReturnsNonUnit.kt")
- public void testUnitFunReturnsNonUnit() throws Exception {
- runTest("compiler/testData/codegen/box/coroutines/tailCallOptimizations/unitFunReturnsNonUnit.kt");
- }
-
- @TestMetadata("unitFunReturnsNonUnitCallSuspend.kt")
- public void testUnitFunReturnsNonUnitCallSuspend() throws Exception {
- runTest("compiler/testData/codegen/box/coroutines/tailCallOptimizations/unitFunReturnsNonUnitCallSuspend.kt");
- }
-
@TestMetadata("unreachable.kt")
public void testUnreachable() throws Exception {
runTest("compiler/testData/codegen/box/coroutines/tailCallOptimizations/unreachable.kt");
@@ -8568,6 +8558,69 @@ public class LightAnalysisModeTestGenerated extends AbstractLightAnalysisModeTes
public void testWhenUnit() throws Exception {
runTest("compiler/testData/codegen/box/coroutines/tailCallOptimizations/whenUnit.kt");
}
+
+ @TestMetadata("compiler/testData/codegen/box/coroutines/tailCallOptimizations/unit")
+ @TestDataPath("$PROJECT_ROOT")
+ @RunWith(JUnit3RunnerWithInners.class)
+ public static class Unit extends AbstractLightAnalysisModeTest {
+ private void runTest(String testDataFilePath) throws Exception {
+ KotlinTestUtils.runTest(this::doTest, TargetBackend.JVM, testDataFilePath);
+ }
+
+ public void testAllFilesPresentInUnit() throws Exception {
+ KotlinTestUtils.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/box/coroutines/tailCallOptimizations/unit"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JVM, true);
+ }
+
+ @TestMetadata("override.kt")
+ public void testOverride() throws Exception {
+ runTest("compiler/testData/codegen/box/coroutines/tailCallOptimizations/unit/override.kt");
+ }
+
+ @TestMetadata("override2.kt")
+ public void testOverride2() throws Exception {
+ runTest("compiler/testData/codegen/box/coroutines/tailCallOptimizations/unit/override2.kt");
+ }
+
+ @TestMetadata("override3.kt")
+ public void testOverride3() throws Exception {
+ runTest("compiler/testData/codegen/box/coroutines/tailCallOptimizations/unit/override3.kt");
+ }
+
+ @TestMetadata("override4.kt")
+ public void testOverride4() throws Exception {
+ runTest("compiler/testData/codegen/box/coroutines/tailCallOptimizations/unit/override4.kt");
+ }
+
+ @TestMetadata("override5.kt")
+ public void testOverride5() throws Exception {
+ runTest("compiler/testData/codegen/box/coroutines/tailCallOptimizations/unit/override5.kt");
+ }
+
+ @TestMetadata("override6.kt")
+ public void testOverride6() throws Exception {
+ runTest("compiler/testData/codegen/box/coroutines/tailCallOptimizations/unit/override6.kt");
+ }
+
+ @TestMetadata("overrideCrossinline.kt")
+ public void testOverrideCrossinline() throws Exception {
+ runTest("compiler/testData/codegen/box/coroutines/tailCallOptimizations/unit/overrideCrossinline.kt");
+ }
+
+ @TestMetadata("overrideOverriden.kt")
+ public void testOverrideOverriden() throws Exception {
+ runTest("compiler/testData/codegen/box/coroutines/tailCallOptimizations/unit/overrideOverriden.kt");
+ }
+
+ @TestMetadata("reflection.kt")
+ public void testReflection() throws Exception {
+ runTest("compiler/testData/codegen/box/coroutines/tailCallOptimizations/unit/reflection.kt");
+ }
+
+ @TestMetadata("simple.kt")
+ public void testSimple() throws Exception {
+ runTest("compiler/testData/codegen/box/coroutines/tailCallOptimizations/unit/simple.kt");
+ }
+ }
}
@TestMetadata("compiler/testData/codegen/box/coroutines/tailOperations")
diff --git a/compiler/tests/org/jetbrains/kotlin/codegen/ir/FirBlackBoxCodegenTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/codegen/ir/FirBlackBoxCodegenTestGenerated.java
index e56e863a624..b7b622cbf9c 100644
--- a/compiler/tests/org/jetbrains/kotlin/codegen/ir/FirBlackBoxCodegenTestGenerated.java
+++ b/compiler/tests/org/jetbrains/kotlin/codegen/ir/FirBlackBoxCodegenTestGenerated.java
@@ -7454,16 +7454,6 @@ public class FirBlackBoxCodegenTestGenerated extends AbstractFirBlackBoxCodegenT
runTestWithPackageReplacement("compiler/testData/codegen/box/coroutines/tailCallOptimizations/tryCatch.kt", "kotlin.coroutines");
}
- @TestMetadata("unitFunReturnsNonUnit.kt")
- public void testUnitFunReturnsNonUnit() throws Exception {
- runTest("compiler/testData/codegen/box/coroutines/tailCallOptimizations/unitFunReturnsNonUnit.kt");
- }
-
- @TestMetadata("unitFunReturnsNonUnitCallSuspend.kt")
- public void testUnitFunReturnsNonUnitCallSuspend() throws Exception {
- runTest("compiler/testData/codegen/box/coroutines/tailCallOptimizations/unitFunReturnsNonUnitCallSuspend.kt");
- }
-
@TestMetadata("unreachable.kt")
public void testUnreachable() throws Exception {
runTest("compiler/testData/codegen/box/coroutines/tailCallOptimizations/unreachable.kt");
@@ -7473,6 +7463,69 @@ public class FirBlackBoxCodegenTestGenerated extends AbstractFirBlackBoxCodegenT
public void testWhenUnit() throws Exception {
runTest("compiler/testData/codegen/box/coroutines/tailCallOptimizations/whenUnit.kt");
}
+
+ @TestMetadata("compiler/testData/codegen/box/coroutines/tailCallOptimizations/unit")
+ @TestDataPath("$PROJECT_ROOT")
+ @RunWith(JUnit3RunnerWithInners.class)
+ public static class Unit extends AbstractFirBlackBoxCodegenTest {
+ private void runTest(String testDataFilePath) throws Exception {
+ KotlinTestUtils.runTestWithCustomIgnoreDirective(this::doTest, TargetBackend.JVM_IR, testDataFilePath, "// IGNORE_BACKEND_FIR: ");
+ }
+
+ public void testAllFilesPresentInUnit() throws Exception {
+ KotlinTestUtils.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/box/coroutines/tailCallOptimizations/unit"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JVM_IR, true);
+ }
+
+ @TestMetadata("override.kt")
+ public void testOverride() throws Exception {
+ runTest("compiler/testData/codegen/box/coroutines/tailCallOptimizations/unit/override.kt");
+ }
+
+ @TestMetadata("override2.kt")
+ public void testOverride2() throws Exception {
+ runTest("compiler/testData/codegen/box/coroutines/tailCallOptimizations/unit/override2.kt");
+ }
+
+ @TestMetadata("override3.kt")
+ public void testOverride3() throws Exception {
+ runTest("compiler/testData/codegen/box/coroutines/tailCallOptimizations/unit/override3.kt");
+ }
+
+ @TestMetadata("override4.kt")
+ public void testOverride4() throws Exception {
+ runTest("compiler/testData/codegen/box/coroutines/tailCallOptimizations/unit/override4.kt");
+ }
+
+ @TestMetadata("override5.kt")
+ public void testOverride5() throws Exception {
+ runTest("compiler/testData/codegen/box/coroutines/tailCallOptimizations/unit/override5.kt");
+ }
+
+ @TestMetadata("override6.kt")
+ public void testOverride6() throws Exception {
+ runTest("compiler/testData/codegen/box/coroutines/tailCallOptimizations/unit/override6.kt");
+ }
+
+ @TestMetadata("overrideCrossinline.kt")
+ public void testOverrideCrossinline() throws Exception {
+ runTest("compiler/testData/codegen/box/coroutines/tailCallOptimizations/unit/overrideCrossinline.kt");
+ }
+
+ @TestMetadata("overrideOverriden.kt")
+ public void testOverrideOverriden() throws Exception {
+ runTest("compiler/testData/codegen/box/coroutines/tailCallOptimizations/unit/overrideOverriden.kt");
+ }
+
+ @TestMetadata("reflection.kt")
+ public void testReflection() throws Exception {
+ runTest("compiler/testData/codegen/box/coroutines/tailCallOptimizations/unit/reflection.kt");
+ }
+
+ @TestMetadata("simple.kt")
+ public void testSimple() throws Exception {
+ runTest("compiler/testData/codegen/box/coroutines/tailCallOptimizations/unit/simple.kt");
+ }
+ }
}
@TestMetadata("compiler/testData/codegen/box/coroutines/tailOperations")
diff --git a/compiler/tests/org/jetbrains/kotlin/codegen/ir/IrBlackBoxCodegenTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/codegen/ir/IrBlackBoxCodegenTestGenerated.java
index a57844230f7..01ccccacc85 100644
--- a/compiler/tests/org/jetbrains/kotlin/codegen/ir/IrBlackBoxCodegenTestGenerated.java
+++ b/compiler/tests/org/jetbrains/kotlin/codegen/ir/IrBlackBoxCodegenTestGenerated.java
@@ -7454,16 +7454,6 @@ public class IrBlackBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTes
runTestWithPackageReplacement("compiler/testData/codegen/box/coroutines/tailCallOptimizations/tryCatch.kt", "kotlin.coroutines");
}
- @TestMetadata("unitFunReturnsNonUnit.kt")
- public void testUnitFunReturnsNonUnit() throws Exception {
- runTest("compiler/testData/codegen/box/coroutines/tailCallOptimizations/unitFunReturnsNonUnit.kt");
- }
-
- @TestMetadata("unitFunReturnsNonUnitCallSuspend.kt")
- public void testUnitFunReturnsNonUnitCallSuspend() throws Exception {
- runTest("compiler/testData/codegen/box/coroutines/tailCallOptimizations/unitFunReturnsNonUnitCallSuspend.kt");
- }
-
@TestMetadata("unreachable.kt")
public void testUnreachable() throws Exception {
runTest("compiler/testData/codegen/box/coroutines/tailCallOptimizations/unreachable.kt");
@@ -7473,6 +7463,69 @@ public class IrBlackBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTes
public void testWhenUnit() throws Exception {
runTest("compiler/testData/codegen/box/coroutines/tailCallOptimizations/whenUnit.kt");
}
+
+ @TestMetadata("compiler/testData/codegen/box/coroutines/tailCallOptimizations/unit")
+ @TestDataPath("$PROJECT_ROOT")
+ @RunWith(JUnit3RunnerWithInners.class)
+ public static class Unit extends AbstractIrBlackBoxCodegenTest {
+ private void runTest(String testDataFilePath) throws Exception {
+ KotlinTestUtils.runTest(this::doTest, TargetBackend.JVM_IR, testDataFilePath);
+ }
+
+ public void testAllFilesPresentInUnit() throws Exception {
+ KotlinTestUtils.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/box/coroutines/tailCallOptimizations/unit"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JVM_IR, true);
+ }
+
+ @TestMetadata("override.kt")
+ public void testOverride() throws Exception {
+ runTest("compiler/testData/codegen/box/coroutines/tailCallOptimizations/unit/override.kt");
+ }
+
+ @TestMetadata("override2.kt")
+ public void testOverride2() throws Exception {
+ runTest("compiler/testData/codegen/box/coroutines/tailCallOptimizations/unit/override2.kt");
+ }
+
+ @TestMetadata("override3.kt")
+ public void testOverride3() throws Exception {
+ runTest("compiler/testData/codegen/box/coroutines/tailCallOptimizations/unit/override3.kt");
+ }
+
+ @TestMetadata("override4.kt")
+ public void testOverride4() throws Exception {
+ runTest("compiler/testData/codegen/box/coroutines/tailCallOptimizations/unit/override4.kt");
+ }
+
+ @TestMetadata("override5.kt")
+ public void testOverride5() throws Exception {
+ runTest("compiler/testData/codegen/box/coroutines/tailCallOptimizations/unit/override5.kt");
+ }
+
+ @TestMetadata("override6.kt")
+ public void testOverride6() throws Exception {
+ runTest("compiler/testData/codegen/box/coroutines/tailCallOptimizations/unit/override6.kt");
+ }
+
+ @TestMetadata("overrideCrossinline.kt")
+ public void testOverrideCrossinline() throws Exception {
+ runTest("compiler/testData/codegen/box/coroutines/tailCallOptimizations/unit/overrideCrossinline.kt");
+ }
+
+ @TestMetadata("overrideOverriden.kt")
+ public void testOverrideOverriden() throws Exception {
+ runTest("compiler/testData/codegen/box/coroutines/tailCallOptimizations/unit/overrideOverriden.kt");
+ }
+
+ @TestMetadata("reflection.kt")
+ public void testReflection() throws Exception {
+ runTest("compiler/testData/codegen/box/coroutines/tailCallOptimizations/unit/reflection.kt");
+ }
+
+ @TestMetadata("simple.kt")
+ public void testSimple() throws Exception {
+ runTest("compiler/testData/codegen/box/coroutines/tailCallOptimizations/unit/simple.kt");
+ }
+ }
}
@TestMetadata("compiler/testData/codegen/box/coroutines/tailOperations")
diff --git a/js/js.tests/test/org/jetbrains/kotlin/js/test/ir/semantics/IrJsCodegenBoxTestGenerated.java b/js/js.tests/test/org/jetbrains/kotlin/js/test/ir/semantics/IrJsCodegenBoxTestGenerated.java
index ffb5b980992..d2cbabfbf1b 100644
--- a/js/js.tests/test/org/jetbrains/kotlin/js/test/ir/semantics/IrJsCodegenBoxTestGenerated.java
+++ b/js/js.tests/test/org/jetbrains/kotlin/js/test/ir/semantics/IrJsCodegenBoxTestGenerated.java
@@ -6383,6 +6383,19 @@ public class IrJsCodegenBoxTestGenerated extends AbstractIrJsCodegenBoxTest {
public void testTryCatch_1_3() throws Exception {
runTestWithPackageReplacement("compiler/testData/codegen/box/coroutines/tailCallOptimizations/tryCatch.kt", "kotlin.coroutines");
}
+
+ @TestMetadata("compiler/testData/codegen/box/coroutines/tailCallOptimizations/unit")
+ @TestDataPath("$PROJECT_ROOT")
+ @RunWith(JUnit3RunnerWithInners.class)
+ public static class Unit extends AbstractIrJsCodegenBoxTest {
+ private void runTest(String testDataFilePath) throws Exception {
+ KotlinTestUtils.runTest0(this::doTest, TargetBackend.JS_IR, testDataFilePath);
+ }
+
+ public void testAllFilesPresentInUnit() throws Exception {
+ KotlinTestUtils.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/box/coroutines/tailCallOptimizations/unit"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JS_IR, true);
+ }
+ }
}
@TestMetadata("compiler/testData/codegen/box/coroutines/tailOperations")
diff --git a/js/js.tests/test/org/jetbrains/kotlin/js/test/semantics/JsCodegenBoxTestGenerated.java b/js/js.tests/test/org/jetbrains/kotlin/js/test/semantics/JsCodegenBoxTestGenerated.java
index 1b619afbd01..66575d9f10a 100644
--- a/js/js.tests/test/org/jetbrains/kotlin/js/test/semantics/JsCodegenBoxTestGenerated.java
+++ b/js/js.tests/test/org/jetbrains/kotlin/js/test/semantics/JsCodegenBoxTestGenerated.java
@@ -7403,6 +7403,19 @@ public class JsCodegenBoxTestGenerated extends AbstractJsCodegenBoxTest {
public void testTryCatch_1_3() throws Exception {
runTestWithPackageReplacement("compiler/testData/codegen/box/coroutines/tailCallOptimizations/tryCatch.kt", "kotlin.coroutines");
}
+
+ @TestMetadata("compiler/testData/codegen/box/coroutines/tailCallOptimizations/unit")
+ @TestDataPath("$PROJECT_ROOT")
+ @RunWith(JUnit3RunnerWithInners.class)
+ public static class Unit extends AbstractJsCodegenBoxTest {
+ private void runTest(String testDataFilePath) throws Exception {
+ KotlinTestUtils.runTest0(this::doTest, TargetBackend.JS, testDataFilePath);
+ }
+
+ public void testAllFilesPresentInUnit() throws Exception {
+ KotlinTestUtils.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/box/coroutines/tailCallOptimizations/unit"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JS, true);
+ }
+ }
}
@TestMetadata("compiler/testData/codegen/box/coroutines/tailOperations")