diff --git a/compiler/fir/fir2ir/tests-gen/org/jetbrains/kotlin/test/runners/codegen/FirBlackBoxCodegenTestGenerated.java b/compiler/fir/fir2ir/tests-gen/org/jetbrains/kotlin/test/runners/codegen/FirBlackBoxCodegenTestGenerated.java index b849da2ce2e..d4ab8066c48 100644 --- a/compiler/fir/fir2ir/tests-gen/org/jetbrains/kotlin/test/runners/codegen/FirBlackBoxCodegenTestGenerated.java +++ b/compiler/fir/fir2ir/tests-gen/org/jetbrains/kotlin/test/runners/codegen/FirBlackBoxCodegenTestGenerated.java @@ -18850,6 +18850,12 @@ public class FirBlackBoxCodegenTestGenerated extends AbstractFirBlackBoxCodegenT runTest("compiler/testData/codegen/box/inlineClasses/kt46554.kt"); } + @Test + @TestMetadata("kt47609.kt") + public void testKt47609() throws Exception { + runTest("compiler/testData/codegen/box/inlineClasses/kt47609.kt"); + } + @Test @TestMetadata("mangledDefaultParameterFunction.kt") public void testMangledDefaultParameterFunction() throws Exception { diff --git a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/lower/JvmPropertiesLowering.kt b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/lower/JvmPropertiesLowering.kt index 5314180b0f3..2caa587ae7d 100644 --- a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/lower/JvmPropertiesLowering.kt +++ b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/lower/JvmPropertiesLowering.kt @@ -11,6 +11,7 @@ import org.jetbrains.kotlin.backend.common.ir.copyTo import org.jetbrains.kotlin.backend.common.lower.createIrBuilder import org.jetbrains.kotlin.backend.jvm.JvmBackendContext import org.jetbrains.kotlin.backend.jvm.JvmLoweredDeclarationOrigin +import org.jetbrains.kotlin.backend.jvm.ir.eraseTypeParameters import org.jetbrains.kotlin.backend.jvm.ir.needsAccessor import org.jetbrains.kotlin.backend.jvm.lower.inlineclasses.hasMangledReturnType import org.jetbrains.kotlin.backend.jvm.lower.inlineclasses.requiresMangling @@ -27,7 +28,7 @@ import org.jetbrains.kotlin.ir.expressions.IrExpression import org.jetbrains.kotlin.ir.expressions.IrFieldAccessExpression import org.jetbrains.kotlin.ir.expressions.impl.IrBlockBodyImpl import org.jetbrains.kotlin.ir.types.* -import org.jetbrains.kotlin.ir.types.impl.makeTypeProjection +import org.jetbrains.kotlin.ir.types.impl.IrUninitializedType import org.jetbrains.kotlin.ir.util.* import org.jetbrains.kotlin.ir.visitors.transformChildrenVoid import org.jetbrains.kotlin.load.java.JvmAbi @@ -157,73 +158,54 @@ class JvmPropertiesLowering(private val backendContext: JvmBackendContext) : IrE accessor != null && !property.needsAccessor(accessor) private fun createSyntheticMethodForAnnotations(declaration: IrProperty): IrSimpleFunction = - backendContext.irFactory.buildFun { - origin = JvmLoweredDeclarationOrigin.SYNTHETIC_METHOD_FOR_PROPERTY_OR_TYPEALIAS_ANNOTATIONS - name = Name.identifier(computeSyntheticMethodName(declaration)) - visibility = declaration.visibility - modality = Modality.OPEN + backendContext.createSyntheticMethodForProperty( + declaration, + JvmAbi.ANNOTATED_PROPERTY_METHOD_NAME_SUFFIX, + JvmLoweredDeclarationOrigin.SYNTHETIC_METHOD_FOR_PROPERTY_OR_TYPEALIAS_ANNOTATIONS, + // TODO: technically JVM permits having fields with same name but different type, so we could potentially + // generate two properties like that; should this be the getter's return type instead? returnType = backendContext.irBuiltIns.unitType - }.apply { - declaration.getter?.extensionReceiverParameter?.let { extensionReceiver -> - extensionReceiverParameter = extensionReceiver.copyTo( - this, - type = extensionReceiver.type.erasePropertyAnnotationsExtensionReceiverType() - ) - } - + ).apply { body = IrBlockBodyImpl(UNDEFINED_OFFSET, UNDEFINED_OFFSET) - parent = declaration.parent - annotations = declaration.annotations + } + + companion object { + private fun JvmBackendContext.createSyntheticMethodForProperty( + declaration: IrProperty, + suffix: String, + origin: IrDeclarationOrigin, + returnType: IrType = IrUninitializedType + ) = irFactory.buildFun { + name = Name.identifier(computeSyntheticMethodName(declaration, suffix)) + modality = Modality.OPEN + visibility = declaration.visibility + this.origin = origin + this.returnType = returnType + }.apply { + declaration.getter?.extensionReceiverParameter?.let { + // Synthetic methods don't get generic type signatures anyway, so not exactly useful to preserve type parameters. + extensionReceiverParameter = it.copyTo(this, type = it.type.eraseTypeParameters()) + } + parent = declaration.parent metadata = declaration.metadata } - private fun IrType.erasePropertyAnnotationsExtensionReceiverType(): IrType { - // Use raw type of extension receiver to avoid generic signature, - // which should not be generated for '...$annotations' method. - if (this !is IrSimpleType) { - throw AssertionError("Unexpected property receiver type: $this") - } - val erasedType = if (isArray()) { - when (val arg0 = arguments[0]) { - is IrStarProjection -> { - // 'Array<*>' becomes 'Array<*>' - this + private fun JvmBackendContext.computeSyntheticMethodName(property: IrProperty, suffix: String): String { + val baseName = + if (state.languageVersionSettings.supportsFeature(LanguageFeature.UseGetterNameForPropertyAnnotationsMethodOnJvm)) { + val getter = property.getter + if (getter != null) { + val needsMangling = + getter.extensionReceiverParameter?.type?.requiresMangling == true || + (state.functionsWithInlineClassReturnTypesMangled && getter.hasMangledReturnType) + val mangled = if (needsMangling) inlineClassReplacements.getReplacementFunction(getter) else null + methodSignatureMapper.mapFunctionName(mangled ?: getter) + } else JvmAbi.getterName(property.name.asString()) + } else { + property.name.asString() } - is IrTypeProjection -> { - // 'Array' becomes 'Array' - classifier.typeWithArguments( - listOf(makeTypeProjection(arg0.type.erasePropertyAnnotationsExtensionReceiverType(), arg0.variance)) - ) - } - else -> - throw AssertionError("Unexpected type argument: $arg0") - } - } else { - classifier.typeWith() + return baseName + suffix } - return erasedType - .withHasQuestionMark(this.hasQuestionMark) - .addAnnotations(this.annotations) - } - - private fun computeSyntheticMethodName(property: IrProperty): String { - val baseName = - if (backendContext.state.languageVersionSettings.supportsFeature(LanguageFeature.UseGetterNameForPropertyAnnotationsMethodOnJvm)) { - val getter = property.getter - if (getter != null) { - val needsMangling = - getter.extensionReceiverParameter?.type?.requiresMangling == true || - (backendContext.state.functionsWithInlineClassReturnTypesMangled && getter.hasMangledReturnType) - - backendContext.methodSignatureMapper.mapFunctionName( - if (needsMangling) backendContext.inlineClassReplacements.getReplacementFunction(getter) ?: getter - else getter - ) - } else JvmAbi.getterName(property.name.asString()) - } else { - property.name.asString() - } - return JvmAbi.getSyntheticMethodNameForAnnotatedProperty(baseName) } } diff --git a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/lower/PropertyReferenceLowering.kt b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/lower/PropertyReferenceLowering.kt index 6e099e403a7..a6c23087b32 100644 --- a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/lower/PropertyReferenceLowering.kt +++ b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/lower/PropertyReferenceLowering.kt @@ -121,8 +121,12 @@ private class PropertyReferenceLowering(val context: JvmBackendContext) : IrElem // Internal underlying vals of inline classes have no getter method getter.owner.isInlineClassFieldGetter && getter.owner.visibility == DescriptorVisibilities.INTERNAL val origin = if (needsDummySignature) InlineClassAbi.UNMANGLED_FUNCTION_REFERENCE else null - val reference = - IrFunctionReferenceImpl.fromSymbolOwner(UNDEFINED_OFFSET, UNDEFINED_OFFSET, expression.type, getter, 0, getter, origin) + val reference = IrFunctionReferenceImpl.fromSymbolOwner( + startOffset, endOffset, expression.type, getter, getter.owner.typeParameters.size, getter, origin + ) + for ((index, parameter) in getter.owner.typeParameters.withIndex()) { + reference.putTypeArgument(index, parameter.erasedUpperBound.defaultType) + } return irCall(signatureStringIntrinsic).apply { putValueArgument(0, reference) } } diff --git a/compiler/testData/codegen/box/inlineClasses/kt47609.kt b/compiler/testData/codegen/box/inlineClasses/kt47609.kt new file mode 100644 index 00000000000..fc0fc4af475 --- /dev/null +++ b/compiler/testData/codegen/box/inlineClasses/kt47609.kt @@ -0,0 +1,11 @@ +// WITH_REFLECT +// TARGET_BACKEND: JVM +annotation class Ann(val value: String) + +inline class C(val x: String) + +@Ann("OK") +val C.value: String + get() = x + +fun box() = (C::value.annotations.singleOrNull() as? Ann)?.value ?: "null" diff --git a/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/BlackBoxCodegenTestGenerated.java b/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/BlackBoxCodegenTestGenerated.java index 50439138d4e..b9ee78a9ab5 100644 --- a/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/BlackBoxCodegenTestGenerated.java +++ b/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/BlackBoxCodegenTestGenerated.java @@ -18808,6 +18808,12 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest { runTest("compiler/testData/codegen/box/inlineClasses/kt46554.kt"); } + @Test + @TestMetadata("kt47609.kt") + public void testKt47609() throws Exception { + runTest("compiler/testData/codegen/box/inlineClasses/kt47609.kt"); + } + @Test @TestMetadata("mangledDefaultParameterFunction.kt") public void testMangledDefaultParameterFunction() throws Exception { diff --git a/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/IrBlackBoxCodegenTestGenerated.java b/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/IrBlackBoxCodegenTestGenerated.java index 951a1e369a5..7e9bf8f6f75 100644 --- a/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/IrBlackBoxCodegenTestGenerated.java +++ b/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/IrBlackBoxCodegenTestGenerated.java @@ -18850,6 +18850,12 @@ public class IrBlackBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTes runTest("compiler/testData/codegen/box/inlineClasses/kt46554.kt"); } + @Test + @TestMetadata("kt47609.kt") + public void testKt47609() throws Exception { + runTest("compiler/testData/codegen/box/inlineClasses/kt47609.kt"); + } + @Test @TestMetadata("mangledDefaultParameterFunction.kt") public void testMangledDefaultParameterFunction() throws Exception { diff --git a/compiler/tests-gen/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java b/compiler/tests-gen/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java index a60071f0279..e04aa82b798 100644 --- a/compiler/tests-gen/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java +++ b/compiler/tests-gen/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java @@ -15598,6 +15598,11 @@ public class LightAnalysisModeTestGenerated extends AbstractLightAnalysisModeTes runTest("compiler/testData/codegen/box/inlineClasses/kt46554.kt"); } + @TestMetadata("kt47609.kt") + public void testKt47609() throws Exception { + runTest("compiler/testData/codegen/box/inlineClasses/kt47609.kt"); + } + @TestMetadata("mangledDefaultParameterFunction.kt") public void testMangledDefaultParameterFunction() throws Exception { runTest("compiler/testData/codegen/box/inlineClasses/mangledDefaultParameterFunction.kt");