diff --git a/compiler/ir/backend.jvm/lower/src/org/jetbrains/kotlin/backend/jvm/JvmLower.kt b/compiler/ir/backend.jvm/lower/src/org/jetbrains/kotlin/backend/jvm/JvmLower.kt index 89a2805b90f..6609d2ae023 100644 --- a/compiler/ir/backend.jvm/lower/src/org/jetbrains/kotlin/backend/jvm/JvmLower.kt +++ b/compiler/ir/backend.jvm/lower/src/org/jetbrains/kotlin/backend/jvm/JvmLower.kt @@ -326,6 +326,16 @@ private val apiVersionIsAtLeastEvaluationPhase = makeIrModulePhase( prerequisite = setOf(functionInliningPhase) ) +private val inlinedClassReferencesBoxingPhase = makeIrModulePhase( + { context -> + if (!context.irInlinerIsEnabled()) return@makeIrModulePhase FileLoweringPass.Empty + InlinedClassReferencesBoxingLowering(context) + }, + name = "InlinedClassReferencesBoxingLowering", + description = "Replace inlined primitive types in class references with boxed versions", + prerequisite = setOf(functionInliningPhase, markNecessaryInlinedClassesAsRegenerated) +) + private val constEvaluationPhase = makeIrModulePhase( ::ConstEvaluationLowering, name = "ConstEvaluationLowering", @@ -476,6 +486,7 @@ private fun buildJvmLoweringPhases( apiVersionIsAtLeastEvaluationPhase then createSeparateCallForInlinedLambdas then markNecessaryInlinedClassesAsRegenerated then + inlinedClassReferencesBoxingPhase then buildLoweringsPhase(phases) then generateMultifileFacadesPhase then diff --git a/compiler/ir/backend.jvm/lower/src/org/jetbrains/kotlin/backend/jvm/lower/InlinedClassReferencesBoxingLowering.kt b/compiler/ir/backend.jvm/lower/src/org/jetbrains/kotlin/backend/jvm/lower/InlinedClassReferencesBoxingLowering.kt new file mode 100644 index 00000000000..9dc5891ad54 --- /dev/null +++ b/compiler/ir/backend.jvm/lower/src/org/jetbrains/kotlin/backend/jvm/lower/InlinedClassReferencesBoxingLowering.kt @@ -0,0 +1,53 @@ +/* + * Copyright 2010-2023 JetBrains s.r.o. and Kotlin Programming Language contributors. + * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. + */ + +package org.jetbrains.kotlin.backend.jvm.lower + +import org.jetbrains.kotlin.backend.common.FileLoweringPass +import org.jetbrains.kotlin.backend.jvm.JvmBackendContext +import org.jetbrains.kotlin.backend.jvm.ir.getAttributeOwnerBeforeInline +import org.jetbrains.kotlin.ir.IrElement +import org.jetbrains.kotlin.ir.declarations.IrFile +import org.jetbrains.kotlin.ir.expressions.IrClassReference +import org.jetbrains.kotlin.ir.symbols.IrTypeParameterSymbol +import org.jetbrains.kotlin.ir.types.* +import org.jetbrains.kotlin.ir.types.impl.buildSimpleType +import org.jetbrains.kotlin.ir.util.render +import org.jetbrains.kotlin.ir.visitors.IrElementVisitorVoid +import org.jetbrains.kotlin.ir.visitors.acceptChildrenVoid + +internal class InlinedClassReferencesBoxingLowering(val context: JvmBackendContext) : FileLoweringPass, IrElementVisitorVoid { + override fun lower(irFile: IrFile) { + irFile.acceptChildrenVoid(this) + } + + override fun visitElement(element: IrElement) { + element.acceptChildrenVoid(this) + } + + override fun visitClassReference(expression: IrClassReference) { + super.visitClassReference(expression) + + val wasTypeParameterClassRefBeforeInline = + (expression.getAttributeOwnerBeforeInline() as? IrClassReference)?.classType?.classifierOrNull is IrTypeParameterSymbol + + if (wasTypeParameterClassRefBeforeInline && expression.classType.isPrimitiveType()) { + // Making primitive type nullable is effectively boxing + val boxedPrimitive = expression.classType.makeNullable() + require(boxedPrimitive is IrSimpleType) { + "Type is expected to be ${IrSimpleType::class.simpleName}: ${boxedPrimitive.render()}" + } + expression.classType = boxedPrimitive + val classReferenceType = expression.type + require(classReferenceType is IrSimpleType && classReferenceType.isKClass()) { + "Type of the type reference is expected to be KClass: ${classReferenceType.render()}" + } + expression.type = classReferenceType.buildSimpleType { + arguments = listOf(boxedPrimitive) + } + } + } + +} \ No newline at end of file diff --git a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/JvmSymbols.kt b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/JvmSymbols.kt index 5184da76b94..56a38617248 100644 --- a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/JvmSymbols.kt +++ b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/JvmSymbols.kt @@ -937,14 +937,14 @@ class JvmSymbols( throw AssertionError("Array type expected: ${arrayType.render()}") } - private val javaLangInteger: IrClassSymbol = createJavaPrimitiveClass(FqName("java.lang.Integer"), irBuiltIns.intType) + val javaLangInteger: IrClassSymbol = createJavaPrimitiveClass(FqName("java.lang.Integer"), irBuiltIns.intType) val compareUnsignedInt: IrSimpleFunctionSymbol = javaLangInteger.functionByName("compareUnsigned") val divideUnsignedInt: IrSimpleFunctionSymbol = javaLangInteger.functionByName("divideUnsigned") val remainderUnsignedInt: IrSimpleFunctionSymbol = javaLangInteger.functionByName("remainderUnsigned") val toUnsignedStringInt: IrSimpleFunctionSymbol = javaLangInteger.functionByName("toUnsignedString") - private val javaLangLong: IrClassSymbol = createJavaPrimitiveClass(FqName("java.lang.Long"), irBuiltIns.longType) + val javaLangLong: IrClassSymbol = createJavaPrimitiveClass(FqName("java.lang.Long"), irBuiltIns.longType) val compareUnsignedLong: IrSimpleFunctionSymbol = javaLangLong.functionByName("compareUnsigned") val divideUnsignedLong: IrSimpleFunctionSymbol = javaLangLong.functionByName("divideUnsigned") diff --git a/compiler/testData/codegen/box/classLiteral/java/javaReified.kt b/compiler/testData/codegen/box/classLiteral/java/javaReified.kt index 18d578ab8c1..b31ce10ad94 100644 --- a/compiler/testData/codegen/box/classLiteral/java/javaReified.kt +++ b/compiler/testData/codegen/box/classLiteral/java/javaReified.kt @@ -1,6 +1,4 @@ // TARGET_BACKEND: JVM -// IGNORE_INLINER: IR - // WITH_STDLIB inline fun check(expected: String) { diff --git a/compiler/testData/codegen/box/reflection/noReflectAtRuntime/reifiedTypeJavaClass.kt b/compiler/testData/codegen/box/reflection/noReflectAtRuntime/reifiedTypeJavaClass.kt index 9a06b35f7c4..5bacaedc9ec 100644 --- a/compiler/testData/codegen/box/reflection/noReflectAtRuntime/reifiedTypeJavaClass.kt +++ b/compiler/testData/codegen/box/reflection/noReflectAtRuntime/reifiedTypeJavaClass.kt @@ -1,6 +1,4 @@ // TARGET_BACKEND: JVM -// IGNORE_INLINER: IR - // WITH_STDLIB import kotlin.test.assertEquals diff --git a/compiler/testData/codegen/box/reified/DIExample.kt b/compiler/testData/codegen/box/reified/DIExample.kt index 331d09b85e1..bae38aeff1e 100644 --- a/compiler/testData/codegen/box/reified/DIExample.kt +++ b/compiler/testData/codegen/box/reified/DIExample.kt @@ -1,6 +1,4 @@ // TARGET_BACKEND: JVM -// IGNORE_INLINER: IR - // WITH_STDLIB import kotlin.test.assertEquals diff --git a/compiler/testData/codegen/box/reified/anonymousObjectNoPropagate.kt b/compiler/testData/codegen/box/reified/anonymousObjectNoPropagate.kt index fe1f73fdde4..ee6a929817c 100644 --- a/compiler/testData/codegen/box/reified/anonymousObjectNoPropagate.kt +++ b/compiler/testData/codegen/box/reified/anonymousObjectNoPropagate.kt @@ -1,6 +1,4 @@ // TARGET_BACKEND: JVM -// IGNORE_INLINER: IR - // WITH_STDLIB import kotlin.test.assertEquals diff --git a/compiler/testData/codegen/box/reified/defaultJavaClass.kt b/compiler/testData/codegen/box/reified/defaultJavaClass.kt index 211df96bdfa..590e90c847f 100644 --- a/compiler/testData/codegen/box/reified/defaultJavaClass.kt +++ b/compiler/testData/codegen/box/reified/defaultJavaClass.kt @@ -1,6 +1,4 @@ // TARGET_BACKEND: JVM -// IGNORE_INLINER: IR - // WITH_STDLIB import kotlin.test.assertEquals diff --git a/compiler/testData/codegen/box/reified/javaClass.kt b/compiler/testData/codegen/box/reified/javaClass.kt index 9077662e7f8..b4609156199 100644 --- a/compiler/testData/codegen/box/reified/javaClass.kt +++ b/compiler/testData/codegen/box/reified/javaClass.kt @@ -1,5 +1,4 @@ // TARGET_BACKEND: JVM -// IGNORE_INLINER: IR // WITH_STDLIB diff --git a/compiler/testData/codegen/box/reified/nestedReified.kt b/compiler/testData/codegen/box/reified/nestedReified.kt index 41ec86e583d..d9f90dc7928 100644 --- a/compiler/testData/codegen/box/reified/nestedReified.kt +++ b/compiler/testData/codegen/box/reified/nestedReified.kt @@ -1,6 +1,4 @@ // TARGET_BACKEND: JVM -// IGNORE_INLINER: IR - // WITH_STDLIB import kotlin.test.assertEquals diff --git a/compiler/testData/codegen/box/reified/nonInlineableLambdaInReifiedFunction.kt b/compiler/testData/codegen/box/reified/nonInlineableLambdaInReifiedFunction.kt index 62b90aca394..5fa026d1b37 100644 --- a/compiler/testData/codegen/box/reified/nonInlineableLambdaInReifiedFunction.kt +++ b/compiler/testData/codegen/box/reified/nonInlineableLambdaInReifiedFunction.kt @@ -1,6 +1,4 @@ // TARGET_BACKEND: JVM -// IGNORE_INLINER: IR - // WITH_STDLIB import kotlin.test.assertEquals diff --git a/compiler/testData/codegen/box/reified/recursiveNonInlineableLambda.kt b/compiler/testData/codegen/box/reified/recursiveNonInlineableLambda.kt index 484cd05c0f7..6e37784b6a1 100644 --- a/compiler/testData/codegen/box/reified/recursiveNonInlineableLambda.kt +++ b/compiler/testData/codegen/box/reified/recursiveNonInlineableLambda.kt @@ -1,6 +1,4 @@ // TARGET_BACKEND: JVM -// IGNORE_INLINER: IR - // WITH_STDLIB import kotlin.test.assertEquals diff --git a/compiler/testData/codegen/box/reified/reifiedInlineFunOfObject.kt b/compiler/testData/codegen/box/reified/reifiedInlineFunOfObject.kt index f269016c30f..614856f6adf 100644 --- a/compiler/testData/codegen/box/reified/reifiedInlineFunOfObject.kt +++ b/compiler/testData/codegen/box/reified/reifiedInlineFunOfObject.kt @@ -1,6 +1,4 @@ // TARGET_BACKEND: JVM -// IGNORE_INLINER: IR - // WITH_STDLIB import kotlin.test.assertEquals diff --git a/compiler/testData/codegen/box/reified/reifiedInlineFunOfObjectWithinReified.kt b/compiler/testData/codegen/box/reified/reifiedInlineFunOfObjectWithinReified.kt index 804b1799e19..68c11556c1a 100644 --- a/compiler/testData/codegen/box/reified/reifiedInlineFunOfObjectWithinReified.kt +++ b/compiler/testData/codegen/box/reified/reifiedInlineFunOfObjectWithinReified.kt @@ -1,6 +1,4 @@ // TARGET_BACKEND: JVM -// IGNORE_INLINER: IR - // WITH_STDLIB import kotlin.test.assertEquals diff --git a/compiler/testData/codegen/box/reified/reifiedInlineIntoNonInlineableLambda.kt b/compiler/testData/codegen/box/reified/reifiedInlineIntoNonInlineableLambda.kt index 8ab462e7d89..fd92059db52 100644 --- a/compiler/testData/codegen/box/reified/reifiedInlineIntoNonInlineableLambda.kt +++ b/compiler/testData/codegen/box/reified/reifiedInlineIntoNonInlineableLambda.kt @@ -1,6 +1,4 @@ // TARGET_BACKEND: JVM -// IGNORE_INLINER: IR - // WITH_STDLIB import kotlin.test.assertEquals