From a206eca164259930d8d1545b7eb9cfbfbb9f5fc3 Mon Sep 17 00:00:00 2001 From: Dmitry Petrov Date: Fri, 27 Nov 2020 12:31:47 +0300 Subject: [PATCH] JVM_IR KT-43611 report signature clash on private interface members --- .../jvm/codegen/JvmSignatureClashDetector.kt | 48 +++++++++++-------- .../traitImpl/kt43611.kt | 6 +++ .../traitImpl/kt43611.txt | 18 +++++++ ...gnosticsTestWithJvmIrBackendGenerated.java | 5 ++ ...nosticsTestWithOldJvmBackendGenerated.java | 5 ++ 5 files changed, 62 insertions(+), 20 deletions(-) create mode 100644 compiler/testData/diagnostics/testsWithJvmBackend/duplicateJvmSignature/traitImpl/kt43611.kt create mode 100644 compiler/testData/diagnostics/testsWithJvmBackend/duplicateJvmSignature/traitImpl/kt43611.txt diff --git a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/codegen/JvmSignatureClashDetector.kt b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/codegen/JvmSignatureClashDetector.kt index a4373fbed86..2369b94b941 100644 --- a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/codegen/JvmSignatureClashDetector.kt +++ b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/codegen/JvmSignatureClashDetector.kt @@ -8,6 +8,7 @@ package org.jetbrains.kotlin.backend.jvm.codegen import com.intellij.psi.PsiElement import org.jetbrains.kotlin.backend.jvm.JvmBackendContext import org.jetbrains.kotlin.backend.jvm.JvmLoweredDeclarationOrigin +import org.jetbrains.kotlin.descriptors.DescriptorVisibilities import org.jetbrains.kotlin.diagnostics.DiagnosticFactory1 import org.jetbrains.kotlin.ir.declarations.* import org.jetbrains.kotlin.ir.descriptors.toIrBasedDescriptor @@ -68,10 +69,6 @@ class JvmSignatureClashDetector( origin in SPECIAL_BRIDGES_AND_OVERRIDES fun reportErrors(classOrigin: JvmDeclarationOrigin) { - // Class IFoo$DefaultImpls has conflicting signatures if and only if corresponding interface IFoo has conflicting signatures. - // Do not report these diagnostics twice. - if (irClass.origin == JvmLoweredDeclarationOrigin.DEFAULT_IMPLS) return - reportMethodSignatureConflicts(classOrigin) reportPredefinedMethodSignatureConflicts(classOrigin) reportFieldSignatureConflicts(classOrigin) @@ -89,25 +86,36 @@ class JvmSignatureClashDetector( when { realMethodsCount == 0 && (fakeOverridesCount > 1 || specialOverridesCount > 1) -> - reportJvmSignatureClash( - ErrorsJvm.CONFLICTING_INHERITED_JVM_DECLARATIONS, - listOf(irClass), - conflictingJvmDeclarationsData - ) + if (irClass.origin != JvmLoweredDeclarationOrigin.DEFAULT_IMPLS) { + reportJvmSignatureClash( + ErrorsJvm.CONFLICTING_INHERITED_JVM_DECLARATIONS, + listOf(irClass), + conflictingJvmDeclarationsData + ) + } - fakeOverridesCount == 0 && specialOverridesCount == 0 -> - reportJvmSignatureClash( - ErrorsJvm.CONFLICTING_JVM_DECLARATIONS, - methods, - conflictingJvmDeclarationsData - ) + fakeOverridesCount == 0 && specialOverridesCount == 0 -> { + // In IFoo$DefaultImpls we should report errors only if there are private methods among conflicting ones + // (otherwise such errors would be reported twice: once for IFoo and once for IFoo$DefaultImpls). + if (irClass.origin != JvmLoweredDeclarationOrigin.DEFAULT_IMPLS || + methods.any { DescriptorVisibilities.isPrivate(it.visibility) } + ) { + reportJvmSignatureClash( + ErrorsJvm.CONFLICTING_JVM_DECLARATIONS, + methods, + conflictingJvmDeclarationsData + ) + } + } else -> - reportJvmSignatureClash( - ErrorsJvm.ACCIDENTAL_OVERRIDE, - methods.filter { !it.isFakeOverride && !it.isSpecialOverride() }, - conflictingJvmDeclarationsData - ) + if (irClass.origin != JvmLoweredDeclarationOrigin.DEFAULT_IMPLS) { + reportJvmSignatureClash( + ErrorsJvm.ACCIDENTAL_OVERRIDE, + methods.filter { !it.isFakeOverride && !it.isSpecialOverride() }, + conflictingJvmDeclarationsData + ) + } } } } diff --git a/compiler/testData/diagnostics/testsWithJvmBackend/duplicateJvmSignature/traitImpl/kt43611.kt b/compiler/testData/diagnostics/testsWithJvmBackend/duplicateJvmSignature/traitImpl/kt43611.kt new file mode 100644 index 00000000000..228ab02f029 --- /dev/null +++ b/compiler/testData/diagnostics/testsWithJvmBackend/duplicateJvmSignature/traitImpl/kt43611.kt @@ -0,0 +1,6 @@ +interface A { + fun f(a: List): String = TODO() + private fun f(a: List): String = TODO() +} + +class B : A \ No newline at end of file diff --git a/compiler/testData/diagnostics/testsWithJvmBackend/duplicateJvmSignature/traitImpl/kt43611.txt b/compiler/testData/diagnostics/testsWithJvmBackend/duplicateJvmSignature/traitImpl/kt43611.txt new file mode 100644 index 00000000000..e1d7e4b419e --- /dev/null +++ b/compiler/testData/diagnostics/testsWithJvmBackend/duplicateJvmSignature/traitImpl/kt43611.txt @@ -0,0 +1,18 @@ +package + +public interface A { + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + public open fun f(/*0*/ a: kotlin.collections.List): kotlin.String + private final fun f(/*0*/ a: kotlin.collections.List): kotlin.String + public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String +} + +public final class B : A { + public constructor B() + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + public open override /*1*/ /*fake_override*/ fun f(/*0*/ a: kotlin.collections.List): kotlin.String + invisible_fake final override /*1*/ /*fake_override*/ fun f(/*0*/ a: kotlin.collections.List): kotlin.String + public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String +} diff --git a/compiler/tests-gen/org/jetbrains/kotlin/checkers/DiagnosticsTestWithJvmIrBackendGenerated.java b/compiler/tests-gen/org/jetbrains/kotlin/checkers/DiagnosticsTestWithJvmIrBackendGenerated.java index 865e2a9417a..0e71ce26617 100644 --- a/compiler/tests-gen/org/jetbrains/kotlin/checkers/DiagnosticsTestWithJvmIrBackendGenerated.java +++ b/compiler/tests-gen/org/jetbrains/kotlin/checkers/DiagnosticsTestWithJvmIrBackendGenerated.java @@ -552,6 +552,11 @@ public class DiagnosticsTestWithJvmIrBackendGenerated extends AbstractDiagnostic runTest("compiler/testData/diagnostics/testsWithJvmBackend/duplicateJvmSignature/traitImpl/defaultVsNonDefault_ir.kt"); } + @TestMetadata("kt43611.kt") + public void testKt43611() throws Exception { + runTest("compiler/testData/diagnostics/testsWithJvmBackend/duplicateJvmSignature/traitImpl/kt43611.kt"); + } + @TestMetadata("oneTrait_ir.kt") public void testOneTrait_ir() throws Exception { runTest("compiler/testData/diagnostics/testsWithJvmBackend/duplicateJvmSignature/traitImpl/oneTrait_ir.kt"); diff --git a/compiler/tests-gen/org/jetbrains/kotlin/checkers/DiagnosticsTestWithOldJvmBackendGenerated.java b/compiler/tests-gen/org/jetbrains/kotlin/checkers/DiagnosticsTestWithOldJvmBackendGenerated.java index 7caddc4167e..66044c1c3b7 100644 --- a/compiler/tests-gen/org/jetbrains/kotlin/checkers/DiagnosticsTestWithOldJvmBackendGenerated.java +++ b/compiler/tests-gen/org/jetbrains/kotlin/checkers/DiagnosticsTestWithOldJvmBackendGenerated.java @@ -542,6 +542,11 @@ public class DiagnosticsTestWithOldJvmBackendGenerated extends AbstractDiagnosti runTest("compiler/testData/diagnostics/testsWithJvmBackend/duplicateJvmSignature/traitImpl/defaultVsNonDefault_old.kt"); } + @TestMetadata("kt43611.kt") + public void testKt43611() throws Exception { + runTest("compiler/testData/diagnostics/testsWithJvmBackend/duplicateJvmSignature/traitImpl/kt43611.kt"); + } + @TestMetadata("oneTrait_old.kt") public void testOneTrait_old() throws Exception { runTest("compiler/testData/diagnostics/testsWithJvmBackend/duplicateJvmSignature/traitImpl/oneTrait_old.kt");