diff --git a/compiler/frontend.java/src/org/jetbrains/kotlin/resolve/jvm/checkers/JvmFieldApplicabilityChecker.kt b/compiler/frontend.java/src/org/jetbrains/kotlin/resolve/jvm/checkers/JvmFieldApplicabilityChecker.kt index 1a3b3328463..de0a6f5d4e2 100644 --- a/compiler/frontend.java/src/org/jetbrains/kotlin/resolve/jvm/checkers/JvmFieldApplicabilityChecker.kt +++ b/compiler/frontend.java/src/org/jetbrains/kotlin/resolve/jvm/checkers/JvmFieldApplicabilityChecker.kt @@ -28,9 +28,11 @@ import org.jetbrains.kotlin.resolve.DescriptorToSourceUtils import org.jetbrains.kotlin.resolve.DescriptorUtils import org.jetbrains.kotlin.resolve.checkers.DeclarationChecker import org.jetbrains.kotlin.resolve.checkers.DeclarationCheckerContext +import org.jetbrains.kotlin.resolve.isInlineClassType import org.jetbrains.kotlin.resolve.jvm.annotations.findJvmFieldAnnotation import org.jetbrains.kotlin.resolve.jvm.checkers.JvmFieldApplicabilityChecker.Problem.* import org.jetbrains.kotlin.resolve.jvm.diagnostics.ErrorsJvm +import org.jetbrains.kotlin.resolve.jvm.isInlineClassThatRequiresMangling import org.jetbrains.kotlin.resolve.scopes.DescriptorKindFilter import org.jetbrains.kotlin.resolve.scopes.MemberScope @@ -46,7 +48,8 @@ class JvmFieldApplicabilityChecker : DeclarationChecker { INSIDE_COMPANION_OF_INTERFACE("JvmField cannot be applied to a property defined in companion object of interface"), NOT_PUBLIC_VAL_WITH_JVMFIELD("JvmField could be applied only if all interface companion properties are 'public final val' with '@JvmField' annotation"), TOP_LEVEL_PROPERTY_OF_MULTIFILE_FACADE("JvmField cannot be applied to top level property of a file annotated with ${JvmFileClassUtil.JVM_MULTIFILE_CLASS_SHORT}"), - DELEGATE("JvmField cannot be applied to delegated property") + DELEGATE("JvmField cannot be applied to delegated property"), + RETURN_TYPE_IS_INLINE_CLASS("JvmField cannot be applied to a property of an inline class type") } override fun check(declaration: KtDeclaration, descriptor: DeclarationDescriptor, context: DeclarationCheckerContext) { @@ -75,6 +78,7 @@ class JvmFieldApplicabilityChecker : DeclarationChecker { } DescriptorUtils.isTopLevelDeclaration(descriptor) && declaration.isInsideJvmMultifileClassFile() -> TOP_LEVEL_PROPERTY_OF_MULTIFILE_FACADE + descriptor.returnType?.isInlineClassThatRequiresMangling() == true -> RETURN_TYPE_IS_INLINE_CLASS else -> return } diff --git a/compiler/testData/diagnostics/testsWithStdLib/annotations/jvmField/jvmFieldApplicability.kt b/compiler/testData/diagnostics/testsWithStdLib/annotations/jvmField/jvmFieldApplicability.kt index e5b58ebd39d..c97c4a894e9 100644 --- a/compiler/testData/diagnostics/testsWithStdLib/annotations/jvmField/jvmFieldApplicability.kt +++ b/compiler/testData/diagnostics/testsWithStdLib/annotations/jvmField/jvmFieldApplicability.kt @@ -1,4 +1,4 @@ -// !LANGUAGE: +NestedClassesInAnnotations +// !LANGUAGE: +NestedClassesInAnnotations +InlineClasses // !DIAGNOSTICS: -UNUSED_PARAMETER -UNUSED_VARIABLE @kotlin.jvm.JvmField @@ -128,3 +128,16 @@ object O { @JvmField private val private = 3 + +inline class Foo(val x: Int) + +object IObject { + @JvmField + val c: Foo = Foo(42) + + @JvmField + val u = 42u + + @JvmField + internal val r: Result = TODO() +} diff --git a/compiler/testData/diagnostics/testsWithStdLib/annotations/jvmField/jvmFieldApplicability.txt b/compiler/testData/diagnostics/testsWithStdLib/annotations/jvmField/jvmFieldApplicability.txt index 0a93626031d..313a001f8b7 100644 --- a/compiler/testData/diagnostics/testsWithStdLib/annotations/jvmField/jvmFieldApplicability.txt +++ b/compiler/testData/diagnostics/testsWithStdLib/annotations/jvmField/jvmFieldApplicability.txt @@ -33,6 +33,14 @@ public final annotation class DemoAnnotation : kotlin.Annotation { public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String } +public final inline class Foo { + public constructor Foo(/*0*/ x: kotlin.Int) + public final val x: kotlin.Int + public open override /*1*/ /*synthesized*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + public open override /*1*/ /*synthesized*/ fun hashCode(): kotlin.Int + public open override /*1*/ /*synthesized*/ fun toString(): kotlin.String +} + public final class G { public constructor G() @field:kotlin.jvm.JvmField public final lateinit var lateInit: kotlin.String @@ -65,6 +73,16 @@ public interface I { public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String } +public object IObject { + private constructor IObject() + @field:kotlin.jvm.JvmField public final val c: Foo + @field:kotlin.jvm.JvmField internal final val r: kotlin.Result + @field:kotlin.jvm.JvmField public final val u: kotlin.UInt = 42.toUInt() + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String +} + public interface K { public abstract val i: kotlin.Int public abstract val j: kotlin.Int diff --git a/core/descriptors.jvm/src/org/jetbrains/kotlin/resolve/jvm/inlineClassManglingRules.kt b/core/descriptors.jvm/src/org/jetbrains/kotlin/resolve/jvm/inlineClassManglingRules.kt index b7143ec02a7..870a840c6b7 100644 --- a/core/descriptors.jvm/src/org/jetbrains/kotlin/resolve/jvm/inlineClassManglingRules.kt +++ b/core/descriptors.jvm/src/org/jetbrains/kotlin/resolve/jvm/inlineClassManglingRules.kt @@ -33,12 +33,12 @@ fun requiresFunctionNameMangling(valueParameterTypes: List): Boolean fun DeclarationDescriptor.isInlineClassThatRequiresMangling(): Boolean = isInlineClass() && !isDontMangleClass(this as ClassDescriptor) +fun KotlinType.isInlineClassThatRequiresMangling() = + constructor.declarationDescriptor?.isInlineClassThatRequiresMangling() == true + private fun KotlinType.requiresFunctionNameMangling() = isInlineClassThatRequiresMangling() || isTypeParameterWithUpperBoundThatRequiresMangling() -private fun KotlinType.isInlineClassThatRequiresMangling() = - constructor.declarationDescriptor?.isInlineClassThatRequiresMangling() == true - private fun isDontMangleClass(classDescriptor: ClassDescriptor) = classDescriptor.fqNameSafe == DescriptorUtils.RESULT_FQ_NAME