diff --git a/compiler/backend-common/src/org/jetbrains/kotlin/backend/common/CodegenUtil.kt b/compiler/backend-common/src/org/jetbrains/kotlin/backend/common/CodegenUtil.kt index 40a25ecbc79..80d27fac127 100644 --- a/compiler/backend-common/src/org/jetbrains/kotlin/backend/common/CodegenUtil.kt +++ b/compiler/backend-common/src/org/jetbrains/kotlin/backend/common/CodegenUtil.kt @@ -71,8 +71,7 @@ object CodegenUtil { } private fun doesOverride(overrideCandidate: CallableMemberDescriptor, overriddenDescriptor: CallableMemberDescriptor) = - (listOf(overrideCandidate) + DescriptorUtils.getAllOverriddenDescriptors(overrideCandidate)) - .map(CallableMemberDescriptor::getOriginal) + (listOf(overrideCandidate.original) + DescriptorUtils.getAllOverriddenDescriptors(overrideCandidate)) .contains(overriddenDescriptor.original) @JvmStatic diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/state/KotlinTypeMapper.java b/compiler/backend/src/org/jetbrains/kotlin/codegen/state/KotlinTypeMapper.java index 2b37ac8549c..97fad151398 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/state/KotlinTypeMapper.java +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/state/KotlinTypeMapper.java @@ -1075,7 +1075,7 @@ public class KotlinTypeMapper { for (FunctionDescriptor overridden : getAllOverriddenDescriptors(descriptor)) { //noinspection ConstantConditions - if (!KotlinBuiltIns.isPrimitiveType(overridden.getOriginal().getReturnType())) return true; + if (!KotlinBuiltIns.isPrimitiveType(overridden.getReturnType())) return true; } return false; diff --git a/compiler/testData/codegen/box/delegation/kt8154.kt b/compiler/testData/codegen/box/delegation/kt8154.kt new file mode 100644 index 00000000000..86550e49f60 --- /dev/null +++ b/compiler/testData/codegen/box/delegation/kt8154.kt @@ -0,0 +1,19 @@ +interface A { + fun foo(): T +} + +interface B : A + +class BImpl(a: A) : B, A by a + +fun box(): String { + val b: B = BImpl(object : A { + override fun foo() = "OK" + }) + + if (b.foo() != "OK") return "fail 1" + + val a: A = b + + return a.foo() +} diff --git a/compiler/testData/diagnostics/tests/delegation/kt8154.kt b/compiler/testData/diagnostics/tests/delegation/kt8154.kt new file mode 100644 index 00000000000..066fef5fa23 --- /dev/null +++ b/compiler/testData/diagnostics/tests/delegation/kt8154.kt @@ -0,0 +1,11 @@ +interface A { + fun foo() +} + +interface B : A { + fun bar() +} + +class BImpl(a: A) : B, A by a { + override fun bar() { throw UnsupportedOperationException() } +} diff --git a/compiler/testData/diagnostics/tests/delegation/kt8154.txt b/compiler/testData/diagnostics/tests/delegation/kt8154.txt new file mode 100644 index 00000000000..2d0a3a8e1c5 --- /dev/null +++ b/compiler/testData/diagnostics/tests/delegation/kt8154.txt @@ -0,0 +1,25 @@ +package + +public interface A { + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + public abstract fun foo(): kotlin.Unit + public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String +} + +public interface B : A { + public abstract fun bar(): kotlin.Unit + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + public abstract override /*1*/ /*fake_override*/ fun foo(): kotlin.Unit + public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String +} + +public final class BImpl : B, A { + public constructor BImpl(/*0*/ a: A) + public open override /*1*/ fun bar(): kotlin.Unit + public open override /*2*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + public open override /*2*/ /*delegation*/ fun foo(): kotlin.Unit + public open override /*2*/ /*fake_override*/ fun hashCode(): kotlin.Int + public open override /*2*/ /*fake_override*/ fun toString(): kotlin.String +} diff --git a/compiler/tests/org/jetbrains/kotlin/checkers/DiagnosticsTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/checkers/DiagnosticsTestGenerated.java index eb75bfda199..85ca6ae751a 100644 --- a/compiler/tests/org/jetbrains/kotlin/checkers/DiagnosticsTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/checkers/DiagnosticsTestGenerated.java @@ -5748,6 +5748,12 @@ public class DiagnosticsTestGenerated extends AbstractDiagnosticsTest { doTest(fileName); } + @TestMetadata("kt8154.kt") + public void testKt8154() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/delegation/kt8154.kt"); + doTest(fileName); + } + @TestMetadata("compiler/testData/diagnostics/tests/delegation/clashes") @TestDataPath("$PROJECT_ROOT") @RunWith(JUnit3RunnerWithInners.class) diff --git a/compiler/tests/org/jetbrains/kotlin/codegen/BlackBoxCodegenTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/codegen/BlackBoxCodegenTestGenerated.java index da489e48b10..b974114a9c4 100644 --- a/compiler/tests/org/jetbrains/kotlin/codegen/BlackBoxCodegenTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/codegen/BlackBoxCodegenTestGenerated.java @@ -5655,6 +5655,12 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest { String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/delegation/delegationToVal.kt"); doTest(fileName); } + + @TestMetadata("kt8154.kt") + public void testKt8154() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/delegation/kt8154.kt"); + doTest(fileName); + } } @TestMetadata("compiler/testData/codegen/box/destructuringDeclInLambdaParam") diff --git a/core/descriptors/src/org/jetbrains/kotlin/resolve/DescriptorUtils.java b/core/descriptors/src/org/jetbrains/kotlin/resolve/DescriptorUtils.java index 8d771b2e39f..6f05d33b5e5 100644 --- a/core/descriptors/src/org/jetbrains/kotlin/resolve/DescriptorUtils.java +++ b/core/descriptors/src/org/jetbrains/kotlin/resolve/DescriptorUtils.java @@ -469,6 +469,9 @@ public class DescriptorUtils { return classDescriptor.getModality() != Modality.FINAL || classDescriptor.getKind() == ClassKind.ENUM_CLASS; } + /** + * @return original (not substituted) descriptors without any duplicates + */ @NotNull @SuppressWarnings("unchecked") public static Set getAllOverriddenDescriptors(@NotNull D f) { @@ -481,7 +484,7 @@ public class DescriptorUtils { if (result.contains(current)) return; for (CallableDescriptor callableDescriptor : current.getOriginal().getOverriddenDescriptors()) { @SuppressWarnings("unchecked") - D descriptor = (D) callableDescriptor; + D descriptor = (D) callableDescriptor.getOriginal(); collectAllOverriddenDescriptors(descriptor, result); result.add(descriptor); } diff --git a/core/descriptors/src/org/jetbrains/kotlin/resolve/OverridingUtil.java b/core/descriptors/src/org/jetbrains/kotlin/resolve/OverridingUtil.java index c96d2e20cbc..80a9bf027f1 100644 --- a/core/descriptors/src/org/jetbrains/kotlin/resolve/OverridingUtil.java +++ b/core/descriptors/src/org/jetbrains/kotlin/resolve/OverridingUtil.java @@ -119,7 +119,7 @@ public class OverridingUtil { CallableDescriptor originalG = g.getOriginal(); for (D overriddenFunction : DescriptorUtils.getAllOverriddenDescriptors(f)) { - if (DescriptorEquivalenceForOverrides.INSTANCE.areEquivalent(originalG, overriddenFunction.getOriginal())) return true; + if (DescriptorEquivalenceForOverrides.INSTANCE.areEquivalent(originalG, overriddenFunction)) return true; } return false; }