JVM IR: add isInlineClassType, use it instead of isInlined
This commit is contained in:
+6
@@ -18018,6 +18018,12 @@ public class FirBlackBoxCodegenTestGenerated extends AbstractFirBlackBoxCodegenT
|
||||
runTest("compiler/testData/codegen/box/inlineClasses/resultRunCatchingOrElse.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("safeAsOfTypeParameterWithInlineClassBound.kt")
|
||||
public void testSafeAsOfTypeParameterWithInlineClassBound() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/inlineClasses/safeAsOfTypeParameterWithInlineClassBound.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("secondaryConstructorWithVararg.kt")
|
||||
public void testSecondaryConstructorWithVararg() throws Exception {
|
||||
|
||||
+2
-1
@@ -22,6 +22,7 @@ import org.jetbrains.kotlin.backend.common.ir.ir2string
|
||||
import org.jetbrains.kotlin.backend.jvm.JvmBackendContext
|
||||
import org.jetbrains.kotlin.backend.jvm.JvmLoweredDeclarationOrigin
|
||||
import org.jetbrains.kotlin.backend.jvm.JvmSymbols
|
||||
import org.jetbrains.kotlin.backend.jvm.ir.isInlineClassType
|
||||
import org.jetbrains.kotlin.builtins.StandardNames
|
||||
import org.jetbrains.kotlin.codegen.AsmUtil
|
||||
import org.jetbrains.kotlin.codegen.TypeAnnotationCollector
|
||||
@@ -275,7 +276,7 @@ abstract class AnnotationCodegen(
|
||||
is IrClassReference -> {
|
||||
var classType = value.classType
|
||||
classType.classOrNull?.owner?.let(innerClassConsumer::addInnerClassInfoFromAnnotation)
|
||||
if (classType.isInlined()) {
|
||||
if (classType.isInlineClassType()) {
|
||||
classType = classType.makeNullable()
|
||||
}
|
||||
annotationVisitor.visit(name, typeMapper.mapType(classType))
|
||||
|
||||
+5
-5
@@ -13,10 +13,12 @@ import org.jetbrains.kotlin.backend.jvm.intrinsics.IrIntrinsicMethods
|
||||
import org.jetbrains.kotlin.backend.jvm.intrinsics.JavaClassProperty
|
||||
import org.jetbrains.kotlin.backend.jvm.ir.erasedUpperBound
|
||||
import org.jetbrains.kotlin.backend.jvm.ir.isFromJava
|
||||
import org.jetbrains.kotlin.backend.jvm.ir.isInlineClassType
|
||||
import org.jetbrains.kotlin.backend.jvm.lower.MultifileFacadeFileEntry
|
||||
import org.jetbrains.kotlin.backend.jvm.lower.constantValue
|
||||
import org.jetbrains.kotlin.backend.jvm.lower.inlineclasses.isInlineCallableReference
|
||||
import org.jetbrains.kotlin.backend.jvm.lower.inlineclasses.isMappedToPrimitive
|
||||
import org.jetbrains.kotlin.backend.jvm.lower.inlineclasses.requiresMangling
|
||||
import org.jetbrains.kotlin.backend.jvm.lower.inlineclasses.unboxInlineClass
|
||||
import org.jetbrains.kotlin.backend.jvm.lower.isMultifileBridge
|
||||
import org.jetbrains.kotlin.backend.jvm.lower.suspendFunctionOriginal
|
||||
@@ -633,7 +635,7 @@ class ExpressionCodegen(
|
||||
// it generates them as normal functions and not objects.
|
||||
// Thus, we need to unbox inline class argument with reference underlying type.
|
||||
private fun unboxInlineClassArgumentOfInlineCallableReference(arg: IrGetValue) {
|
||||
if (!arg.type.erasedUpperBound.isInline) return
|
||||
if (!arg.type.isInlineClassType()) return
|
||||
if (arg.type.isMappedToPrimitive) return
|
||||
if (!irFunction.isInlineCallableReference) return
|
||||
if (irFunction.extensionReceiverParameter?.symbol == arg.symbol) return
|
||||
@@ -670,9 +672,7 @@ class ExpressionCodegen(
|
||||
|
||||
private fun IrClass.isSamAdapter(): Boolean = this.superTypes.any { it.getClass()?.isFun == true }
|
||||
|
||||
private fun onlyResultInlineClassParameters(): Boolean = irFunction.valueParameters.all {
|
||||
!it.type.erasedUpperBound.isInline || it.type.erasedUpperBound.fqNameWhenAvailable == StandardNames.RESULT_FQ_NAME
|
||||
}
|
||||
private fun onlyResultInlineClassParameters(): Boolean = irFunction.valueParameters.all { !it.type.requiresMangling }
|
||||
|
||||
private fun hasBridge(): Boolean = irFunction.parentAsClass.declarations.any { function ->
|
||||
function is IrFunction && function != irFunction &&
|
||||
@@ -699,7 +699,7 @@ class ExpressionCodegen(
|
||||
?: receiverType ?: typeMapper.mapClass(callee.parentAsClass)
|
||||
val ownerName = ownerType.internalName
|
||||
val fieldName = callee.name.asString()
|
||||
val calleeIrType = if (callee.isFromJava() && callee.type.isInlined()) callee.type.makeNullable() else callee.type
|
||||
val calleeIrType = if (callee.isFromJava() && callee.type.isInlineClassType()) callee.type.makeNullable() else callee.type
|
||||
val fieldType = calleeIrType.asmType
|
||||
return if (expression is IrSetField) {
|
||||
val value = expression.value.accept(this, data)
|
||||
|
||||
+3
-3
@@ -203,7 +203,7 @@ class MethodSignatureMapper(private val context: JvmBackendContext) {
|
||||
isBoxMethodForInlineClass(function) ||
|
||||
forceFoxedReturnTypeOnOverride(function) ||
|
||||
forceBoxedReturnTypeOnDefaultImplFun(function) ||
|
||||
function.isFromJava() && function.returnType.isInlined()
|
||||
function.isFromJava() && function.returnType.isInlineClassType()
|
||||
|
||||
private fun forceFoxedReturnTypeOnOverride(function: IrFunction) =
|
||||
function is IrSimpleFunction &&
|
||||
@@ -225,7 +225,7 @@ class MethodSignatureMapper(private val context: JvmBackendContext) {
|
||||
if (isBoundReceiver) return false
|
||||
if (function !is IrSimpleFunction) return false
|
||||
if (!function.isInlineCallableReference) return false
|
||||
return type.erasedUpperBound.isInline && !type.isMappedToPrimitive
|
||||
return type.isInlineClassType() && !type.isMappedToPrimitive
|
||||
}
|
||||
|
||||
fun mapSignatureSkipGeneric(function: IrFunction): JvmMethodSignature =
|
||||
@@ -341,7 +341,7 @@ class MethodSignatureMapper(private val context: JvmBackendContext) {
|
||||
|
||||
private fun writeParameterType(sw: JvmSignatureWriter, type: IrType, declaration: IrDeclaration, isReceiver: Boolean) {
|
||||
if (sw.skipGenericSignature()) {
|
||||
if (type.isInlined() &&
|
||||
if (type.isInlineClassType() &&
|
||||
(declaration.isFromJava() || forceBoxedInlineClassParametersForInliner(declaration, type, isReceiver))
|
||||
) {
|
||||
typeMapper.mapType(type, TypeMappingMode.GENERIC_ARGUMENT, sw)
|
||||
|
||||
@@ -400,3 +400,6 @@ fun IrClass.getSingleAbstractMethod(): IrSimpleFunction? =
|
||||
|
||||
fun IrFile.getKtFile(): KtFile? =
|
||||
(fileEntry as? PsiIrFileEntry)?.psiFile as KtFile?
|
||||
|
||||
fun IrType.isInlineClassType(): Boolean =
|
||||
erasedUpperBound.isInline
|
||||
|
||||
+3
-1
@@ -558,7 +558,9 @@ internal class FunctionReferenceLowering(private val context: JvmBackendContext)
|
||||
functionReferenceClass.addFunction {
|
||||
setSourceRange(if (isLambda) callee else irFunctionReference)
|
||||
name =
|
||||
if (samSuperType == null && callee.returnType.erasedUpperBound.isInline && context.state.functionsWithInlineClassReturnTypesMangled) {
|
||||
if (samSuperType == null && callee.returnType.isInlineClassType() &&
|
||||
context.state.functionsWithInlineClassReturnTypesMangled
|
||||
) {
|
||||
// For functions with inline class return type we need to mangle the invoke method.
|
||||
// Otherwise, bridge lowering may fail to generate bridges for inline class types erasing to Any.
|
||||
val suffix = InlineClassAbi.hashReturnSuffix(callee)
|
||||
|
||||
+2
-2
@@ -16,6 +16,7 @@ import org.jetbrains.kotlin.backend.jvm.codegen.fileParent
|
||||
import org.jetbrains.kotlin.backend.jvm.ir.createJvmIrBuilder
|
||||
import org.jetbrains.kotlin.backend.jvm.ir.erasedUpperBound
|
||||
import org.jetbrains.kotlin.backend.jvm.ir.getKtFile
|
||||
import org.jetbrains.kotlin.backend.jvm.ir.isInlineClassType
|
||||
import org.jetbrains.kotlin.ir.IrElement
|
||||
import org.jetbrains.kotlin.ir.UNDEFINED_OFFSET
|
||||
import org.jetbrains.kotlin.ir.builders.*
|
||||
@@ -29,7 +30,6 @@ import org.jetbrains.kotlin.ir.symbols.IrSimpleFunctionSymbol
|
||||
import org.jetbrains.kotlin.ir.symbols.IrTypeParameterSymbol
|
||||
import org.jetbrains.kotlin.ir.types.*
|
||||
import org.jetbrains.kotlin.ir.util.dump
|
||||
import org.jetbrains.kotlin.ir.util.isInlined
|
||||
import org.jetbrains.kotlin.ir.util.render
|
||||
import org.jetbrains.kotlin.ir.visitors.IrElementVisitorVoid
|
||||
import org.jetbrains.kotlin.ir.visitors.acceptChildrenVoid
|
||||
@@ -383,7 +383,7 @@ private class TypeOperatorLowering(private val context: JvmBackendContext) : Fil
|
||||
irType = context.irBuiltIns.anyNType
|
||||
) { valueSymbol ->
|
||||
val thenPart =
|
||||
if (valueSymbol.owner.type.isInlined())
|
||||
if (valueSymbol.owner.type.isInlineClassType())
|
||||
lowerCast(irGet(valueSymbol.owner), expression.typeOperand)
|
||||
else
|
||||
irGet(valueSymbol.owner)
|
||||
|
||||
+4
-3
@@ -6,6 +6,7 @@
|
||||
package org.jetbrains.kotlin.backend.jvm.lower.inlineclasses
|
||||
|
||||
import org.jetbrains.kotlin.backend.jvm.ir.erasedUpperBound
|
||||
import org.jetbrains.kotlin.backend.jvm.ir.isInlineClassType
|
||||
import org.jetbrains.kotlin.backend.jvm.lower.STUB_FOR_INLINING
|
||||
import org.jetbrains.kotlin.builtins.StandardNames
|
||||
import org.jetbrains.kotlin.codegen.state.InfoForMangling
|
||||
@@ -131,7 +132,7 @@ object InlineClassAbi {
|
||||
private fun IrType.asInfoForMangling(): InfoForMangling =
|
||||
InfoForMangling(
|
||||
erasedUpperBound.fqNameWhenAvailable!!.toUnsafe(),
|
||||
isInline = erasedUpperBound.isInline,
|
||||
isInline = isInlineClassType(),
|
||||
isNullable = isNullable()
|
||||
)
|
||||
|
||||
@@ -154,7 +155,7 @@ internal val IrFunction.hasMangledParameters: Boolean
|
||||
(this is IrConstructor && constructedClass.isInline)
|
||||
|
||||
internal val IrFunction.hasMangledReturnType: Boolean
|
||||
get() = returnType.erasedUpperBound.isInline && parentClassOrNull?.isFileClass != true
|
||||
get() = returnType.isInlineClassType() && parentClassOrNull?.isFileClass != true
|
||||
|
||||
private val IrClass.singlePrimaryConstructorParameter: IrValueParameter
|
||||
get() {
|
||||
@@ -178,6 +179,6 @@ val IrFunction.isInlineCallableReference: Boolean
|
||||
get() = origin == IrDeclarationOrigin.LOCAL_FUNCTION_FOR_LAMBDA && name.asString().contains("\$$STUB_FOR_INLINING")
|
||||
|
||||
val IrType.isMappedToPrimitive: Boolean
|
||||
get() = erasedUpperBound.isInline &&
|
||||
get() = isInlineClassType() &&
|
||||
!(isNullable() && makeNotNull().unboxInlineClass().isNullable()) &&
|
||||
makeNotNull().unboxInlineClass().isPrimitiveType()
|
||||
|
||||
@@ -17,12 +17,11 @@ import org.jetbrains.kotlin.ir.types.IrType
|
||||
import org.jetbrains.kotlin.ir.types.classifierOrFail
|
||||
import org.jetbrains.kotlin.ir.types.isMarkedNullable
|
||||
|
||||
|
||||
/**
|
||||
* Returns inline class for given class or null of type is not inlined
|
||||
* TODO: Make this configurable for different backends (currently implements logic of JS BE)
|
||||
*/
|
||||
fun IrType.getInlinedClass(): IrClass? {
|
||||
private fun IrType.getInlinedClass(): IrClass? {
|
||||
if (this is IrSimpleType) {
|
||||
val erased = erase(this) ?: return null
|
||||
if (erased.isInline) {
|
||||
@@ -45,6 +44,13 @@ fun IrType.getInlinedClass(): IrClass? {
|
||||
return null
|
||||
}
|
||||
|
||||
/**
|
||||
* Do not use this function in the JVM backend! Use `isInlineClassType` instead.
|
||||
*
|
||||
* This function has slightly different semantics for generic type parameters with inline class bounds.
|
||||
*
|
||||
* TODO: examine remaining usages in Native and preferably remove this function.
|
||||
*/
|
||||
fun IrType.isInlined(): Boolean = this.getInlinedClass() != null
|
||||
|
||||
private tailrec fun erase(type: IrType): IrClass? {
|
||||
|
||||
+8
@@ -0,0 +1,8 @@
|
||||
// IGNORE_BACKEND: JVM
|
||||
|
||||
interface X
|
||||
inline class Z(val value: Int) : X
|
||||
|
||||
fun <T> test(t: T) where T : X, T : Z = t as? Int
|
||||
|
||||
fun box(): String = if (test(Z(42)) != null) "fail" else "OK"
|
||||
+6
@@ -18018,6 +18018,12 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest {
|
||||
runTest("compiler/testData/codegen/box/inlineClasses/resultRunCatchingOrElse.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("safeAsOfTypeParameterWithInlineClassBound.kt")
|
||||
public void testSafeAsOfTypeParameterWithInlineClassBound() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/inlineClasses/safeAsOfTypeParameterWithInlineClassBound.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("secondaryConstructorWithVararg.kt")
|
||||
public void testSecondaryConstructorWithVararg() throws Exception {
|
||||
|
||||
+6
@@ -18018,6 +18018,12 @@ public class IrBlackBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTes
|
||||
runTest("compiler/testData/codegen/box/inlineClasses/resultRunCatchingOrElse.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("safeAsOfTypeParameterWithInlineClassBound.kt")
|
||||
public void testSafeAsOfTypeParameterWithInlineClassBound() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/inlineClasses/safeAsOfTypeParameterWithInlineClassBound.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("secondaryConstructorWithVararg.kt")
|
||||
public void testSecondaryConstructorWithVararg() throws Exception {
|
||||
|
||||
+2
-2
@@ -24,6 +24,7 @@ import com.intellij.mock.MockProject
|
||||
import com.intellij.openapi.project.Project
|
||||
import org.jetbrains.kotlin.backend.common.extensions.IrGenerationExtension
|
||||
import org.jetbrains.kotlin.backend.common.extensions.IrPluginContext
|
||||
import org.jetbrains.kotlin.backend.jvm.ir.isInlineClassType
|
||||
import org.jetbrains.kotlin.compiler.plugin.ComponentRegistrar
|
||||
import org.jetbrains.kotlin.config.CompilerConfiguration
|
||||
import org.jetbrains.kotlin.ir.IrStatement
|
||||
@@ -41,7 +42,6 @@ import org.jetbrains.kotlin.ir.types.IrType
|
||||
import org.jetbrains.kotlin.ir.types.isPrimitiveType
|
||||
import org.jetbrains.kotlin.ir.types.makeNullable
|
||||
import org.jetbrains.kotlin.ir.util.hasDefaultValue
|
||||
import org.jetbrains.kotlin.ir.util.isInlined
|
||||
import org.jetbrains.kotlin.ir.util.statements
|
||||
import org.jetbrains.kotlin.ir.visitors.IrElementTransformerVoid
|
||||
import org.jetbrains.kotlin.ir.visitors.transformChildrenVoid
|
||||
@@ -207,7 +207,7 @@ class ComposeLikeDefaultArgumentRewriter(
|
||||
val type = param.type
|
||||
return when {
|
||||
type.isPrimitiveType() -> type
|
||||
type.isInlined() -> type
|
||||
type.isInlineClassType() -> type
|
||||
else -> type.makeNullable()
|
||||
}
|
||||
}
|
||||
|
||||
+5
@@ -14941,6 +14941,11 @@ public class LightAnalysisModeTestGenerated extends AbstractLightAnalysisModeTes
|
||||
runTest("compiler/testData/codegen/box/inlineClasses/resultRunCatchingOrElse.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("safeAsOfTypeParameterWithInlineClassBound.kt")
|
||||
public void testSafeAsOfTypeParameterWithInlineClassBound() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/inlineClasses/safeAsOfTypeParameterWithInlineClassBound.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("secondaryConstructorWithVararg.kt")
|
||||
public void testSecondaryConstructorWithVararg() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/inlineClasses/secondaryConstructorWithVararg.kt");
|
||||
|
||||
js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/es6/semantics/IrJsCodegenBoxES6TestGenerated.java
Generated
+5
@@ -13120,6 +13120,11 @@ public class IrJsCodegenBoxES6TestGenerated extends AbstractIrJsCodegenBoxES6Tes
|
||||
runTest("compiler/testData/codegen/box/inlineClasses/resultRunCatchingOrElse.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("safeAsOfTypeParameterWithInlineClassBound.kt")
|
||||
public void testSafeAsOfTypeParameterWithInlineClassBound() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/inlineClasses/safeAsOfTypeParameterWithInlineClassBound.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("secondaryConstructorWithVararg.kt")
|
||||
public void testSecondaryConstructorWithVararg() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/inlineClasses/secondaryConstructorWithVararg.kt");
|
||||
|
||||
Generated
+5
@@ -12541,6 +12541,11 @@ public class IrJsCodegenBoxTestGenerated extends AbstractIrJsCodegenBoxTest {
|
||||
runTest("compiler/testData/codegen/box/inlineClasses/resultRunCatchingOrElse.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("safeAsOfTypeParameterWithInlineClassBound.kt")
|
||||
public void testSafeAsOfTypeParameterWithInlineClassBound() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/inlineClasses/safeAsOfTypeParameterWithInlineClassBound.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("secondaryConstructorWithVararg.kt")
|
||||
public void testSecondaryConstructorWithVararg() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/inlineClasses/secondaryConstructorWithVararg.kt");
|
||||
|
||||
Generated
+5
@@ -12606,6 +12606,11 @@ public class JsCodegenBoxTestGenerated extends AbstractJsCodegenBoxTest {
|
||||
runTest("compiler/testData/codegen/box/inlineClasses/resultRunCatchingOrElse.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("safeAsOfTypeParameterWithInlineClassBound.kt")
|
||||
public void testSafeAsOfTypeParameterWithInlineClassBound() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/inlineClasses/safeAsOfTypeParameterWithInlineClassBound.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("secondaryConstructorWithVararg.kt")
|
||||
public void testSecondaryConstructorWithVararg() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/inlineClasses/secondaryConstructorWithVararg.kt");
|
||||
|
||||
js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/wasm/semantics/IrCodegenBoxWasmTestGenerated.java
Generated
+5
@@ -6867,6 +6867,11 @@ public class IrCodegenBoxWasmTestGenerated extends AbstractIrCodegenBoxWasmTest
|
||||
runTest("compiler/testData/codegen/box/inlineClasses/resultInlining.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("safeAsOfTypeParameterWithInlineClassBound.kt")
|
||||
public void testSafeAsOfTypeParameterWithInlineClassBound() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/inlineClasses/safeAsOfTypeParameterWithInlineClassBound.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("secondaryConstructorWithVararg.kt")
|
||||
public void testSecondaryConstructorWithVararg() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/inlineClasses/secondaryConstructorWithVararg.kt");
|
||||
|
||||
Reference in New Issue
Block a user