From ed79891ee6e3341c8dc7afb800e26d024ad3e033 Mon Sep 17 00:00:00 2001 From: Denis Zharkov Date: Thu, 31 Aug 2017 12:38:08 +0300 Subject: [PATCH] Fix type mapping for parameter of Collection::remove override In the case the single parameter of override has `Integer` type instead of `int` type (while in common case it would be just `int`) See the comment inside forceSingleValueParameterBoxing for clarification #KT-19892 Fixed --- .../kotlin/codegen/ExpressionCodegen.java | 16 ++++++++++++++-- .../box/specialBuiltins/removeSetInt.kt | 18 ++++++++++++++++++ .../ir/IrBlackBoxCodegenTestGenerated.java | 6 ++++++ .../codegen/BlackBoxCodegenTestGenerated.java | 6 ++++++ .../LightAnalysisModeTestGenerated.java | 6 ++++++ .../load/kotlin/methodSignatureMapping.kt | 4 +++- .../semantics/JsCodegenBoxTestGenerated.java | 6 ++++++ 7 files changed, 59 insertions(+), 3 deletions(-) create mode 100644 compiler/testData/codegen/box/specialBuiltins/removeSetInt.kt diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/ExpressionCodegen.java b/compiler/backend/src/org/jetbrains/kotlin/codegen/ExpressionCodegen.java index 5e4428a0e5c..a9e8d8618be 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/ExpressionCodegen.java +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/ExpressionCodegen.java @@ -61,6 +61,7 @@ import org.jetbrains.kotlin.diagnostics.Errors; import org.jetbrains.kotlin.lexer.KtTokens; import org.jetbrains.kotlin.load.java.JvmAbi; import org.jetbrains.kotlin.load.java.sam.SamConstructorDescriptor; +import org.jetbrains.kotlin.load.kotlin.MethodSignatureMappingKt; import org.jetbrains.kotlin.load.kotlin.TypeSignatureMappingKt; import org.jetbrains.kotlin.name.Name; import org.jetbrains.kotlin.psi.*; @@ -1284,8 +1285,19 @@ public class ExpressionCodegen extends KtVisitor impleme KotlinType varType = isDelegatedLocalVariable(variableDescriptor) ? JvmCodegenUtil.getPropertyDelegateType((VariableDescriptorWithAccessors) variableDescriptor, bindingContext) : variableDescriptor.getType(); - //noinspection ConstantConditions - return asmType(varType); + + if (variableDescriptor instanceof ValueParameterDescriptor && + MethodSignatureMappingKt.forceSingleValueParameterBoxing( + (CallableDescriptor) variableDescriptor.getContainingDeclaration() + ) + ) { + //noinspection ConstantConditions + return asmType(TypeUtils.makeNullable(varType)); + } + else { + //noinspection ConstantConditions + return asmType(varType); + } } private void putDescriptorIntoFrameMap(@NotNull KtElement statement) { diff --git a/compiler/testData/codegen/box/specialBuiltins/removeSetInt.kt b/compiler/testData/codegen/box/specialBuiltins/removeSetInt.kt new file mode 100644 index 00000000000..868c5c6bc4b --- /dev/null +++ b/compiler/testData/codegen/box/specialBuiltins/removeSetInt.kt @@ -0,0 +1,18 @@ +class MySet : HashSet() { + override fun remove(element: Int): Boolean { + return super.remove(element) + } +} + +fun box(): String { + val a = MySet() + a.add(1) + a.add(2) + a.add(3) + + if (!a.remove(1)) return "fail 1" + if (a.remove(1)) return "fail 2" + if (a.contains(1)) return "fail 3" + + return "OK" +} diff --git a/compiler/tests-ir-jvm/tests/org/jetbrains/kotlin/codegen/ir/IrBlackBoxCodegenTestGenerated.java b/compiler/tests-ir-jvm/tests/org/jetbrains/kotlin/codegen/ir/IrBlackBoxCodegenTestGenerated.java index 562c4e63ec6..659c0082dfd 100644 --- a/compiler/tests-ir-jvm/tests/org/jetbrains/kotlin/codegen/ir/IrBlackBoxCodegenTestGenerated.java +++ b/compiler/tests-ir-jvm/tests/org/jetbrains/kotlin/codegen/ir/IrBlackBoxCodegenTestGenerated.java @@ -18080,6 +18080,12 @@ public class IrBlackBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTes doTest(fileName); } + @TestMetadata("removeSetInt.kt") + public void testRemoveSetInt() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/specialBuiltins/removeSetInt.kt"); + doTest(fileName); + } + @TestMetadata("throwable.kt") public void testThrowable() throws Exception { String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/specialBuiltins/throwable.kt"); diff --git a/compiler/tests/org/jetbrains/kotlin/codegen/BlackBoxCodegenTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/codegen/BlackBoxCodegenTestGenerated.java index 23d951696af..58890b421b0 100644 --- a/compiler/tests/org/jetbrains/kotlin/codegen/BlackBoxCodegenTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/codegen/BlackBoxCodegenTestGenerated.java @@ -18080,6 +18080,12 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest { doTest(fileName); } + @TestMetadata("removeSetInt.kt") + public void testRemoveSetInt() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/specialBuiltins/removeSetInt.kt"); + doTest(fileName); + } + @TestMetadata("throwable.kt") public void testThrowable() throws Exception { String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/specialBuiltins/throwable.kt"); diff --git a/compiler/tests/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java index e71d90ab6b6..7c4799b0c49 100644 --- a/compiler/tests/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java @@ -18080,6 +18080,12 @@ public class LightAnalysisModeTestGenerated extends AbstractLightAnalysisModeTes doTest(fileName); } + @TestMetadata("removeSetInt.kt") + public void testRemoveSetInt() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/specialBuiltins/removeSetInt.kt"); + doTest(fileName); + } + @TestMetadata("throwable.kt") public void testThrowable() throws Exception { String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/specialBuiltins/throwable.kt"); diff --git a/core/descriptor.loader.java/src/org/jetbrains/kotlin/load/kotlin/methodSignatureMapping.kt b/core/descriptor.loader.java/src/org/jetbrains/kotlin/load/kotlin/methodSignatureMapping.kt index 123671206ae..9b94738ef07 100644 --- a/core/descriptor.loader.java/src/org/jetbrains/kotlin/load/kotlin/methodSignatureMapping.kt +++ b/core/descriptor.loader.java/src/org/jetbrains/kotlin/load/kotlin/methodSignatureMapping.kt @@ -52,7 +52,9 @@ fun FunctionDescriptor.computeJvmDescriptor(withReturnType: Boolean = true) // Boxing is only necessary for 'remove(E): Boolean' of a MutableCollection implementation // Otherwise this method might clash with 'remove(I): E' defined in the java.util.List JDK interface (mapped to kotlin 'removeAt') -fun forceSingleValueParameterBoxing(f: FunctionDescriptor): Boolean { +fun forceSingleValueParameterBoxing(f: CallableDescriptor): Boolean { + if (f !is FunctionDescriptor) return false + if (f.valueParameters.size != 1 || f.isFromJavaOrBuiltins() || f.name.asString() != "remove") return false if ((f.original.valueParameters.single().type.mapToJvmType() as? JvmType.Primitive)?.jvmPrimitiveType != JvmPrimitiveType.INT) return false diff --git a/js/js.tests/test/org/jetbrains/kotlin/js/test/semantics/JsCodegenBoxTestGenerated.java b/js/js.tests/test/org/jetbrains/kotlin/js/test/semantics/JsCodegenBoxTestGenerated.java index 55388d0ec83..b999e5eb49e 100644 --- a/js/js.tests/test/org/jetbrains/kotlin/js/test/semantics/JsCodegenBoxTestGenerated.java +++ b/js/js.tests/test/org/jetbrains/kotlin/js/test/semantics/JsCodegenBoxTestGenerated.java @@ -22076,6 +22076,12 @@ public class JsCodegenBoxTestGenerated extends AbstractJsCodegenBoxTest { doTest(fileName); } + @TestMetadata("removeSetInt.kt") + public void testRemoveSetInt() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/specialBuiltins/removeSetInt.kt"); + doTest(fileName); + } + @TestMetadata("throwable.kt") public void testThrowable() throws Exception { String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/specialBuiltins/throwable.kt");