diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/CollectionStubMethodGenerator.kt b/compiler/backend/src/org/jetbrains/kotlin/codegen/CollectionStubMethodGenerator.kt index 243eb1f5989..64b7d7f9f63 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/CollectionStubMethodGenerator.kt +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/CollectionStubMethodGenerator.kt @@ -23,6 +23,7 @@ import org.jetbrains.kotlin.descriptors.annotations.Annotations import org.jetbrains.kotlin.load.java.BuiltinMethodsWithSpecialGenericSignature.getSpecialSignatureInfo import org.jetbrains.kotlin.load.java.BuiltinMethodsWithSpecialGenericSignature.isBuiltinWithSpecialDescriptorInJvm import org.jetbrains.kotlin.name.Name +import org.jetbrains.kotlin.resolve.NonReportingOverrideStrategy import org.jetbrains.kotlin.resolve.OverrideResolver import org.jetbrains.kotlin.resolve.OverridingStrategy import org.jetbrains.kotlin.resolve.descriptorUtil.builtIns @@ -191,7 +192,7 @@ class CollectionStubMethodGenerator( ): List { val result = ArrayList() - OverrideResolver.generateOverridesInAClass(klass, listOf(), object : OverridingStrategy() { + OverrideResolver.generateOverridesInAClass(klass, listOf(), object : NonReportingOverrideStrategy() { override fun addFakeOverride(fakeOverride: CallableMemberDescriptor) { if (fakeOverride !is FunctionDescriptor) return if (fakeOverride.findOverriddenFromDirectSuperClass(mutableCollectionClass)?.kind == DECLARATION) { diff --git a/compiler/frontend/src/org/jetbrains/kotlin/diagnostics/Errors.java b/compiler/frontend/src/org/jetbrains/kotlin/diagnostics/Errors.java index 4fbf4e210d4..2aafc9a6577 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/diagnostics/Errors.java +++ b/compiler/frontend/src/org/jetbrains/kotlin/diagnostics/Errors.java @@ -345,6 +345,8 @@ public interface Errors { DiagnosticFactory2 VAR_OVERRIDDEN_BY_VAL_BY_DELEGATION = DiagnosticFactory2.create(ERROR, DECLARATION_NAME); + DiagnosticFactory2> CONFLICTING_INHERITED_MEMBERS = + DiagnosticFactory2.create(ERROR, DECLARATION_NAME); DiagnosticFactory2 ABSTRACT_MEMBER_NOT_IMPLEMENTED = DiagnosticFactory2.create(ERROR, DECLARATION_NAME); DiagnosticFactory2 ABSTRACT_CLASS_MEMBER_NOT_IMPLEMENTED = diff --git a/compiler/frontend/src/org/jetbrains/kotlin/diagnostics/rendering/DefaultErrorMessages.java b/compiler/frontend/src/org/jetbrains/kotlin/diagnostics/rendering/DefaultErrorMessages.java index a5cb609370d..0b701eb90c1 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/diagnostics/rendering/DefaultErrorMessages.java +++ b/compiler/frontend/src/org/jetbrains/kotlin/diagnostics/rendering/DefaultErrorMessages.java @@ -601,6 +601,7 @@ public class DefaultErrorMessages { MAP.put(VAR_OVERRIDDEN_BY_VAL, "Var-property {0} cannot be overridden by val-property {1}", FQ_NAMES_IN_TYPES, FQ_NAMES_IN_TYPES); + MAP.put(CONFLICTING_INHERITED_MEMBERS, "{0} inherits conflicting members: {1}", NAME, commaSeparated(FQ_NAMES_IN_TYPES)); MAP.put(ABSTRACT_MEMBER_NOT_IMPLEMENTED, "{0} must be declared abstract or implement abstract member {1}", RENDER_CLASS_OR_OBJECT, FQ_NAMES_IN_TYPES); MAP.put(ABSTRACT_CLASS_MEMBER_NOT_IMPLEMENTED, "{0} must be declared abstract or implement abstract base class member {1}", diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/lazy/descriptors/LazyClassMemberScope.kt b/compiler/frontend/src/org/jetbrains/kotlin/resolve/lazy/descriptors/LazyClassMemberScope.kt index 26e2739369b..d9beb6de3ce 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/lazy/descriptors/LazyClassMemberScope.kt +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/lazy/descriptors/LazyClassMemberScope.kt @@ -25,6 +25,7 @@ import org.jetbrains.kotlin.diagnostics.Errors import org.jetbrains.kotlin.incremental.components.LookupLocation import org.jetbrains.kotlin.incremental.components.NoLookupLocation import org.jetbrains.kotlin.name.Name +import org.jetbrains.kotlin.psi.KtClassOrObject import org.jetbrains.kotlin.psi.KtDeclaration import org.jetbrains.kotlin.psi.KtProperty import org.jetbrains.kotlin.psi.KtTypeReference @@ -106,10 +107,15 @@ open class LazyClassMemberScope( result.add(fakeOverride as D) } - override fun conflict(fromSuper: CallableMemberDescriptor, fromCurrent: CallableMemberDescriptor) { + override fun overrideConflict(fromSuper: CallableMemberDescriptor, fromCurrent: CallableMemberDescriptor) { val declaration = DescriptorToSourceUtils.descriptorToDeclaration(fromCurrent) as? KtDeclaration ?: error("fromCurrent can not be a fake override") trace.report(Errors.CONFLICTING_OVERLOADS.on(declaration, fromCurrent, fromSuper.containingDeclaration)) } + + override fun inheritanceConflict(first: CallableMemberDescriptor, second: CallableMemberDescriptor) { + val thisClassDeclaration = DescriptorToSourceUtils.descriptorToDeclaration(thisDescriptor) as? KtClassOrObject ?: error("No class declaration") + trace.report(Errors.CONFLICTING_INHERITED_MEMBERS.on(thisClassDeclaration, thisDescriptor, listOf(first, second))) + } }) OverrideResolver.resolveUnknownVisibilities(result, trace) } diff --git a/compiler/testData/diagnostics/tests/override/clashesOnInheritance/kt9550.kt b/compiler/testData/diagnostics/tests/override/clashesOnInheritance/kt9550.kt new file mode 100644 index 00000000000..8e70e835447 --- /dev/null +++ b/compiler/testData/diagnostics/tests/override/clashesOnInheritance/kt9550.kt @@ -0,0 +1,13 @@ +interface A { + fun foo() + fun bar() +} + +interface B { + fun foo() + fun bar() +} + +interface C1 : A, B { + override fun bar() +} diff --git a/compiler/testData/diagnostics/tests/override/clashesOnInheritance/kt9550.txt b/compiler/testData/diagnostics/tests/override/clashesOnInheritance/kt9550.txt new file mode 100644 index 00000000000..7db52d53281 --- /dev/null +++ b/compiler/testData/diagnostics/tests/override/clashesOnInheritance/kt9550.txt @@ -0,0 +1,25 @@ +package + +public interface A { + public abstract fun bar(): kotlin.Unit + 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 { + public abstract fun bar(): kotlin.Unit + 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 C1 : A, B { + public abstract override /*1*/ fun bar(): kotlin.Unit + public open override /*2*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + public abstract override /*1*/ /*fake_override*/ 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 a11f4e00823..4e244a24716 100644 --- a/compiler/tests/org/jetbrains/kotlin/checkers/DiagnosticsTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/checkers/DiagnosticsTestGenerated.java @@ -12146,6 +12146,12 @@ public class DiagnosticsTestGenerated extends AbstractDiagnosticsTest { doTest(fileName); } + @TestMetadata("kt9550.kt") + public void testKt9550() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/override/clashesOnInheritance/kt9550.kt"); + doTest(fileName); + } + @TestMetadata("returnTypeMismatch.kt") public void testReturnTypeMismatch() throws Exception { String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/override/clashesOnInheritance/returnTypeMismatch.kt"); diff --git a/core/descriptor.loader.java/src/org/jetbrains/kotlin/load/java/components/DescriptorResolverUtils.java b/core/descriptor.loader.java/src/org/jetbrains/kotlin/load/java/components/DescriptorResolverUtils.java index 34116d7d0b6..9d2f626c221 100644 --- a/core/descriptor.loader.java/src/org/jetbrains/kotlin/load/java/components/DescriptorResolverUtils.java +++ b/core/descriptor.loader.java/src/org/jetbrains/kotlin/load/java/components/DescriptorResolverUtils.java @@ -27,11 +27,14 @@ import org.jetbrains.kotlin.descriptors.ValueParameterDescriptor; import org.jetbrains.kotlin.load.java.structure.*; import org.jetbrains.kotlin.name.FqName; import org.jetbrains.kotlin.name.Name; -import org.jetbrains.kotlin.resolve.OverridingStrategy; +import org.jetbrains.kotlin.resolve.NonReportingOverrideStrategy; import org.jetbrains.kotlin.resolve.OverridingUtil; import org.jetbrains.kotlin.serialization.deserialization.ErrorReporter; -import java.util.*; +import java.util.Collection; +import java.util.LinkedHashSet; +import java.util.List; +import java.util.Set; public final class DescriptorResolverUtils { private DescriptorResolverUtils() { @@ -66,7 +69,7 @@ public final class DescriptorResolverUtils { OverridingUtil.generateOverridesInFunctionGroup( name, membersFromSupertypes, membersFromCurrent, classDescriptor, - new OverridingStrategy() { + new NonReportingOverrideStrategy() { @Override @SuppressWarnings("unchecked") public void addFakeOverride(@NotNull CallableMemberDescriptor fakeOverride) { diff --git a/core/descriptors/src/org/jetbrains/kotlin/builtins/functions/FunctionClassScope.kt b/core/descriptors/src/org/jetbrains/kotlin/builtins/functions/FunctionClassScope.kt index c5105bd2c0e..546ed4b9508 100644 --- a/core/descriptors/src/org/jetbrains/kotlin/builtins/functions/FunctionClassScope.kt +++ b/core/descriptors/src/org/jetbrains/kotlin/builtins/functions/FunctionClassScope.kt @@ -22,6 +22,7 @@ import org.jetbrains.kotlin.resolve.OverridingUtil import org.jetbrains.kotlin.resolve.scopes.DescriptorKindFilter import org.jetbrains.kotlin.resolve.scopes.MemberScopeImpl import org.jetbrains.kotlin.incremental.components.LookupLocation +import org.jetbrains.kotlin.resolve.NonReportingOverrideStrategy import org.jetbrains.kotlin.resolve.OverridingStrategy import org.jetbrains.kotlin.storage.StorageManager import org.jetbrains.kotlin.utils.Printer @@ -67,7 +68,7 @@ class FunctionClassScope( /* membersFromSupertypes = */ descriptors, /* membersFromCurrent = */ if (isFunction && name == invoke?.name) listOf(invoke) else listOf(), functionClass, - object : OverridingStrategy() { + object : NonReportingOverrideStrategy() { override fun addFakeOverride(fakeOverride: CallableMemberDescriptor) { OverridingUtil.resolveUnknownVisibilityForMember(fakeOverride, null) result.add(fakeOverride) diff --git a/core/descriptors/src/org/jetbrains/kotlin/descriptors/impl/EnumEntrySyntheticClassDescriptor.java b/core/descriptors/src/org/jetbrains/kotlin/descriptors/impl/EnumEntrySyntheticClassDescriptor.java index a672b25ec3d..c11ae870b4c 100644 --- a/core/descriptors/src/org/jetbrains/kotlin/descriptors/impl/EnumEntrySyntheticClassDescriptor.java +++ b/core/descriptors/src/org/jetbrains/kotlin/descriptors/impl/EnumEntrySyntheticClassDescriptor.java @@ -26,7 +26,7 @@ import org.jetbrains.kotlin.incremental.components.LookupLocation; import org.jetbrains.kotlin.incremental.components.NoLookupLocation; import org.jetbrains.kotlin.name.Name; import org.jetbrains.kotlin.resolve.DescriptorFactory; -import org.jetbrains.kotlin.resolve.OverridingStrategy; +import org.jetbrains.kotlin.resolve.NonReportingOverrideStrategy; import org.jetbrains.kotlin.resolve.OverridingUtil; import org.jetbrains.kotlin.resolve.scopes.DescriptorKindFilter; import org.jetbrains.kotlin.resolve.scopes.MemberScope; @@ -246,7 +246,7 @@ public class EnumEntrySyntheticClassDescriptor extends ClassDescriptorBase { OverridingUtil.generateOverridesInFunctionGroup( name, fromSupertypes, Collections.emptySet(), EnumEntrySyntheticClassDescriptor.this, - new OverridingStrategy() { + new NonReportingOverrideStrategy() { @Override @SuppressWarnings("unchecked") public void addFakeOverride(@NotNull CallableMemberDescriptor fakeOverride) { @@ -255,7 +255,7 @@ public class EnumEntrySyntheticClassDescriptor extends ClassDescriptorBase { } @Override - public void conflict(@NotNull CallableMemberDescriptor fromSuper, @NotNull CallableMemberDescriptor fromCurrent) { + protected void conflict(@NotNull CallableMemberDescriptor fromSuper, @NotNull CallableMemberDescriptor fromCurrent) { // Do nothing } } diff --git a/core/descriptors/src/org/jetbrains/kotlin/resolve/OverridingStrategy.kt b/core/descriptors/src/org/jetbrains/kotlin/resolve/OverridingStrategy.kt index fca7b1955b1..fb6900f1371 100644 --- a/core/descriptors/src/org/jetbrains/kotlin/resolve/OverridingStrategy.kt +++ b/core/descriptors/src/org/jetbrains/kotlin/resolve/OverridingStrategy.kt @@ -21,9 +21,23 @@ import org.jetbrains.kotlin.descriptors.CallableMemberDescriptor abstract class OverridingStrategy { abstract fun addFakeOverride(fakeOverride: CallableMemberDescriptor) - abstract fun conflict(fromSuper: CallableMemberDescriptor, fromCurrent: CallableMemberDescriptor) + abstract fun overrideConflict(fromSuper: CallableMemberDescriptor, fromCurrent: CallableMemberDescriptor) + + abstract fun inheritanceConflict(first: CallableMemberDescriptor, second: CallableMemberDescriptor) open fun setOverriddenDescriptors(member: CallableMemberDescriptor, overridden: Collection) { member.overriddenDescriptors = overridden } +} + +abstract class NonReportingOverrideStrategy : OverridingStrategy() { + override fun overrideConflict(fromSuper: CallableMemberDescriptor, fromCurrent: CallableMemberDescriptor) { + conflict(fromSuper, fromCurrent) + } + + override fun inheritanceConflict(first: CallableMemberDescriptor, second: CallableMemberDescriptor) { + conflict(first, second) + } + + protected abstract fun conflict(first: CallableMemberDescriptor, second: CallableMemberDescriptor) } \ No newline at end of file diff --git a/core/descriptors/src/org/jetbrains/kotlin/resolve/OverridingUtil.java b/core/descriptors/src/org/jetbrains/kotlin/resolve/OverridingUtil.java index ef3a67d8d6d..a45c1e772ce 100644 --- a/core/descriptors/src/org/jetbrains/kotlin/resolve/OverridingUtil.java +++ b/core/descriptors/src/org/jetbrains/kotlin/resolve/OverridingUtil.java @@ -347,7 +347,7 @@ public class OverridingUtil { break; case CONFLICT: if (isVisible) { - strategy.conflict(fromSupertype, fromCurrent); + strategy.overrideConflict(fromSupertype, fromCurrent); } bound.add(fromSupertype); break; @@ -638,7 +638,7 @@ public class OverridingUtil { new Function1() { @Override public Unit invoke(CallableMemberDescriptor descriptor) { - strategy.conflict(overrider, descriptor); + strategy.inheritanceConflict(overrider, descriptor); return Unit.INSTANCE; } }); diff --git a/core/deserialization/src/org/jetbrains/kotlin/serialization/deserialization/descriptors/DeserializedClassDescriptor.kt b/core/deserialization/src/org/jetbrains/kotlin/serialization/deserialization/descriptors/DeserializedClassDescriptor.kt index 4bd87af1d6e..0d3f73e7151 100644 --- a/core/deserialization/src/org/jetbrains/kotlin/serialization/deserialization/descriptors/DeserializedClassDescriptor.kt +++ b/core/deserialization/src/org/jetbrains/kotlin/serialization/deserialization/descriptors/DeserializedClassDescriptor.kt @@ -24,6 +24,7 @@ import org.jetbrains.kotlin.incremental.components.LookupLocation import org.jetbrains.kotlin.incremental.components.NoLookupLocation import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.resolve.DescriptorFactory +import org.jetbrains.kotlin.resolve.NonReportingOverrideStrategy import org.jetbrains.kotlin.resolve.OverridingStrategy import org.jetbrains.kotlin.resolve.OverridingUtil import org.jetbrains.kotlin.resolve.scopes.DescriptorKindFilter @@ -220,7 +221,7 @@ class DeserializedClassDescriptor( private fun generateFakeOverrides(name: Name, fromSupertypes: Collection, result: MutableCollection) { val fromCurrent = ArrayList(result) - OverridingUtil.generateOverridesInFunctionGroup(name, fromSupertypes, fromCurrent, classDescriptor, object : OverridingStrategy() { + OverridingUtil.generateOverridesInFunctionGroup(name, fromSupertypes, fromCurrent, classDescriptor, object : NonReportingOverrideStrategy() { override fun addFakeOverride(fakeOverride: CallableMemberDescriptor) { // TODO: report "cannot infer visibility" OverridingUtil.resolveUnknownVisibilityForMember(fakeOverride, null)