From 4dc1d61c380be04f5a071967a8521f8c2b8097f5 Mon Sep 17 00:00:00 2001 From: Alexander Udalov Date: Tue, 27 Aug 2019 13:34:27 +0200 Subject: [PATCH] JVM IR: do not remove overridden symbols in BridgeLowering This information might be needed in subsequent lowerings or codegen. For example, it'll be needed in MethodSignatureMapper to determine that we need to box primitive return type if one of overridden functions has a non-primitive return type. For invoke in lambda classes specifically though, we need to remove this override from the specialized invoke because otherwise we'd call a boxed version in the bridge (see 73d2ae961c). In this change, we still keep the override on a bridge though just for the sake of IR consistency. --- .../kotlin/backend/jvm/lower/BridgeLowering.kt | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/lower/BridgeLowering.kt b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/lower/BridgeLowering.kt index 9b507c2f11d..12d35af7168 100644 --- a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/lower/BridgeLowering.kt +++ b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/lower/BridgeLowering.kt @@ -41,6 +41,7 @@ import org.jetbrains.kotlin.ir.util.fqNameWhenAvailable import org.jetbrains.kotlin.ir.util.isInterface import org.jetbrains.kotlin.ir.util.parentAsClass import org.jetbrains.kotlin.name.Name +import org.jetbrains.kotlin.util.OperatorNameConventions import org.jetbrains.kotlin.utils.addToStdlib.safeAs import org.jetbrains.org.objectweb.asm.commons.Method @@ -186,7 +187,14 @@ private class BridgeLowering(val context: JvmBackendContext) : ClassLoweringPass val bridge = createBridgeHeader(irClass, target, method, isSpecial = isSpecial, isSynthetic = !isSpecial) bridge.createBridgeBody(target, defaultValueGenerator, isSpecial) irClass.declarations.add(bridge) - target.overriddenSymbols.remove(method.symbol) + + // For lambda classes, we move override from the `invoke` function to its bridge. This will allow us to avoid boxing + // the return type of `invoke` in codegen, in case lambda's return type is primitive. + if (method.name == OperatorNameConventions.INVOKE && irClass.origin == JvmLoweredDeclarationOrigin.LAMBDA_IMPL) { + target.overriddenSymbols.remove(method.symbol) + bridge.overriddenSymbols.add(method.symbol) + } + signaturesToSkip.add(signature) }