From c4a48927d2fe5ce63cb3997810b017a0bf26d0b8 Mon Sep 17 00:00:00 2001 From: Mikhail Glukhikh Date: Thu, 15 Sep 2022 09:42:22 +0200 Subject: [PATCH] K1: report ABSTRACT_SUPER_CALL(_WARNING) also for 2+ steps to intersection #KT-53953 Fixed --- .../calls/components/ResolutionParts.kt | 32 +++++++++++++------ ...ctFakeOverrideSuperCallOneMoreLevel.fir.kt | 16 ---------- ...stractFakeOverrideSuperCallOneMoreLevel.kt | 11 ++++++- ...tractFakeOverrideSuperCallOneMoreLevel.txt | 17 ++++++++++ 4 files changed, 50 insertions(+), 26 deletions(-) delete mode 100644 compiler/testData/diagnostics/tests/java8Overrides/abstractFakeOverrideSuperCallOneMoreLevel.fir.kt diff --git a/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/components/ResolutionParts.kt b/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/components/ResolutionParts.kt index 37cb4f2f75f..7d6c0c57679 100644 --- a/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/components/ResolutionParts.kt +++ b/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/components/ResolutionParts.kt @@ -804,15 +804,7 @@ internal object CheckSuperExpressionCallPart : ResolutionPart() { if (callComponents.statelessCallbacks.isSuperExpression(resolvedCall.dispatchReceiverArgument)) { if (candidateDescriptor is CallableMemberDescriptor) { - if (candidateDescriptor.modality == Modality.ABSTRACT) { - addDiagnostic(AbstractSuperCall(resolvedCall.dispatchReceiverArgument!!)) - } else if (candidateDescriptor.kind == CallableMemberDescriptor.Kind.FAKE_OVERRIDE && - candidateDescriptor.overriddenDescriptors.size > 1 - ) { - if (candidateDescriptor.overriddenDescriptors.firstOrNull { !it.isInsideInterface }?.modality == Modality.ABSTRACT) { - addDiagnostic(AbstractFakeOverrideSuperCall) - } - } + checkSuperCandidateDescriptor(candidateDescriptor) } } @@ -821,6 +813,28 @@ internal object CheckSuperExpressionCallPart : ResolutionPart() { addDiagnostic(SuperAsExtensionReceiver(extensionReceiver)) } } + + private fun ResolutionCandidate.checkSuperCandidateDescriptor(candidateDescriptor: CallableMemberDescriptor) { + if (candidateDescriptor.modality == Modality.ABSTRACT) { + addDiagnostic(AbstractSuperCall(resolvedCall.dispatchReceiverArgument!!)) + } else if (candidateDescriptor.kind == CallableMemberDescriptor.Kind.FAKE_OVERRIDE) { + var intersectionFakeOverrideDescriptor = candidateDescriptor + while (intersectionFakeOverrideDescriptor.overriddenDescriptors.size == 1) { + intersectionFakeOverrideDescriptor = intersectionFakeOverrideDescriptor.overriddenDescriptors.first() + if (intersectionFakeOverrideDescriptor.kind != CallableMemberDescriptor.Kind.FAKE_OVERRIDE) { + return + } + } + if (intersectionFakeOverrideDescriptor.overriddenDescriptors.size > 1) { + if (intersectionFakeOverrideDescriptor.overriddenDescriptors.firstOrNull { + !it.isInsideInterface + }?.modality == Modality.ABSTRACT + ) { + addDiagnostic(AbstractFakeOverrideSuperCall) + } + } + } + } } internal object ErrorDescriptorResolutionPart : ResolutionPart() { diff --git a/compiler/testData/diagnostics/tests/java8Overrides/abstractFakeOverrideSuperCallOneMoreLevel.fir.kt b/compiler/testData/diagnostics/tests/java8Overrides/abstractFakeOverrideSuperCallOneMoreLevel.fir.kt deleted file mode 100644 index 265cf2636e3..00000000000 --- a/compiler/testData/diagnostics/tests/java8Overrides/abstractFakeOverrideSuperCallOneMoreLevel.fir.kt +++ /dev/null @@ -1,16 +0,0 @@ -// !LANGUAGE: -ForbidSuperDelegationToAbstractFakeOverride -interface Foo { - fun check(): String = "OK" -} -abstract class Base { - abstract fun check(): String -} - -abstract class Derived : Base(), Foo -abstract class Derived2 : Derived() // ONE MORE LEVEL - -class Problem : Derived2() { - override fun check(): String { - return super.check() // NO COMPILER ERROR, BUT FAILURE IN RUNTIME - } -} diff --git a/compiler/testData/diagnostics/tests/java8Overrides/abstractFakeOverrideSuperCallOneMoreLevel.kt b/compiler/testData/diagnostics/tests/java8Overrides/abstractFakeOverrideSuperCallOneMoreLevel.kt index 9e14c3a0e35..0b40f79dc57 100644 --- a/compiler/testData/diagnostics/tests/java8Overrides/abstractFakeOverrideSuperCallOneMoreLevel.kt +++ b/compiler/testData/diagnostics/tests/java8Overrides/abstractFakeOverrideSuperCallOneMoreLevel.kt @@ -1,3 +1,4 @@ +// FIR_IDENTICAL // !LANGUAGE: -ForbidSuperDelegationToAbstractFakeOverride interface Foo { fun check(): String = "OK" @@ -9,8 +10,16 @@ abstract class Base { abstract class Derived : Base(), Foo abstract class Derived2 : Derived() // ONE MORE LEVEL +abstract class Derived3 : Derived2() + class Problem : Derived2() { override fun check(): String { - return super.check() // NO COMPILER ERROR, BUT FAILURE IN RUNTIME + return super.check() + } +} + +class Problem2 : Derived3() { + override fun check(): String { + return super.check() } } diff --git a/compiler/testData/diagnostics/tests/java8Overrides/abstractFakeOverrideSuperCallOneMoreLevel.txt b/compiler/testData/diagnostics/tests/java8Overrides/abstractFakeOverrideSuperCallOneMoreLevel.txt index 6faa4698d7c..0c5c30c6585 100644 --- a/compiler/testData/diagnostics/tests/java8Overrides/abstractFakeOverrideSuperCallOneMoreLevel.txt +++ b/compiler/testData/diagnostics/tests/java8Overrides/abstractFakeOverrideSuperCallOneMoreLevel.txt @@ -24,6 +24,14 @@ public abstract class Derived2 : Derived { public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String } +public abstract class Derived3 : Derived2 { + public constructor Derived3() + public open override /*1*/ /*fake_override*/ fun check(): kotlin.String + 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 Foo { public open fun check(): kotlin.String public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean @@ -38,3 +46,12 @@ public final class Problem : Derived2 { public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String } + +public final class Problem2 : Derived3 { + public constructor Problem2() + public open override /*1*/ fun check(): kotlin.String + 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 +} +