diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/LambdaInfo.kt b/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/LambdaInfo.kt index a41e9a3efab..df4dab01a40 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/LambdaInfo.kt +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/LambdaInfo.kt @@ -73,10 +73,7 @@ abstract class ExpressionLambda : LambdaInfo() { } } - class DefaultLambda(info: ExtractedDefaultLambda, sourceCompiler: SourceCompilerForInline) : LambdaInfo() { - val needReification = info.needReification // TODO: remove this - override val lambdaClassType: Type = info.type override val isSuspend: Boolean get() = false // TODO: it should probably be true sometimes, but it never was override val isBoundCallableReference: Boolean 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 ee13aff47e0..51c57cce78e 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/MethodInliner.kt +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/MethodInliner.kt @@ -92,10 +92,6 @@ class MethodInliner( ): InlineResult { //analyze body var transformedNode = markPlacesForInlineAndRemoveInlinable(node, returnLabels, finallyDeepShift) - if (inliningContext.isInliningLambda && isDefaultLambdaWithReification(inliningContext.lambdaInfo!!)) { - //TODO maybe move reification in one place - inliningContext.root.inlineMethodReifier.reifyInstructions(transformedNode) - } //substitute returns with "goto end" instruction to keep non local returns in lambdas val end = linkedLabel() @@ -321,10 +317,17 @@ class MethodInliner( } else { super.visitMethodInsn(opcode, owner, name, desc, itf) } - } else if ((!inliningContext.isInliningLambda || isDefaultLambdaWithReification(inliningContext.lambdaInfo!!)) && - ReifiedTypeInliner.isNeedClassReificationMarker(MethodInsnNode(opcode, owner, name, desc, false)) - ) { - //we shouldn't process here content of inlining lambda it should be reified at external level except default lambdas + } else if (ReifiedTypeInliner.isNeedClassReificationMarker(MethodInsnNode(opcode, owner, name, desc, false))) { + // Consider this arrangement: + // inline fun f(x: () -> Unit = { /* uses `T` in a local class */ }) = x() + // inline fun g() = f<...> { /* uses `V` in a local class */ } + // When inlining `f` into `g`, we need to erase class reification markers from `f` and the default lambda + // (they will be recreated by `handleAnonymousObjectRegeneration` above if `T` is instantiated with another + // reified type parameter), but not from the lambda passed to `f` in `g` (as reified type parameters inside + // it do not belong to `f`, thus we cannot substitute them yet). + if (inliningContext.isInliningLambda && inliningContext.lambdaInfo !is DefaultLambda) { + super.visitMethodInsn(opcode, owner, name, desc, itf) + } } else { super.visitMethodInsn(opcode, owner, name, desc, itf) } @@ -349,9 +352,6 @@ class MethodInliner( return resultNode } - private fun isDefaultLambdaWithReification(lambdaInfo: LambdaInfo) = - lambdaInfo is DefaultLambda && lambdaInfo.needReification - private fun prepareNode(node: MethodNode, finallyDeepShift: Int): MethodNode { node.instructions.resetLabels()