diff --git a/compiler/frontend.java/src/org/jetbrains/kotlin/resolve/jvm/checkers/declarationCheckers.kt b/compiler/frontend.java/src/org/jetbrains/kotlin/resolve/jvm/checkers/declarationCheckers.kt index 736b8c8dfa4..30ec93e8a98 100644 --- a/compiler/frontend.java/src/org/jetbrains/kotlin/resolve/jvm/checkers/declarationCheckers.kt +++ b/compiler/frontend.java/src/org/jetbrains/kotlin/resolve/jvm/checkers/declarationCheckers.kt @@ -34,11 +34,14 @@ import org.jetbrains.kotlin.resolve.calls.components.isActualParameterWithCorres import org.jetbrains.kotlin.resolve.checkers.DeclarationChecker import org.jetbrains.kotlin.resolve.checkers.DeclarationCheckerContext import org.jetbrains.kotlin.resolve.inline.InlineUtil +import org.jetbrains.kotlin.resolve.isInlineClass import org.jetbrains.kotlin.resolve.jvm.annotations.VOLATILE_ANNOTATION_FQ_NAME import org.jetbrains.kotlin.resolve.jvm.annotations.findJvmOverloadsAnnotation import org.jetbrains.kotlin.resolve.jvm.annotations.findSynchronizedAnnotation import org.jetbrains.kotlin.resolve.jvm.annotations.hasJvmFieldAnnotation import org.jetbrains.kotlin.resolve.jvm.diagnostics.ErrorsJvm +import org.jetbrains.kotlin.resolve.jvm.isInlineClassThatRequiresMangling +import org.jetbrains.kotlin.resolve.jvm.requiresFunctionNameMangling class LocalFunInlineChecker : DeclarationChecker { override fun check(declaration: KtDeclaration, descriptor: DeclarationDescriptor, context: DeclarationCheckerContext) { @@ -143,6 +146,10 @@ class JvmNameAnnotationChecker : DeclarationChecker { if (descriptor is CallableMemberDescriptor) { if (DescriptorUtils.isOverride(descriptor) || descriptor.isOverridable) { diagnosticHolder.report(ErrorsJvm.INAPPLICABLE_JVM_NAME.on(annotationEntry)) + } else if (descriptor.containingDeclaration.isInlineClassThatRequiresMangling() || + requiresFunctionNameMangling(descriptor.valueParameters.map { it.type }) + ) { + diagnosticHolder.report(ErrorsJvm.INAPPLICABLE_JVM_NAME.on(annotationEntry)) } } } diff --git a/compiler/testData/diagnostics/testsWithStdLib/annotations/annotationApplicability/jvmNameOnMangledNames.kt b/compiler/testData/diagnostics/testsWithStdLib/annotations/annotationApplicability/jvmNameOnMangledNames.kt new file mode 100644 index 00000000000..07807c3e31a --- /dev/null +++ b/compiler/testData/diagnostics/testsWithStdLib/annotations/annotationApplicability/jvmNameOnMangledNames.kt @@ -0,0 +1,13 @@ +// !LANGUAGE: +InlineClasses +// !DIAGNOSTICS: -UNUSED_PARAMETER + +inline class Foo(val x: Int) { + @JvmName("other") + fun simple() {} +} + +@JvmName("bad") +fun bar(f: Foo) {} + +@JvmName("good") +fun baz(r: Result) {} \ No newline at end of file diff --git a/compiler/testData/diagnostics/testsWithStdLib/annotations/annotationApplicability/jvmNameOnMangledNames.txt b/compiler/testData/diagnostics/testsWithStdLib/annotations/annotationApplicability/jvmNameOnMangledNames.txt new file mode 100644 index 00000000000..c3e73ad3abe --- /dev/null +++ b/compiler/testData/diagnostics/testsWithStdLib/annotations/annotationApplicability/jvmNameOnMangledNames.txt @@ -0,0 +1,13 @@ +package + +@kotlin.jvm.JvmName(name = "bad") public fun bar(/*0*/ f: Foo): kotlin.Unit +@kotlin.jvm.JvmName(name = "good") public fun baz(/*0*/ r: kotlin.Result): kotlin.Unit + +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 + @kotlin.jvm.JvmName(name = "other") public final fun simple(): kotlin.Unit + public open override /*1*/ /*synthesized*/ fun toString(): kotlin.String +} diff --git a/compiler/testData/diagnostics/testsWithUnsignedTypes/conversions/overloadResolutionForSignedAndUnsignedTypes.kt b/compiler/testData/diagnostics/testsWithUnsignedTypes/conversions/overloadResolutionForSignedAndUnsignedTypes.kt index 72c3331e2a4..7b625e5b14d 100644 --- a/compiler/testData/diagnostics/testsWithUnsignedTypes/conversions/overloadResolutionForSignedAndUnsignedTypes.kt +++ b/compiler/testData/diagnostics/testsWithUnsignedTypes/conversions/overloadResolutionForSignedAndUnsignedTypes.kt @@ -3,22 +3,18 @@ fun foo(x: Int): Int = 0 -@JvmName("fooUInt") fun foo(x: UInt): String = "" fun foo(x: UByte): String = "" fun foo(x: UShort): String = "" fun foo(x: ULong): String = "" fun fooByte(x: Byte): Int = 0 -@JvmName("fooUByte") fun fooByte(x: UByte): String = "" fun fooShort(x: Short): Int = 0 -@JvmName("fooUByte") fun fooShort(x: UShort): String = "" fun fooLong(x: Long): Int = 0 -@JvmName("fooULong") fun fooLong(x: ULong): String = "" fun test() { diff --git a/compiler/testData/diagnostics/testsWithUnsignedTypes/conversions/overloadResolutionForSignedAndUnsignedTypes.txt b/compiler/testData/diagnostics/testsWithUnsignedTypes/conversions/overloadResolutionForSignedAndUnsignedTypes.txt index bafe60f62f3..820c3ea6052 100644 --- a/compiler/testData/diagnostics/testsWithUnsignedTypes/conversions/overloadResolutionForSignedAndUnsignedTypes.txt +++ b/compiler/testData/diagnostics/testsWithUnsignedTypes/conversions/overloadResolutionForSignedAndUnsignedTypes.txt @@ -2,13 +2,13 @@ package public fun foo(/*0*/ x: kotlin.Int): kotlin.Int public fun foo(/*0*/ x: kotlin.UByte): kotlin.String -@kotlin.jvm.JvmName(name = "fooUInt") public fun foo(/*0*/ x: kotlin.UInt): kotlin.String +public fun foo(/*0*/ x: kotlin.UInt): kotlin.String public fun foo(/*0*/ x: kotlin.ULong): kotlin.String public fun foo(/*0*/ x: kotlin.UShort): kotlin.String public fun fooByte(/*0*/ x: kotlin.Byte): kotlin.Int -@kotlin.jvm.JvmName(name = "fooUByte") public fun fooByte(/*0*/ x: kotlin.UByte): kotlin.String +public fun fooByte(/*0*/ x: kotlin.UByte): kotlin.String public fun fooLong(/*0*/ x: kotlin.Long): kotlin.Int -@kotlin.jvm.JvmName(name = "fooULong") public fun fooLong(/*0*/ x: kotlin.ULong): kotlin.String +public fun fooLong(/*0*/ x: kotlin.ULong): kotlin.String public fun fooShort(/*0*/ x: kotlin.Short): kotlin.Int -@kotlin.jvm.JvmName(name = "fooUByte") public fun fooShort(/*0*/ x: kotlin.UShort): kotlin.String +public fun fooShort(/*0*/ x: kotlin.UShort): kotlin.String public fun test(): kotlin.Unit diff --git a/compiler/tests/org/jetbrains/kotlin/checkers/DiagnosticsTestWithStdLibGenerated.java b/compiler/tests/org/jetbrains/kotlin/checkers/DiagnosticsTestWithStdLibGenerated.java index 5d0f338a62d..9529ddb3eff 100644 --- a/compiler/tests/org/jetbrains/kotlin/checkers/DiagnosticsTestWithStdLibGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/checkers/DiagnosticsTestWithStdLibGenerated.java @@ -243,6 +243,11 @@ public class DiagnosticsTestWithStdLibGenerated extends AbstractDiagnosticsTestW runTest("compiler/testData/diagnostics/testsWithStdLib/annotations/annotationApplicability/jvmName.kt"); } + @TestMetadata("jvmNameOnMangledNames.kt") + public void testJvmNameOnMangledNames() throws Exception { + runTest("compiler/testData/diagnostics/testsWithStdLib/annotations/annotationApplicability/jvmNameOnMangledNames.kt"); + } + @TestMetadata("multifileClassPart.kt") public void testMultifileClassPart() throws Exception { runTest("compiler/testData/diagnostics/testsWithStdLib/annotations/annotationApplicability/multifileClassPart.kt"); diff --git a/compiler/tests/org/jetbrains/kotlin/checkers/javac/DiagnosticsTestWithStdLibUsingJavacGenerated.java b/compiler/tests/org/jetbrains/kotlin/checkers/javac/DiagnosticsTestWithStdLibUsingJavacGenerated.java index 4795eec998f..f4b6675d11e 100644 --- a/compiler/tests/org/jetbrains/kotlin/checkers/javac/DiagnosticsTestWithStdLibUsingJavacGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/checkers/javac/DiagnosticsTestWithStdLibUsingJavacGenerated.java @@ -243,6 +243,11 @@ public class DiagnosticsTestWithStdLibUsingJavacGenerated extends AbstractDiagno runTest("compiler/testData/diagnostics/testsWithStdLib/annotations/annotationApplicability/jvmName.kt"); } + @TestMetadata("jvmNameOnMangledNames.kt") + public void testJvmNameOnMangledNames() throws Exception { + runTest("compiler/testData/diagnostics/testsWithStdLib/annotations/annotationApplicability/jvmNameOnMangledNames.kt"); + } + @TestMetadata("multifileClassPart.kt") public void testMultifileClassPart() throws Exception { runTest("compiler/testData/diagnostics/testsWithStdLib/annotations/annotationApplicability/multifileClassPart.kt"); 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 314588eb439..b7143ec02a7 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 @@ -10,6 +10,7 @@ import org.jetbrains.kotlin.load.kotlin.getRepresentativeUpperBound import org.jetbrains.kotlin.resolve.DescriptorUtils import org.jetbrains.kotlin.resolve.descriptorUtil.fqNameSafe import org.jetbrains.kotlin.resolve.descriptorUtil.fqNameUnsafe +import org.jetbrains.kotlin.resolve.isInlineClass import org.jetbrains.kotlin.resolve.isInlineClassType import org.jetbrains.kotlin.types.KotlinType import java.security.MessageDigest @@ -29,11 +30,14 @@ fun requiresFunctionNameMangling(valueParameterTypes: List): Boolean return valueParameterTypes.any { it.requiresFunctionNameMangling() } } +fun DeclarationDescriptor.isInlineClassThatRequiresMangling(): Boolean = + isInlineClass() && !isDontMangleClass(this as ClassDescriptor) + private fun KotlinType.requiresFunctionNameMangling() = isInlineClassThatRequiresMangling() || isTypeParameterWithUpperBoundThatRequiresMangling() private fun KotlinType.isInlineClassThatRequiresMangling() = - isInlineClassType() && !isDontMangleClass(this.constructor.declarationDescriptor as ClassDescriptor) + constructor.declarationDescriptor?.isInlineClassThatRequiresMangling() == true private fun isDontMangleClass(classDescriptor: ClassDescriptor) = classDescriptor.fqNameSafe == DescriptorUtils.RESULT_FQ_NAME