diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/MethodInliner.kt b/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/MethodInliner.kt index 76ecc94bd5d..b83616cc7cc 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/MethodInliner.kt +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/MethodInliner.kt @@ -1,5 +1,5 @@ /* - * Copyright 2010-2019 JetBrains s.r.o. and Kotlin Programming Language contributors. + * Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors. * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. */ @@ -703,6 +703,9 @@ class MethodInliner( // 2) it is ASTORE'd right after // 3) it is passed to invoke of lambda private fun replaceContinuationAccessesWithFakeContinuationsIfNeeded(processingNode: MethodNode) { + // in ir backend inline suspend lambdas do not use ALOAD 0 to get continuation, since they are generated as static functions + // instead they get continuation from parameter. + if (inliningContext.state.isIrBackend) return val lambdaInfo = inliningContext.lambdaInfo ?: return if (!lambdaInfo.isSuspend) return val sources = analyzeMethodNodeBeforeInline(processingNode) diff --git a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/codegen/ExpressionCodegen.kt b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/codegen/ExpressionCodegen.kt index 6434afede45..dcae6697f2b 100644 --- a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/codegen/ExpressionCodegen.kt +++ b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/codegen/ExpressionCodegen.kt @@ -1,11 +1,12 @@ /* - * Copyright 2010-2019 JetBrains s.r.o. and Kotlin Programming Language contributors. + * Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors. * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. */ package org.jetbrains.kotlin.backend.jvm.codegen import org.jetbrains.kotlin.backend.common.lower.BOUND_RECEIVER_PARAMETER +import org.jetbrains.kotlin.backend.common.lower.LocalDeclarationsLowering import org.jetbrains.kotlin.backend.jvm.JvmLoweredDeclarationOrigin import org.jetbrains.kotlin.backend.jvm.intrinsics.IrIntrinsicMethods import org.jetbrains.kotlin.backend.jvm.intrinsics.JavaClassProperty @@ -401,19 +402,19 @@ class ExpressionCodegen( } expression.symbol.descriptor is ConstructorDescriptor -> throw AssertionError("IrCall with ConstructorDescriptor: ${expression.javaClass.simpleName}") - callee.shouldGenerateSuspendMarkers() -> + expression.isSuspensionPoint() -> addInlineMarker(mv, isStartNotEnd = true) } expression.dispatchReceiver?.let { receiver -> val type = if ((expression as? IrCall)?.superQualifierSymbol != null) receiver.asmType else callable.owner - continuationAwareGenValueAndPut(receiver, type, callee.dispatchReceiverParameter!!, data, callGenerator) + callGenerator.genValueAndPut(callee.dispatchReceiverParameter!!, receiver, type, this, data) } expression.extensionReceiver?.let { receiver -> val type = callable.signature.valueParameters.singleOrNull { it.kind == JvmMethodParameterKind.RECEIVER }?.asmType ?: error("No single extension receiver parameter: ${callable.signature.valueParameters}") - continuationAwareGenValueAndPut(receiver, type, callee.extensionReceiverParameter!!, data, callGenerator) + callGenerator.genValueAndPut(callee.extensionReceiverParameter!!, receiver, type, this, data) } callGenerator.beforeValueParametersStart() @@ -421,13 +422,13 @@ class ExpressionCodegen( val arg = expression.getValueArgument(i) val parameterType = callable.valueParameterTypes[i] require(arg != null) { "Null argument in ExpressionCodegen for parameter ${irParameter.render()}" } - continuationAwareGenValueAndPut(arg, parameterType, irParameter, data, callGenerator) + callGenerator.genValueAndPut(irParameter, arg, parameterType, this, data) } expression.markLineNumber(true) // Do not generate redundant markers in continuation class. - if (callee.shouldGenerateSuspendMarkers()) { + if (expression.isSuspensionPoint()) { addSuspendMarker(mv, isStartNotEnd = true) } @@ -440,7 +441,7 @@ class ExpressionCodegen( callGenerator.genCall(callable, this, expression) } - if (callee.shouldGenerateSuspendMarkers()) { + if (expression.isSuspensionPoint()) { // Check return type of non-lowered suspend call, in order to replace the result of the call with Unit, // otherwise, it would seem like the call returns non-unit upon resume. // See box/coroutines/tailCallOptimization/unit tests. @@ -472,29 +473,30 @@ class ExpressionCodegen( } } - // In order to support java interop of inline suspend functions, we generate continuations of inline suspend functions. - // They should behave as ordinary suspend functions, i.e. we should not inline the content of the inline function into continuation. - // Thus, we should put its arguments to stack. - private fun continuationAwareGenValueAndPut( - arg: IrExpression, - parameterType: Type, - irParameter: IrValueParameter, - data: BlockInfo, - callGenerator: IrCallGenerator - ) { - if (irFunction.isInvokeSuspendOfContinuation()) { - gen(arg, parameterType, irParameter.type, data) - } else { - callGenerator.genValueAndPut(irParameter, arg, parameterType, this, data) + private fun IrFunctionAccessExpression.isSuspensionPoint(): Boolean { + val owner = symbol.owner + return when { + // Only suspend functions are suspension points + !owner.isSuspend -> false + // But not inside continuation classes and bridges + irFunction.shouldNotContainSuspendMarkers() -> false + // Noinline function are always suspension points + !owner.isInline -> true + // The suspend intrinsics are, albeit inline, are also suspension points + owner.fqNameForIrSerialization == FqName("kotlin.coroutines.intrinsics.IntrinsicsKt.suspendCoroutineUninterceptedOrReturn") -> true + // Inside $$forInline functions crossinline calls are (usually) not suspension points, otherwise, flow will be pessimized + (dispatchReceiver as? IrGetField)?.symbol?.owner?.origin == + LocalDeclarationsLowering.DECLARATION_ORIGIN_FIELD_FOR_CROSSINLINE_CAPTURED_VALUE -> + irFunction.origin != JvmLoweredDeclarationOrigin.FOR_INLINE_STATE_MACHINE_TEMPLATE_CAPTURES_CROSSINLINE + // The same goes for inline lambdas + (dispatchReceiver as? IrGetValue)?.let { + it.origin == IrStatementOrigin.VARIABLE_AS_FUNCTION && (it.symbol.owner as? IrValueParameter)?.isNoinline != true + } == true -> irFunction.origin != JvmLoweredDeclarationOrigin.FOR_INLINE_STATE_MACHINE_TEMPLATE + // Otherwise, this is normal inline call, ergo not a suspension point + else -> false } } - private fun IrFunction.shouldGenerateSuspendMarkers(): Boolean { - if (!isSuspend) return false - if (irFunction.shouldNotContainSuspendMarkers()) return false - return !symbol.owner.isInline || fqNameForIrSerialization == FqName("kotlin.coroutines.intrinsics.IntrinsicsKt.suspendCoroutineUninterceptedOrReturn") - } - override fun visitVariable(declaration: IrVariable, data: BlockInfo): PromisedValue { val varType = typeMapper.mapType(declaration) val index = frameMap.enter(declaration.symbol, varType) diff --git a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/codegen/IrInlineCodegen.kt b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/codegen/IrInlineCodegen.kt index a2030c810cf..914cb362b14 100644 --- a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/codegen/IrInlineCodegen.kt +++ b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/codegen/IrInlineCodegen.kt @@ -77,6 +77,14 @@ class IrInlineCodegen( codegen: ExpressionCodegen, blockInfo: BlockInfo ) { + if (codegen.irFunction.isInvokeSuspendOfContinuation()) { + // In order to support java interop of inline suspend functions, we generate continuations for these inline suspend functions. + // These functions should behave as ordinary suspend functions, i.e. we should not inline the content of the inline function + // into continuation. + // Thus, we should put its arguments to stack. + super.genValueAndPut(irValueParameter, argumentExpression, parameterType, codegen, blockInfo) + } + if (irValueParameter.isInlineParameter( /*after transformation inlinable lambda parameter with default value would have nullable type: check default value type first*/ irValueParameter.defaultValue?.expression?.type ?: irValueParameter.type diff --git a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/codegen/IrSourceCompilerForInline.kt b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/codegen/IrSourceCompilerForInline.kt index 6416d8a328a..9c6d7157ac7 100644 --- a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/codegen/IrSourceCompilerForInline.kt +++ b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/codegen/IrSourceCompilerForInline.kt @@ -77,6 +77,8 @@ class IrSourceCompilerForInline( private fun makeInlineNode(function: IrFunction, classCodegen: ClassCodegen, isLambda: Boolean): SMAPAndMethodNode { var node: MethodNode? = null + // Do not inline the generated state-machine, which was generated to support java interop of inline suspend functions. + // Instead, find its $$forInline companion (they share the same attributeOwnerId), which is generated for the inliner to use. val forInlineFunction = if (function.isSuspend) function.parentAsClass.functions.find { diff --git a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/lower/AddContinuationLowering.kt b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/lower/AddContinuationLowering.kt index 30b31f3840e..950cc246b8d 100644 --- a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/lower/AddContinuationLowering.kt +++ b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/lower/AddContinuationLowering.kt @@ -536,13 +536,12 @@ private class AddContinuationLowering(private val context: JvmBackendContext) : override fun visitClass(declaration: IrClass): IrStatement { functionsToAdd.push(mutableSetOf()) - val res = super.visitClass(declaration) - (res as IrClass).declarations.addAll(functionsToAdd.peek()!!) - for (function in functionsToAdd.peek()!!) { - function.patchDeclarationParents(res) + return (super.visitClass(declaration) as IrClass).also { irClass -> + for (function in functionsToAdd.pop()) { + function.parent = irClass + irClass.declarations.add(function) + } } - functionsToAdd.pop() - return res } override fun visitFunction(declaration: IrFunction): IrStatement { diff --git a/compiler/testData/codegen/box/coroutines/tailCallOptimizations/crossinline.kt b/compiler/testData/codegen/box/coroutines/tailCallOptimizations/crossinline.kt index ec5c15666ca..7782cb0405e 100644 --- a/compiler/testData/codegen/box/coroutines/tailCallOptimizations/crossinline.kt +++ b/compiler/testData/codegen/box/coroutines/tailCallOptimizations/crossinline.kt @@ -1,5 +1,4 @@ // IGNORE_BACKEND_FIR: JVM_IR -// IGNORE_BACKEND: JVM_IR // COMMON_COROUTINES_TEST // WITH_RUNTIME // WITH_COROUTINES diff --git a/compiler/testData/codegen/box/coroutines/tailCallOptimizations/crossinline_ir.txt b/compiler/testData/codegen/box/coroutines/tailCallOptimizations/crossinline_ir.txt new file mode 100644 index 00000000000..ed8851d622f --- /dev/null +++ b/compiler/testData/codegen/box/coroutines/tailCallOptimizations/crossinline_ir.txt @@ -0,0 +1,390 @@ +@kotlin.Metadata +@kotlin.coroutines.jvm.internal.DebugMetadata +final class CrossinlineKt$box$1$invokeSuspend$$inlined$filter$1$1 { + field L$0: java.lang.Object + field L$1: java.lang.Object + field L$2: java.lang.Object + field L$3: java.lang.Object + field L$4: java.lang.Object + field label: int + @org.jetbrains.annotations.NotNull field result: java.lang.Object + synthetic final field this$0: CrossinlineKt$box$1$invokeSuspend$$inlined$filter$1 + public method (p0: CrossinlineKt$box$1$invokeSuspend$$inlined$filter$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 +@kotlin.coroutines.jvm.internal.DebugMetadata +final class CrossinlineKt$box$1$invokeSuspend$$inlined$filter$1$2$1 { + field L$0: java.lang.Object + field L$1: java.lang.Object + field L$2: java.lang.Object + field label: int + @org.jetbrains.annotations.NotNull field result: java.lang.Object + synthetic final field this$0: CrossinlineKt$box$1$invokeSuspend$$inlined$filter$1$2 + public method (p0: CrossinlineKt$box$1$invokeSuspend$$inlined$filter$1$2, 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 CrossinlineKt$box$1$invokeSuspend$$inlined$filter$1$2 { + synthetic final field $this$anonymous$inlined: Sink + inner class CrossinlineKt$box$1$invokeSuspend$$inlined$filter$1$2 + public method (p0: Sink): void + public method close(@org.jetbrains.annotations.Nullable p0: java.lang.Throwable): void + public @org.jetbrains.annotations.Nullable method send$$forInline(p0: java.lang.Object, @org.jetbrains.annotations.NotNull p1: kotlin.coroutines.Continuation): java.lang.Object + public @org.jetbrains.annotations.Nullable method send(p0: java.lang.Object, @org.jetbrains.annotations.NotNull p1: kotlin.coroutines.Continuation): java.lang.Object +} + +@kotlin.Metadata +public final class CrossinlineKt$box$1$invokeSuspend$$inlined$filter$1 { + synthetic final field $this$filter$inlined: SourceCrossinline + inner class CrossinlineKt$box$1$invokeSuspend$$inlined$filter$1 + public method (p0: SourceCrossinline): void + public @org.jetbrains.annotations.Nullable method consume$$forInline(@org.jetbrains.annotations.NotNull p0: Sink, @org.jetbrains.annotations.NotNull p1: kotlin.coroutines.Continuation): java.lang.Object + public @org.jetbrains.annotations.Nullable method consume(@org.jetbrains.annotations.NotNull p0: Sink, @org.jetbrains.annotations.NotNull p1: kotlin.coroutines.Continuation): java.lang.Object +} + +@kotlin.Metadata +@kotlin.coroutines.jvm.internal.DebugMetadata +final class CrossinlineKt$box$1$invokeSuspend$$inlined$fold$1$1 { + field L$0: java.lang.Object + field L$1: java.lang.Object + field L$2: java.lang.Object + field L$3: java.lang.Object + field label: int + @org.jetbrains.annotations.NotNull field result: java.lang.Object + synthetic final field this$0: CrossinlineKt$box$1$invokeSuspend$$inlined$fold$1 + public method (p0: CrossinlineKt$box$1$invokeSuspend$$inlined$fold$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 CrossinlineKt$box$1$invokeSuspend$$inlined$fold$1 { + synthetic final field $acc$inlined: kotlin.jvm.internal.Ref$ObjectRef + inner class CrossinlineKt$box$1$invokeSuspend$$inlined$fold$1 + public method (p0: kotlin.jvm.internal.Ref$ObjectRef): void + public method close(@org.jetbrains.annotations.Nullable p0: java.lang.Throwable): void + public @org.jetbrains.annotations.Nullable method send$$forInline(p0: java.lang.Object, @org.jetbrains.annotations.NotNull p1: kotlin.coroutines.Continuation): java.lang.Object + public @org.jetbrains.annotations.Nullable method send(p0: java.lang.Object, @org.jetbrains.annotations.NotNull p1: kotlin.coroutines.Continuation): java.lang.Object +} + +@kotlin.coroutines.jvm.internal.DebugMetadata +@kotlin.Metadata +final class CrossinlineKt$box$1 { + private field $res: kotlin.jvm.internal.Ref$IntRef + field L$0: java.lang.Object + field L$1: java.lang.Object + field L$2: java.lang.Object + field L$3: java.lang.Object + field L$4: java.lang.Object + private field label: int + inner class CrossinlineKt$box$1 + public method (p0: kotlin.jvm.internal.Ref$IntRef, p1: 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 +final class CrossinlineKt$consumeEach$1 { + field label: int + @org.jetbrains.annotations.NotNull field result: java.lang.Object + public method (p0: 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 +final class CrossinlineKt$consumeEach$2$send$1 { + field label: int + @org.jetbrains.annotations.NotNull field result: java.lang.Object + private field this$0: CrossinlineKt$consumeEach$2 + public method (p0: CrossinlineKt$consumeEach$2, 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 CrossinlineKt$consumeEach$2 { + private synthetic final field $action: kotlin.jvm.functions.Function2 + inner class CrossinlineKt$consumeEach$2 + public method (p0: kotlin.jvm.functions.Function2): void + public method close(@org.jetbrains.annotations.Nullable p0: java.lang.Throwable): void + public @org.jetbrains.annotations.Nullable method send$$forInline(p0: java.lang.Object, @org.jetbrains.annotations.NotNull p1: kotlin.coroutines.Continuation): java.lang.Object + public @org.jetbrains.annotations.Nullable method send(p0: java.lang.Object, @org.jetbrains.annotations.NotNull p1: kotlin.coroutines.Continuation): java.lang.Object +} + +@kotlin.Metadata +@kotlin.coroutines.jvm.internal.DebugMetadata +final class CrossinlineKt$filter$$inlined$source$1$1 { + field L$0: java.lang.Object + field L$1: java.lang.Object + field L$2: java.lang.Object + field L$3: java.lang.Object + field L$4: java.lang.Object + field label: int + @org.jetbrains.annotations.NotNull field result: java.lang.Object + synthetic final field this$0: CrossinlineKt$filter$$inlined$source$1 + public method (p0: CrossinlineKt$filter$$inlined$source$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 CrossinlineKt$filter$$inlined$source$1 { + synthetic final field $predicate$inlined: kotlin.jvm.functions.Function1 + synthetic final field $this$filter$inlined: SourceCrossinline + inner class CrossinlineKt$filter$$inlined$source$1 + public method (p0: SourceCrossinline, p1: kotlin.jvm.functions.Function1): void + public @org.jetbrains.annotations.Nullable method consume$$forInline(@org.jetbrains.annotations.NotNull p0: Sink, @org.jetbrains.annotations.NotNull p1: kotlin.coroutines.Continuation): java.lang.Object + public @org.jetbrains.annotations.Nullable method consume(@org.jetbrains.annotations.NotNull p0: Sink, @org.jetbrains.annotations.NotNull p1: kotlin.coroutines.Continuation): java.lang.Object +} + +@kotlin.Metadata +@kotlin.coroutines.jvm.internal.DebugMetadata +final class CrossinlineKt$filter$$inlined$source$2$1 { + field L$0: java.lang.Object + field L$1: java.lang.Object + field L$2: java.lang.Object + field L$3: java.lang.Object + field L$4: java.lang.Object + field label: int + @org.jetbrains.annotations.NotNull field result: java.lang.Object + synthetic final field this$0: CrossinlineKt$filter$$inlined$source$2 + public method (p0: CrossinlineKt$filter$$inlined$source$2, 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 CrossinlineKt$filter$$inlined$source$2 { + synthetic final field $predicate$inlined: kotlin.jvm.functions.Function1 + synthetic final field $this$filter$inlined: SourceCrossinline + inner class CrossinlineKt$filter$$inlined$source$2 + public method (p0: SourceCrossinline, p1: kotlin.jvm.functions.Function1): void + public @org.jetbrains.annotations.Nullable method consume$$forInline(@org.jetbrains.annotations.NotNull p0: Sink, @org.jetbrains.annotations.NotNull p1: kotlin.coroutines.Continuation): java.lang.Object + public @org.jetbrains.annotations.Nullable method consume(@org.jetbrains.annotations.NotNull p0: Sink, @org.jetbrains.annotations.NotNull p1: kotlin.coroutines.Continuation): java.lang.Object +} + +@kotlin.Metadata +@kotlin.coroutines.jvm.internal.DebugMetadata +final class CrossinlineKt$filter$lambda-3$$inlined$consumeEach$1$1 { + field L$0: java.lang.Object + field L$1: java.lang.Object + field L$2: java.lang.Object + field label: int + @org.jetbrains.annotations.NotNull field result: java.lang.Object + synthetic final field this$0: CrossinlineKt$filter$lambda-3$$inlined$consumeEach$1 + public method (p0: CrossinlineKt$filter$lambda-3$$inlined$consumeEach$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 CrossinlineKt$filter$lambda-3$$inlined$consumeEach$1 { + synthetic final field $predicate$inlined: kotlin.jvm.functions.Function1 + synthetic final field $this$anonymous$inlined: Sink + inner class CrossinlineKt$filter$lambda-3$$inlined$consumeEach$1 + public method (p0: kotlin.jvm.functions.Function1, p1: Sink): void + public method close(@org.jetbrains.annotations.Nullable p0: java.lang.Throwable): void + public @org.jetbrains.annotations.Nullable method send$$forInline(p0: java.lang.Object, @org.jetbrains.annotations.NotNull p1: kotlin.coroutines.Continuation): java.lang.Object + public @org.jetbrains.annotations.Nullable method send(p0: java.lang.Object, @org.jetbrains.annotations.NotNull p1: kotlin.coroutines.Continuation): java.lang.Object +} + +@kotlin.Metadata +@kotlin.coroutines.jvm.internal.DebugMetadata +final class CrossinlineKt$filter$lambda-3$$inlined$consumeEach$2$1 { + field L$0: java.lang.Object + field L$1: java.lang.Object + field L$2: java.lang.Object + field label: int + @org.jetbrains.annotations.NotNull field result: java.lang.Object + synthetic final field this$0: CrossinlineKt$filter$lambda-3$$inlined$consumeEach$2 + public method (p0: CrossinlineKt$filter$lambda-3$$inlined$consumeEach$2, 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 CrossinlineKt$filter$lambda-3$$inlined$consumeEach$2 { + synthetic final field $predicate$inlined: kotlin.jvm.functions.Function1 + synthetic final field $this$anonymous$inlined: Sink + inner class CrossinlineKt$filter$lambda-3$$inlined$consumeEach$2 + public method (p0: kotlin.jvm.functions.Function1, p1: Sink): void + public method close(@org.jetbrains.annotations.Nullable p0: java.lang.Throwable): void + public @org.jetbrains.annotations.Nullable method send$$forInline(p0: java.lang.Object, @org.jetbrains.annotations.NotNull p1: kotlin.coroutines.Continuation): java.lang.Object + public @org.jetbrains.annotations.Nullable method send(p0: java.lang.Object, @org.jetbrains.annotations.NotNull p1: kotlin.coroutines.Continuation): java.lang.Object +} + +@kotlin.Metadata +@kotlin.coroutines.jvm.internal.DebugMetadata +final class CrossinlineKt$fold$$forInline$$inlined$consumeEach$1$1 { + field L$0: java.lang.Object + field L$1: java.lang.Object + field L$2: java.lang.Object + field L$3: java.lang.Object + field label: int + @org.jetbrains.annotations.NotNull field result: java.lang.Object + synthetic final field this$0: CrossinlineKt$fold$$forInline$$inlined$consumeEach$1 + public method (p0: CrossinlineKt$fold$$forInline$$inlined$consumeEach$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 CrossinlineKt$fold$$forInline$$inlined$consumeEach$1 { + synthetic final field $acc$inlined: kotlin.jvm.internal.Ref$ObjectRef + synthetic final field $operation$inlined: kotlin.jvm.functions.Function3 + inner class CrossinlineKt$fold$$forInline$$inlined$consumeEach$1 + public method (p0: kotlin.jvm.internal.Ref$ObjectRef, p1: kotlin.jvm.functions.Function3): void + public method close(@org.jetbrains.annotations.Nullable p0: java.lang.Throwable): void + public @org.jetbrains.annotations.Nullable method send$$forInline(p0: java.lang.Object, @org.jetbrains.annotations.NotNull p1: kotlin.coroutines.Continuation): java.lang.Object + public @org.jetbrains.annotations.Nullable method send(p0: java.lang.Object, @org.jetbrains.annotations.NotNull p1: kotlin.coroutines.Continuation): java.lang.Object +} + +@kotlin.Metadata +@kotlin.coroutines.jvm.internal.DebugMetadata +final class CrossinlineKt$fold$$forInline$$inlined$consumeEach$2$1 { + field L$0: java.lang.Object + field L$1: java.lang.Object + field L$2: java.lang.Object + field L$3: java.lang.Object + field label: int + @org.jetbrains.annotations.NotNull field result: java.lang.Object + synthetic final field this$0: CrossinlineKt$fold$$forInline$$inlined$consumeEach$2 + public method (p0: CrossinlineKt$fold$$forInline$$inlined$consumeEach$2, 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 CrossinlineKt$fold$$forInline$$inlined$consumeEach$2 { + synthetic final field $acc$inlined: kotlin.jvm.internal.Ref$ObjectRef + synthetic final field $operation$inlined: kotlin.jvm.functions.Function3 + inner class CrossinlineKt$fold$$forInline$$inlined$consumeEach$2 + public method (p0: kotlin.jvm.internal.Ref$ObjectRef, p1: kotlin.jvm.functions.Function3): void + public method close(@org.jetbrains.annotations.Nullable p0: java.lang.Throwable): void + public @org.jetbrains.annotations.Nullable method send$$forInline(p0: java.lang.Object, @org.jetbrains.annotations.NotNull p1: kotlin.coroutines.Continuation): java.lang.Object + public @org.jetbrains.annotations.Nullable method send(p0: java.lang.Object, @org.jetbrains.annotations.NotNull p1: kotlin.coroutines.Continuation): java.lang.Object +} + +@kotlin.Metadata +@kotlin.coroutines.jvm.internal.DebugMetadata +final class CrossinlineKt$fold$$inlined$consumeEach$1$1 { + field L$0: java.lang.Object + field L$1: java.lang.Object + field L$2: java.lang.Object + field L$3: java.lang.Object + field label: int + @org.jetbrains.annotations.NotNull field result: java.lang.Object + synthetic final field this$0: CrossinlineKt$fold$$inlined$consumeEach$1 + public method (p0: CrossinlineKt$fold$$inlined$consumeEach$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 CrossinlineKt$fold$$inlined$consumeEach$1 { + synthetic final field $acc$inlined: kotlin.jvm.internal.Ref$ObjectRef + synthetic final field $operation$inlined: kotlin.jvm.functions.Function3 + inner class CrossinlineKt$fold$$inlined$consumeEach$1 + public method (p0: kotlin.jvm.internal.Ref$ObjectRef, p1: kotlin.jvm.functions.Function3): void + public method close(@org.jetbrains.annotations.Nullable p0: java.lang.Throwable): void + public @org.jetbrains.annotations.Nullable method send$$forInline(p0: java.lang.Object, @org.jetbrains.annotations.NotNull p1: kotlin.coroutines.Continuation): java.lang.Object + public @org.jetbrains.annotations.Nullable method send(p0: java.lang.Object, @org.jetbrains.annotations.NotNull p1: kotlin.coroutines.Continuation): java.lang.Object +} + +@kotlin.Metadata +@kotlin.coroutines.jvm.internal.DebugMetadata +final class CrossinlineKt$fold$1 { + field L$0: java.lang.Object + field L$1: java.lang.Object + field L$2: java.lang.Object + field L$3: java.lang.Object + field L$4: java.lang.Object + field label: int + @org.jetbrains.annotations.NotNull field result: java.lang.Object + public method (p0: 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 +@kotlin.coroutines.jvm.internal.DebugMetadata +final class CrossinlineKt$range$$inlined$source$1$1 { + field I$0: int + field I$1: int + field I$2: int + field L$0: java.lang.Object + field L$1: java.lang.Object + field L$2: java.lang.Object + field L$3: java.lang.Object + field L$4: java.lang.Object + field label: int + @org.jetbrains.annotations.NotNull field result: java.lang.Object + synthetic final field this$0: CrossinlineKt$range$$inlined$source$1 + public method (p0: CrossinlineKt$range$$inlined$source$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 CrossinlineKt$range$$inlined$source$1 { + synthetic final field $count$inlined: int + synthetic final field $start$inlined: int + inner class CrossinlineKt$range$$inlined$source$1 + public method (p0: int, p1: int): void + public @org.jetbrains.annotations.Nullable method consume$$forInline(@org.jetbrains.annotations.NotNull p0: Sink, @org.jetbrains.annotations.NotNull p1: kotlin.coroutines.Continuation): java.lang.Object + public @org.jetbrains.annotations.Nullable method consume(@org.jetbrains.annotations.NotNull p0: Sink, @org.jetbrains.annotations.NotNull p1: kotlin.coroutines.Continuation): java.lang.Object +} + +@kotlin.Metadata +@kotlin.coroutines.jvm.internal.DebugMetadata +final class CrossinlineKt$source$1$consume$1 { + field L$0: java.lang.Object + field L$1: java.lang.Object + field L$2: java.lang.Object + field label: int + @org.jetbrains.annotations.NotNull field result: java.lang.Object + private field this$0: CrossinlineKt$source$1 + public method (p0: CrossinlineKt$source$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 CrossinlineKt$source$1 { + private synthetic final field $action: kotlin.jvm.functions.Function2 + inner class CrossinlineKt$source$1 + public method (p0: kotlin.jvm.functions.Function2): void + public @org.jetbrains.annotations.Nullable method consume$$forInline(@org.jetbrains.annotations.NotNull p0: Sink, @org.jetbrains.annotations.NotNull p1: kotlin.coroutines.Continuation): java.lang.Object + public @org.jetbrains.annotations.Nullable method consume(@org.jetbrains.annotations.NotNull p0: Sink, @org.jetbrains.annotations.NotNull p1: kotlin.coroutines.Continuation): java.lang.Object +} + +@kotlin.Metadata +public final class CrossinlineKt { + inner class CrossinlineKt$box$1 + inner class CrossinlineKt$consumeEach$2 + inner class CrossinlineKt$source$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 consumeEach$$forInline(@org.jetbrains.annotations.NotNull p0: SourceCrossinline, @org.jetbrains.annotations.NotNull p1: kotlin.jvm.functions.Function2, @org.jetbrains.annotations.NotNull p2: kotlin.coroutines.Continuation): java.lang.Object + public final static @org.jetbrains.annotations.Nullable method consumeEach(@org.jetbrains.annotations.NotNull p0: SourceCrossinline, @org.jetbrains.annotations.NotNull p1: kotlin.jvm.functions.Function2, @org.jetbrains.annotations.NotNull p2: kotlin.coroutines.Continuation): java.lang.Object + public final static @org.jetbrains.annotations.NotNull method filter(@org.jetbrains.annotations.NotNull p0: SourceCrossinline, @org.jetbrains.annotations.NotNull p1: kotlin.jvm.functions.Function1): SourceCrossinline + public final static @org.jetbrains.annotations.Nullable method fold$$forInline(@org.jetbrains.annotations.NotNull p0: SourceCrossinline, p1: java.lang.Object, @org.jetbrains.annotations.NotNull p2: kotlin.jvm.functions.Function3, @org.jetbrains.annotations.NotNull p3: kotlin.coroutines.Continuation): java.lang.Object + public final static @org.jetbrains.annotations.Nullable method fold(@org.jetbrains.annotations.NotNull p0: SourceCrossinline, p1: java.lang.Object, @org.jetbrains.annotations.NotNull p2: kotlin.jvm.functions.Function3, @org.jetbrains.annotations.NotNull p3: kotlin.coroutines.Continuation): java.lang.Object + public final static method isGood(p0: int): boolean + public final static @org.jetbrains.annotations.NotNull method range(@org.jetbrains.annotations.NotNull p0: SourceCrossinline$Factory, p1: int, p2: int): SourceCrossinline + public final static @org.jetbrains.annotations.NotNull method source(@org.jetbrains.annotations.NotNull p0: kotlin.jvm.functions.Function2): SourceCrossinline +} + +@kotlin.Metadata +public interface Sink { + public abstract method close(@org.jetbrains.annotations.Nullable p0: java.lang.Throwable): void + public abstract @org.jetbrains.annotations.Nullable method send(p0: java.lang.Object, @org.jetbrains.annotations.NotNull p1: kotlin.coroutines.Continuation): java.lang.Object +} + +@kotlin.Metadata +public final class SourceCrossinline$Factory { + synthetic final static @org.jetbrains.annotations.NotNull field $$INSTANCE: SourceCrossinline$Factory + inner class SourceCrossinline$Factory + public final static method (): void + private method (): void +} + +@kotlin.Metadata +public interface SourceCrossinline { + public final static @org.jetbrains.annotations.NotNull field Factory: SourceCrossinline$Factory + inner class SourceCrossinline$Factory + public static method (): void + public abstract @org.jetbrains.annotations.Nullable method consume(@org.jetbrains.annotations.NotNull p0: Sink, @org.jetbrains.annotations.NotNull p1: kotlin.coroutines.Continuation): java.lang.Object +} diff --git a/compiler/testData/codegen/boxInline/suspend/receiver/inlineSuspendOfSuspend.kt b/compiler/testData/codegen/boxInline/suspend/receiver/inlineSuspendOfSuspend.kt index a2b7a2b0659..ececeddc70a 100644 --- a/compiler/testData/codegen/boxInline/suspend/receiver/inlineSuspendOfSuspend.kt +++ b/compiler/testData/codegen/boxInline/suspend/receiver/inlineSuspendOfSuspend.kt @@ -1,4 +1,3 @@ -// IGNORE_BACKEND: JVM_IR // IGNORE_BACKEND_MULTI_MODULE: JVM_IR // FILE: test.kt // COMMON_COROUTINES_TEST