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.
This commit is contained in:
Alexander Udalov
2019-08-27 13:34:27 +02:00
parent 45929f57b6
commit 4dc1d61c38
@@ -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)
}