diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/InterfaceImplBodyCodegen.kt b/compiler/backend/src/org/jetbrains/kotlin/codegen/InterfaceImplBodyCodegen.kt index d9624ffd991..bf76be8dc9a 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/InterfaceImplBodyCodegen.kt +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/InterfaceImplBodyCodegen.kt @@ -72,17 +72,23 @@ class InterfaceImplBodyCodegen( // If implementation is a default interface method (JVM 8 only) if (implementation.isDefinitelyNotDefaultImplsMethod()) continue + // TODO: we need to copy descriptor otherwise declaration clash diagnostic is missed, see testTraitFunctionOverriddenByPropertyInTrait + val copy = memberDescriptor.copy( + memberDescriptor.containingDeclaration, Modality.OPEN, memberDescriptor.visibility, + CallableMemberDescriptor.Kind.DECLARATION, true + ) + if (memberDescriptor is FunctionDescriptor) { - generateDelegationToSuperDefaultImpls(memberDescriptor, implementation as FunctionDescriptor) + generateDelegationToSuperDefaultImpls(copy as FunctionDescriptor, implementation as FunctionDescriptor) } else if (memberDescriptor is PropertyDescriptor) { implementation as PropertyDescriptor - val getter = memberDescriptor.getter + val getter = (copy as PropertyDescriptor).getter val implGetter = implementation.getter if (getter != null && implGetter != null) { generateDelegationToSuperDefaultImpls(getter, implGetter) } - val setter = memberDescriptor.setter + val setter = copy.setter val implSetter = implementation.setter if (setter != null && implSetter != null) { generateDelegationToSuperDefaultImpls(setter, implSetter) diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/MemberCodegen.java b/compiler/backend/src/org/jetbrains/kotlin/codegen/MemberCodegen.java index 29d46f9e3df..e3107eab594 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/MemberCodegen.java +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/MemberCodegen.java @@ -9,6 +9,7 @@ import com.intellij.openapi.progress.ProcessCanceledException; import com.intellij.psi.PsiElement; import kotlin.Unit; import kotlin.jvm.functions.Function0; +import kotlin.jvm.functions.Function1; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.jetbrains.kotlin.backend.common.CodegenUtil; @@ -44,6 +45,7 @@ import org.jetbrains.kotlin.resolve.descriptorUtil.DescriptorUtilsKt; import org.jetbrains.kotlin.resolve.jvm.AsmTypes; import org.jetbrains.kotlin.resolve.jvm.diagnostics.JvmDeclarationOriginKt; import org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodSignature; +import org.jetbrains.kotlin.resolve.scopes.DescriptorKindFilter; import org.jetbrains.kotlin.resolve.source.KotlinSourceElementKt; import org.jetbrains.kotlin.serialization.DescriptorSerializer; import org.jetbrains.kotlin.storage.LockBasedStorageManager; @@ -726,12 +728,23 @@ public abstract class MemberCodegen existingDescriptors = + ((ClassDescriptor) directMember.getContainingDeclaration()).getUnsubstitutedMemberScope() + .getContributedDescriptors( + DescriptorKindFilter.CALLABLES, name -> name.equals(directMember.getName())); + if (!existingDescriptors.contains(original)) { + //TODO: don't try to copy descriptros in InterfaceImplBodyCodegen.generateSyntheticPartsAfterBody, + // investigate problem with diagnostic and remove this HACK code + descriptor = unwrapFakeOverrideSkipFirst(original).getOriginal(); descriptor = descriptor .copy(original.getContainingDeclaration(), descriptor.getModality(), descriptor.getVisibility(), descriptor.getKind(), false); } + else { + descriptor = original; + } generateMethodCallTo(descriptor, accessor, codegen.v).coerceTo(signature.getReturnType(), null, codegen.v); } else { @@ -892,4 +905,13 @@ public abstract class MemberCodegen D unwrapFakeOverrideSkipFirst(@NotNull D descriptor) { + Collection overridden = descriptor.getOverriddenDescriptors(); + if (overridden.isEmpty()) { + throw new IllegalStateException("Fake override should have at least one overridden descriptor: " + descriptor); + } + descriptor = (D) overridden.iterator().next(); + return unwrapFakeOverride(descriptor); + } }