JVM_IR KT-44627 fix bridge signature for parameter with primitive bound
This commit is contained in:
+3
-1
@@ -198,7 +198,9 @@ class MethodSignatureMapper(private val context: JvmBackendContext) {
|
|||||||
|
|
||||||
// See also: KotlinTypeMapper.forceBoxedReturnType
|
// See also: KotlinTypeMapper.forceBoxedReturnType
|
||||||
private fun forceBoxedReturnType(function: IrFunction): Boolean =
|
private fun forceBoxedReturnType(function: IrFunction): Boolean =
|
||||||
isBoxMethodForInlineClass(function) || forceFoxedReturnTypeOnOverride(function) || forceBoxedReturnTypeOnDefaultImplFun(function) ||
|
isBoxMethodForInlineClass(function) ||
|
||||||
|
forceFoxedReturnTypeOnOverride(function) ||
|
||||||
|
forceBoxedReturnTypeOnDefaultImplFun(function) ||
|
||||||
function.isFromJava() && function.returnType.isInlined()
|
function.isFromJava() && function.returnType.isInlined()
|
||||||
|
|
||||||
private fun forceFoxedReturnTypeOnOverride(function: IrFunction) =
|
private fun forceFoxedReturnTypeOnOverride(function: IrFunction) =
|
||||||
|
|||||||
+15
-8
@@ -428,17 +428,24 @@ internal class BridgeLowering(val context: JvmBackendContext) : FileLoweringPass
|
|||||||
copyParametersWithErasure(this@addBridge, bridge.overridden)
|
copyParametersWithErasure(this@addBridge, bridge.overridden)
|
||||||
body = context.createIrBuilder(symbol, startOffset, endOffset).run { irExprBody(delegatingCall(this@apply, target)) }
|
body = context.createIrBuilder(symbol, startOffset, endOffset).run { irExprBody(delegatingCall(this@apply, target)) }
|
||||||
|
|
||||||
// The generated bridge method overrides all of the symbols which were overridden by its overrides.
|
if (!bridge.overridden.returnType.isTypeParameterWithPrimitiveUpperBound()) {
|
||||||
// This is technically wrong, but it's necessary to generate a method which maps to the same signature.
|
// The generated bridge method overrides all of the symbols which were overridden by its overrides.
|
||||||
val inheritedOverrides = bridge.overriddenSymbols.flatMapTo(mutableSetOf()) { function ->
|
// This is technically wrong, but it's necessary to generate a method which maps to the same signature.
|
||||||
function.owner.safeAs<IrSimpleFunction>()?.overriddenSymbols ?: emptyList()
|
// In case of 'fun foo(): T', where 'T' is a type parameter with primitive upper bound (e.g., 'T : Char'),
|
||||||
|
// 'foo' is mapped to 'foo()C', regardless of its overrides.
|
||||||
|
val inheritedOverrides = bridge.overriddenSymbols.flatMapTo(mutableSetOf()) { function ->
|
||||||
|
function.owner.safeAs<IrSimpleFunction>()?.overriddenSymbols ?: emptyList()
|
||||||
|
}
|
||||||
|
val redundantOverrides = inheritedOverrides.flatMapTo(mutableSetOf()) {
|
||||||
|
it.owner.allOverridden().map { override -> override.symbol }
|
||||||
|
}
|
||||||
|
overriddenSymbols = inheritedOverrides.filter { it !in redundantOverrides }
|
||||||
}
|
}
|
||||||
val redundantOverrides = inheritedOverrides.flatMapTo(mutableSetOf()) {
|
|
||||||
it.owner.allOverridden().map { override -> override.symbol }
|
|
||||||
}
|
|
||||||
overriddenSymbols = inheritedOverrides.filter { it !in redundantOverrides }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun IrType.isTypeParameterWithPrimitiveUpperBound(): Boolean =
|
||||||
|
isTypeParameter() && eraseTypeParameters().isPrimitiveType()
|
||||||
|
|
||||||
private fun IrClass.addSpecialBridge(specialBridge: SpecialBridge, target: IrSimpleFunction): IrSimpleFunction =
|
private fun IrClass.addSpecialBridge(specialBridge: SpecialBridge, target: IrSimpleFunction): IrSimpleFunction =
|
||||||
addFunction {
|
addFunction {
|
||||||
startOffset = this@addSpecialBridge.startOffset
|
startOffset = this@addSpecialBridge.startOffset
|
||||||
|
|||||||
@@ -0,0 +1,5 @@
|
|||||||
|
open class ATChar<T : Char>(open var x: T)
|
||||||
|
|
||||||
|
open class BTChar<T : Char>(override var x: T) : ATChar<T>(x)
|
||||||
|
|
||||||
|
class CChar(override var x: Char) : BTChar<Char>('x')
|
||||||
+27
@@ -0,0 +1,27 @@
|
|||||||
|
@kotlin.Metadata
|
||||||
|
public class ATChar {
|
||||||
|
// source: 'overrideWithPrimitiveUpperBound.kt'
|
||||||
|
private field x: char
|
||||||
|
public method <init>(p0: char): void
|
||||||
|
public method getX(): char
|
||||||
|
public method setX(p0: char): void
|
||||||
|
}
|
||||||
|
|
||||||
|
@kotlin.Metadata
|
||||||
|
public class BTChar {
|
||||||
|
// source: 'overrideWithPrimitiveUpperBound.kt'
|
||||||
|
private field x: char
|
||||||
|
public method <init>(p0: char): void
|
||||||
|
public method getX(): char
|
||||||
|
public method setX(p0: char): void
|
||||||
|
}
|
||||||
|
|
||||||
|
@kotlin.Metadata
|
||||||
|
public final class CChar {
|
||||||
|
// source: 'overrideWithPrimitiveUpperBound.kt'
|
||||||
|
private field x: char
|
||||||
|
public method <init>(p0: char): void
|
||||||
|
public synthetic bridge method getX(): char
|
||||||
|
public @org.jetbrains.annotations.NotNull method getX(): java.lang.Character
|
||||||
|
public method setX(p0: char): void
|
||||||
|
}
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
open class ATAny<T>(open val x: T)
|
||||||
|
|
||||||
|
open class BTChar<T : Char>(override val x: T) : ATAny<T>(x)
|
||||||
|
|
||||||
|
class CChar(override val x: Char) : BTChar<Char>('x')
|
||||||
+26
@@ -0,0 +1,26 @@
|
|||||||
|
@kotlin.Metadata
|
||||||
|
public class ATAny {
|
||||||
|
// source: 'overrideWithPrimitiveUpperBound2.kt'
|
||||||
|
private final field x: java.lang.Object
|
||||||
|
public method <init>(p0: java.lang.Object): void
|
||||||
|
public method getX(): java.lang.Object
|
||||||
|
}
|
||||||
|
|
||||||
|
@kotlin.Metadata
|
||||||
|
public class BTChar {
|
||||||
|
// source: 'overrideWithPrimitiveUpperBound2.kt'
|
||||||
|
private final field x: char
|
||||||
|
public method <init>(p0: char): void
|
||||||
|
public method getX(): char
|
||||||
|
public synthetic bridge method getX(): java.lang.Object
|
||||||
|
}
|
||||||
|
|
||||||
|
@kotlin.Metadata
|
||||||
|
public final class CChar {
|
||||||
|
// source: 'overrideWithPrimitiveUpperBound2.kt'
|
||||||
|
private final field x: char
|
||||||
|
public method <init>(p0: char): void
|
||||||
|
public synthetic bridge method getX(): char
|
||||||
|
public @org.jetbrains.annotations.NotNull method getX(): java.lang.Character
|
||||||
|
public synthetic bridge method getX(): java.lang.Object
|
||||||
|
}
|
||||||
+10
@@ -215,6 +215,16 @@ public class BytecodeListingTestGenerated extends AbstractBytecodeListingTest {
|
|||||||
runTest("compiler/testData/codegen/bytecodeListing/noRemoveAtInReadOnly.kt");
|
runTest("compiler/testData/codegen/bytecodeListing/noRemoveAtInReadOnly.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("overrideWithPrimitiveUpperBound.kt")
|
||||||
|
public void testOverrideWithPrimitiveUpperBound() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/bytecodeListing/overrideWithPrimitiveUpperBound.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("overrideWithPrimitiveUpperBound2.kt")
|
||||||
|
public void testOverrideWithPrimitiveUpperBound2() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/bytecodeListing/overrideWithPrimitiveUpperBound2.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("privateCompanionFields.kt")
|
@TestMetadata("privateCompanionFields.kt")
|
||||||
public void testPrivateCompanionFields() throws Exception {
|
public void testPrivateCompanionFields() throws Exception {
|
||||||
runTest("compiler/testData/codegen/bytecodeListing/privateCompanionFields.kt");
|
runTest("compiler/testData/codegen/bytecodeListing/privateCompanionFields.kt");
|
||||||
|
|||||||
+10
@@ -215,6 +215,16 @@ public class IrBytecodeListingTestGenerated extends AbstractIrBytecodeListingTes
|
|||||||
runTest("compiler/testData/codegen/bytecodeListing/noRemoveAtInReadOnly.kt");
|
runTest("compiler/testData/codegen/bytecodeListing/noRemoveAtInReadOnly.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("overrideWithPrimitiveUpperBound.kt")
|
||||||
|
public void testOverrideWithPrimitiveUpperBound() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/bytecodeListing/overrideWithPrimitiveUpperBound.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("overrideWithPrimitiveUpperBound2.kt")
|
||||||
|
public void testOverrideWithPrimitiveUpperBound2() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/bytecodeListing/overrideWithPrimitiveUpperBound2.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("privateCompanionFields.kt")
|
@TestMetadata("privateCompanionFields.kt")
|
||||||
public void testPrivateCompanionFields() throws Exception {
|
public void testPrivateCompanionFields() throws Exception {
|
||||||
runTest("compiler/testData/codegen/bytecodeListing/privateCompanionFields.kt");
|
runTest("compiler/testData/codegen/bytecodeListing/privateCompanionFields.kt");
|
||||||
|
|||||||
Reference in New Issue
Block a user