diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/state/JetTypeMapper.java b/compiler/backend/src/org/jetbrains/kotlin/codegen/state/JetTypeMapper.java index 6038fbf6d04..86ddc2cf0f2 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/state/JetTypeMapper.java +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/state/JetTypeMapper.java @@ -44,6 +44,7 @@ import org.jetbrains.kotlin.load.java.descriptors.JavaCallableMemberDescriptor; import org.jetbrains.kotlin.load.java.descriptors.JavaClassDescriptor; import org.jetbrains.kotlin.load.java.lazy.descriptors.LazyJavaPackageFragment; import org.jetbrains.kotlin.load.java.lazy.descriptors.LazyJavaPackageScope; +import org.jetbrains.kotlin.load.java.typeEnhancement.TypeEnhancementKt; import org.jetbrains.kotlin.load.kotlin.KotlinJvmBinaryClass; import org.jetbrains.kotlin.load.kotlin.KotlinJvmBinaryPackageSourceElement; import org.jetbrains.kotlin.load.kotlin.KotlinJvmBinarySourceElement; @@ -510,7 +511,8 @@ public class JetTypeMapper { PrimitiveType primitiveType = KotlinBuiltIns.getPrimitiveTypeByFqName(fqName); if (primitiveType != null) { Type asmType = Type.getType(JvmPrimitiveType.get(primitiveType).getDesc()); - return TypeUtils.isNullableType(type) ? boxType(asmType) : asmType; + boolean isNullableInJava = TypeUtils.isNullableType(type) || TypeEnhancementKt.hasEnhancedNullability(type); + return isNullableInJava ? boxType(asmType) : asmType; } PrimitiveType arrayElementType = KotlinBuiltIns.getPrimitiveTypeByArrayClassFqName(fqName); diff --git a/compiler/frontend.java/src/org/jetbrains/kotlin/jvm/RuntimeAssertions.kt b/compiler/frontend.java/src/org/jetbrains/kotlin/jvm/RuntimeAssertions.kt index 71e2a0254d2..41e6aa4f816 100644 --- a/compiler/frontend.java/src/org/jetbrains/kotlin/jvm/RuntimeAssertions.kt +++ b/compiler/frontend.java/src/org/jetbrains/kotlin/jvm/RuntimeAssertions.kt @@ -20,6 +20,7 @@ import com.intellij.openapi.util.text.StringUtil import org.jetbrains.kotlin.descriptors.ReceiverParameterDescriptor import org.jetbrains.kotlin.load.java.JvmAnnotationNames import org.jetbrains.kotlin.jvm.bindingContextSlices.RUNTIME_ASSERTION_INFO +import org.jetbrains.kotlin.load.java.typeEnhancement.hasEnhancedNullability import org.jetbrains.kotlin.psi.KtExpression import org.jetbrains.kotlin.resolve.BindingContext import org.jetbrains.kotlin.resolve.calls.checkers.AdditionalTypeChecker @@ -74,9 +75,6 @@ class RuntimeAssertionInfo(val needNotNullAssertion: Boolean, val message: Strin else null } - - private fun KotlinType.hasEnhancedNullability() - = annotations.findAnnotation(JvmAnnotationNames.ENHANCED_NULLABILITY_ANNOTATION) != null } } diff --git a/compiler/testData/codegen/box/platformTypes/primitives/identityEquals.kt b/compiler/testData/codegen/box/platformTypes/primitives/identityEquals.kt index aa76e30caae..f033a86bf33 100644 --- a/compiler/testData/codegen/box/platformTypes/primitives/identityEquals.kt +++ b/compiler/testData/codegen/box/platformTypes/primitives/identityEquals.kt @@ -3,7 +3,7 @@ fun box(): String { l.add(1000) val x = l[0] === 1000 - if (!x) return "Fail: $x" + if (x) return "Fail: $x" val x1 = l[0] === 1 if (x1) return "Fail 1: $x" val x2 = l[0] === l[0] diff --git a/compiler/testData/codegen/boxWithJava/enhancedPrimitives/J.java b/compiler/testData/codegen/boxWithJava/enhancedPrimitives/J.java new file mode 100644 index 00000000000..eef9a061740 --- /dev/null +++ b/compiler/testData/codegen/boxWithJava/enhancedPrimitives/J.java @@ -0,0 +1,7 @@ +public class J { + // This test checks that although type '@org.jetbrains.annotations.NotNull Integer' is perceived as simple Int, + // it's correctly mapped to 'Lj.l.Integer' by JVM backend + public static String test(@org.jetbrains.annotations.NotNull Integer x) { + return "OK"; + } +} diff --git a/compiler/testData/codegen/boxWithJava/enhancedPrimitives/box.kt b/compiler/testData/codegen/boxWithJava/enhancedPrimitives/box.kt new file mode 100644 index 00000000000..c64158e4833 --- /dev/null +++ b/compiler/testData/codegen/boxWithJava/enhancedPrimitives/box.kt @@ -0,0 +1 @@ +fun box() = J.test(1) diff --git a/compiler/tests/org/jetbrains/kotlin/codegen/generated/BlackBoxWithJavaCodegenTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/codegen/generated/BlackBoxWithJavaCodegenTestGenerated.java index 8d582b48383..a8105208752 100644 --- a/compiler/tests/org/jetbrains/kotlin/codegen/generated/BlackBoxWithJavaCodegenTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/codegen/generated/BlackBoxWithJavaCodegenTestGenerated.java @@ -77,6 +77,12 @@ public class BlackBoxWithJavaCodegenTestGenerated extends AbstractBlackBoxCodege doTestWithJava(fileName); } + @TestMetadata("enhancedPrimitives") + public void testEnhancedPrimitives() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/boxWithJava/enhancedPrimitives/"); + doTestWithJava(fileName); + } + @TestMetadata("inline") public void testInline() throws Exception { String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/boxWithJava/inline/"); diff --git a/core/descriptor.loader.java/src/org/jetbrains/kotlin/load/java/typeEnhancement/typeEnhancement.kt b/core/descriptor.loader.java/src/org/jetbrains/kotlin/load/java/typeEnhancement/typeEnhancement.kt index 8e724187a62..ff6eaf263a7 100644 --- a/core/descriptor.loader.java/src/org/jetbrains/kotlin/load/java/typeEnhancement/typeEnhancement.kt +++ b/core/descriptor.loader.java/src/org/jetbrains/kotlin/load/java/typeEnhancement/typeEnhancement.kt @@ -42,6 +42,8 @@ import org.jetbrains.kotlin.utils.toReadOnlyList // For flexible types, both bounds are indexed in the same way: `(A..C)` gives `0 - (A..C), 1 - B and D`. fun KotlinType.enhance(qualifiers: (Int) -> JavaTypeQualifiers) = this.enhancePossiblyFlexible(qualifiers, 0).typeIfChanged +fun KotlinType.hasEnhancedNullability() + = annotations.findAnnotation(JvmAnnotationNames.ENHANCED_NULLABILITY_ANNOTATION) != null private enum class TypeComponentPosition { FLEXIBLE_LOWER,