diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/OverrideResolver.kt b/compiler/frontend/src/org/jetbrains/kotlin/resolve/OverrideResolver.kt index 59956aa16d0..9d59197d35c 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/OverrideResolver.kt +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/OverrideResolver.kt @@ -40,6 +40,7 @@ import org.jetbrains.kotlin.descriptors.CallableMemberDescriptor.Kind.FAKE_OVERR import org.jetbrains.kotlin.diagnostics.Errors.* import org.jetbrains.kotlin.resolve.DescriptorUtils.classCanHaveAbstractMembers import org.jetbrains.kotlin.resolve.OverridingUtil.OverrideCompatibilityInfo.Result.OVERRIDABLE +import org.jetbrains.kotlin.utils.addToStdlib.assertedCast class OverrideResolver( private val trace: BindingTrace, @@ -74,10 +75,10 @@ class OverrideResolver( private interface CheckInheritedSignaturesReportStrategy { fun abstractMemberNotImplemented(descriptor: CallableMemberDescriptor) fun abstractBaseClassMemberNotImplemented(descriptor: CallableMemberDescriptor) + fun abstractMemberWithMoreSpecificType(abstractMember: CallableMemberDescriptor, concreteMember: CallableMemberDescriptor) fun multipleImplementationsMemberNotImplemented(descriptor: CallableMemberDescriptor) fun conflictingInterfaceMemberNotImplemented(descriptor: CallableMemberDescriptor) - fun returnTypeMismatchOnInheritance(descriptor1: CallableMemberDescriptor, descriptor2: CallableMemberDescriptor) - fun propertyTypeMismatchOnInheritance(descriptor1: PropertyDescriptor, descriptor2: PropertyDescriptor) + fun typeMismatchOnInheritance(descriptor1: CallableMemberDescriptor, descriptor2: CallableMemberDescriptor) } private class CollectMissingImplementationsStrategy : CheckInheritedSignaturesReportStrategy { @@ -101,12 +102,12 @@ class OverrideResolver( } } - override fun returnTypeMismatchOnInheritance(descriptor1: CallableMemberDescriptor, descriptor2: CallableMemberDescriptor) { + override fun typeMismatchOnInheritance(descriptor1: CallableMemberDescriptor, descriptor2: CallableMemberDescriptor) { // don't care } - override fun propertyTypeMismatchOnInheritance(descriptor1: PropertyDescriptor, descriptor2: PropertyDescriptor) { - // don't care + override fun abstractMemberWithMoreSpecificType(abstractMember: CallableMemberDescriptor, concreteMember: CallableMemberDescriptor) { + shouldImplement.add(abstractMember) } } @@ -115,11 +116,11 @@ class OverrideResolver( private val classDescriptor: ClassDescriptor ) : CheckInheritedSignaturesReportStrategy, CheckOverrideReportStrategy { - private val abstractNoImpl = Sets.newLinkedHashSet() - private val multipleImplementations = Sets.newLinkedHashSet() - private val abstractInBaseClassNoImpl = Sets.newLinkedHashSet() - private val conflictingInterfaceMembers = Sets.newLinkedHashSet() - private val conflictingReturnTypes = Sets.newHashSet() + private val abstractNoImpl = linkedSetOf() + private val abstractInBaseClassNoImpl = linkedSetOf() + private val multipleImplementations = linkedSetOf() + private val conflictingInterfaceMembers = linkedSetOf() + private val conflictingReturnTypes = linkedSetOf() private val onceErrorsReported = SmartHashSet>() @@ -139,25 +140,27 @@ class OverrideResolver( conflictingInterfaceMembers.add(descriptor) } - override fun returnTypeMismatchOnInheritance(descriptor1: CallableMemberDescriptor, descriptor2: CallableMemberDescriptor) { + override fun typeMismatchOnInheritance(descriptor1: CallableMemberDescriptor, descriptor2: CallableMemberDescriptor) { conflictingReturnTypes.add(descriptor1) conflictingReturnTypes.add(descriptor2) - reportInheritanceConflictIfRequired(RETURN_TYPE_MISMATCH_ON_INHERITANCE, descriptor1, descriptor2) - } - - override fun propertyTypeMismatchOnInheritance(descriptor1: PropertyDescriptor, descriptor2: PropertyDescriptor) { - conflictingReturnTypes.add(descriptor1) - conflictingReturnTypes.add(descriptor2) - - if (descriptor1.isVar || descriptor2.isVar) { - reportInheritanceConflictIfRequired(VAR_TYPE_MISMATCH_ON_INHERITANCE, descriptor1, descriptor2) + if (descriptor1 is PropertyDescriptor && descriptor2 is PropertyDescriptor) { + if (descriptor1.isVar || descriptor2.isVar) { + reportInheritanceConflictIfRequired(VAR_TYPE_MISMATCH_ON_INHERITANCE, descriptor1, descriptor2) + } + else { + reportInheritanceConflictIfRequired(PROPERTY_TYPE_MISMATCH_ON_INHERITANCE, descriptor1, descriptor2) + } } else { - reportInheritanceConflictIfRequired(PROPERTY_TYPE_MISMATCH_ON_INHERITANCE, descriptor1, descriptor2) + reportInheritanceConflictIfRequired(RETURN_TYPE_MISMATCH_ON_INHERITANCE, descriptor1, descriptor2) } } + override fun abstractMemberWithMoreSpecificType(abstractMember: CallableMemberDescriptor, concreteMember: CallableMemberDescriptor) { + typeMismatchOnInheritance(abstractMember, concreteMember) + } + private fun reportInheritanceConflictIfRequired( diagnosticFactory: DiagnosticFactory2, descriptor1: CallableMemberDescriptor, @@ -208,13 +211,12 @@ class OverrideResolver( } internal fun doReportErrors() { - if (!classCanHaveAbstractMembers(classDescriptor)) { - if (!abstractInBaseClassNoImpl.isEmpty()) { - trace.report(ABSTRACT_CLASS_MEMBER_NOT_IMPLEMENTED.on(klass, klass, abstractInBaseClassNoImpl.iterator().next())) - } - else if (!abstractNoImpl.isEmpty()) { - trace.report(ABSTRACT_MEMBER_NOT_IMPLEMENTED.on(klass, klass, abstractNoImpl.iterator().next())) - } + val canHaveAbstractMembers = classCanHaveAbstractMembers(classDescriptor) + if (abstractInBaseClassNoImpl.isNotEmpty() && !canHaveAbstractMembers) { + trace.report(ABSTRACT_CLASS_MEMBER_NOT_IMPLEMENTED.on(klass, klass, abstractInBaseClassNoImpl.first())) + } + else if (abstractNoImpl.isNotEmpty() && !canHaveAbstractMembers) { + trace.report(ABSTRACT_MEMBER_NOT_IMPLEMENTED.on(klass, klass, abstractNoImpl.first())) } conflictingInterfaceMembers.removeAll(conflictingReturnTypes) @@ -386,7 +388,7 @@ class OverrideResolver( } private fun checkNameAndDefaultForDeclaredParameter(descriptor: ValueParameterDescriptor, multipleDefaultsInSuper: Boolean) { - val parameter = DescriptorToSourceUtils.descriptorToDeclaration(descriptor) as KtParameter? ?: error("Declaration not found for parameter: " + descriptor) + val parameter = DescriptorToSourceUtils.descriptorToDeclaration(descriptor) as? KtParameter ?: error("Declaration not found for parameter: " + descriptor) if (descriptor.declaresDefaultValue()) { trace.report(DEFAULT_VALUE_NOT_ALLOWED_IN_OVERRIDE.on(parameter)) @@ -530,7 +532,7 @@ class OverrideResolver( val relevantDirectlyOverridden = getRelevantDirectlyOverridden(overriddenDeclarationsByDirectParent, allFilteredOverriddenDeclarations) - checkInheritedDescriptorsGroup(relevantDirectlyOverridden, descriptor, reportingStrategy) + checkInheritedDescriptorsGroup(descriptor, relevantDirectlyOverridden, reportingStrategy) if (kind == DELEGATION && overrideReportStrategyForDelegates != null) { checkOverridesForMember(descriptor, relevantDirectlyOverridden, overrideReportStrategyForDelegates) @@ -540,36 +542,30 @@ class OverrideResolver( checkMissingOverridesByJava8Restrictions(relevantDirectlyOverridden, reportingStrategy) } - val implementations = collectImplementations(relevantDirectlyOverridden) + val (concreteOverridden, abstractOverridden) = relevantDirectlyOverridden + .filter { !isOrOverridesSynthesized(it) } + .partition { it.modality != Modality.ABSTRACT } - val numImplementations = implementations.size + val numImplementations = concreteOverridden.size - // The most common case: there's one implementation in the supertypes with the matching return type - if (numImplementations == 1 && isReturnTypeOkForOverride(descriptor, implementations[0])) return - - val abstractOverridden = ArrayList(allFilteredOverriddenDeclarations.size) - val concreteOverridden = ArrayList(allFilteredOverriddenDeclarations.size) - filterNotSynthesizedDescriptorsByModality(allFilteredOverriddenDeclarations, abstractOverridden, concreteOverridden) - - if (numImplementations == 0) { - if (kind != DELEGATION) { - for (member in abstractOverridden) { - reportingStrategy.abstractMemberNotImplemented(member) + when (numImplementations) { + 0 -> + if (kind != DELEGATION) { + abstractOverridden.forEach { + reportingStrategy.abstractMemberNotImplemented(it) + } } - } - } - else if (numImplementations > 1) { - for (member in concreteOverridden) { - reportingStrategy.multipleImplementationsMemberNotImplemented(member) - } - } - else { - if (kind != DELEGATION) { - val membersWithMoreSpecificReturnType = collectAbstractMethodsWithMoreSpecificReturnType(abstractOverridden, implementations[0]) - for (member in membersWithMoreSpecificReturnType) { - reportingStrategy.abstractMemberNotImplemented(member) + 1 -> + if (kind != DELEGATION) { + val implementation = concreteOverridden.first() + collectAbstractMethodsWithMoreSpecificReturnType(abstractOverridden, implementation).forEach { + reportingStrategy.abstractMemberWithMoreSpecificType(it, implementation) + } + } + else -> + concreteOverridden.forEach { + reportingStrategy.multipleImplementationsMemberNotImplemented(it) } - } } } @@ -615,58 +611,6 @@ class OverrideResolver( } } - private fun collectImplementations(relevantDirectlyOverridden: Set): List { - val result = ArrayList(relevantDirectlyOverridden.size) - for (overriddenDescriptor in relevantDirectlyOverridden) { - if (isImplementation(overriddenDescriptor)) { - result.add(overriddenDescriptor) - } - } - return result - } - - private fun isImplementation(callableMemberDescriptor: CallableMemberDescriptor): Boolean { - // An abstract member is not an implementation. - if (callableMemberDescriptor.modality === Modality.ABSTRACT) return false - - // Interfaces contain fake overrides for 'toString', 'hashCode', 'equals'. - // They are not considered implementations if their dispatch receiver type is 'Any'. - val containingDeclaration = callableMemberDescriptor.containingDeclaration - assert(containingDeclaration is ClassDescriptor) { "ClassDescriptor expected, got $containingDeclaration for $callableMemberDescriptor" } - val containingClassDescriptor = containingDeclaration as ClassDescriptor - if (containingClassDescriptor.kind == ClassKind.INTERFACE && callableMemberDescriptor.kind == FAKE_OVERRIDE) { - val dispatchReceiverParameter = callableMemberDescriptor.dispatchReceiverParameter ?: return false - if (KotlinBuiltIns.isAny(dispatchReceiverParameter.type)) return false - } - - // A FAKE_OVERRIDE is an implementation iff it overrides an implementation. - if (callableMemberDescriptor.kind == FAKE_OVERRIDE) { - for (overriddenDescriptor in callableMemberDescriptor.overriddenDescriptors) { - if (isImplementation(overriddenDescriptor)) return true - } - return false - } - - return true - } - - private fun filterNotSynthesizedDescriptorsByModality( - allOverriddenDeclarations: Set, - abstractOverridden: MutableList, - concreteOverridden: MutableList - ) { - for (overridden in allOverriddenDeclarations) { - if (!isOrOverridesSynthesized(overridden)) { - if (overridden.modality === Modality.ABSTRACT) { - abstractOverridden.add(overridden) - } - else { - concreteOverridden.add(overridden) - } - } - } - } - private fun collectAbstractMethodsWithMoreSpecificReturnType( abstractOverridden: List, implementation: CallableMemberDescriptor @@ -742,24 +686,24 @@ class OverrideResolver( } private fun checkInheritedDescriptorsGroup( - inheritedDescriptors: Collection, - mostSpecific: CallableMemberDescriptor, + descriptor: CallableMemberDescriptor, + overriddenDescriptors: Collection, reportingStrategy: CheckInheritedSignaturesReportStrategy ) { - if (inheritedDescriptors.size > 1) { - val mostSpecificProperty = if (mostSpecific is PropertyDescriptor) mostSpecific else null + if (overriddenDescriptors.size <= 1) return - for (inheritedDescriptor in inheritedDescriptors) { - if (mostSpecificProperty != null) { - assert(inheritedDescriptor is PropertyDescriptor) { inheritedDescriptor.toString() + " inherited from " + mostSpecificProperty + " is not a property" } - val inheritedPropertyDescriptor = inheritedDescriptor as PropertyDescriptor + val propertyDescriptor = descriptor as? PropertyDescriptor - if (!isPropertyTypeOkForOverride(inheritedPropertyDescriptor, mostSpecificProperty)) { - reportingStrategy.propertyTypeMismatchOnInheritance(mostSpecificProperty, inheritedPropertyDescriptor) - } + for (overriddenDescriptor in overriddenDescriptors) { + if (propertyDescriptor != null) { + val overriddenPropertyDescriptor = overriddenDescriptor.assertedCast { "$overriddenDescriptor is not a property" } + if (!isPropertyTypeOkForOverride(overriddenPropertyDescriptor, propertyDescriptor)) { + reportingStrategy.typeMismatchOnInheritance(propertyDescriptor, overriddenPropertyDescriptor) } - else if (!isReturnTypeOkForOverride(inheritedDescriptor, mostSpecific)) { - reportingStrategy.returnTypeMismatchOnInheritance(mostSpecific, inheritedDescriptor) + } + else { + if (!isReturnTypeOkForOverride(overriddenDescriptor, descriptor)) { + reportingStrategy.typeMismatchOnInheritance(descriptor, overriddenDescriptor) } } } @@ -775,8 +719,9 @@ class OverrideResolver( if (overriddenDescriptors.isEmpty()) { val containingDeclaration = declared.containingDeclaration - assert(containingDeclaration is ClassDescriptor) { "Overrides may only be resolved in a class, but $declared comes from $containingDeclaration" } - val declaringClass = containingDeclaration as ClassDescriptor + val declaringClass = containingDeclaration.assertedCast { + "Overrides may only be resolved in a class, but $declared comes from $containingDeclaration" + } val invisibleOverriddenDescriptor = findInvisibleOverriddenDescriptor(declared, declaringClass) if (invisibleOverriddenDescriptor != null) { @@ -796,15 +741,14 @@ class OverrideResolver( val propertyMemberDescriptor = if (memberDescriptor is PropertyDescriptor) memberDescriptor else null for (overridden in overriddenDescriptors) { -// if (overridden == null) continue - if (!overridden.isOverridable) { reportError.overridingFinalMember(memberDescriptor, overridden) } if (propertyMemberDescriptor != null) { - assert(overridden is PropertyDescriptor) { overridden.toString() + " is overridden by property " + propertyMemberDescriptor } - val overriddenProperty = overridden as PropertyDescriptor + val overriddenProperty = overridden.assertedCast { + "$overridden is overridden by property $propertyMemberDescriptor" + } if (!isPropertyTypeOkForOverride(overriddenProperty, propertyMemberDescriptor)) { reportError.propertyTypeMismatchOnOverride(propertyMemberDescriptor, overriddenProperty) } diff --git a/compiler/testData/diagnostics/tests/override/clashesOnInheritance/kt13355.kt b/compiler/testData/diagnostics/tests/override/clashesOnInheritance/kt13355.kt new file mode 100644 index 00000000000..a8d15e0936d --- /dev/null +++ b/compiler/testData/diagnostics/tests/override/clashesOnInheritance/kt13355.kt @@ -0,0 +1,13 @@ +interface IFooAny { + val foo: Any +} + +interface IFooStr : IFooAny { + override val foo: String +} + +abstract class BaseAny(override val foo: Any): IFooAny + +abstract class BaseStr : BaseAny(42), IFooStr + +class C : BaseStr() \ No newline at end of file diff --git a/compiler/testData/diagnostics/tests/override/clashesOnInheritance/kt13355.txt b/compiler/testData/diagnostics/tests/override/clashesOnInheritance/kt13355.txt new file mode 100644 index 00000000000..0a2983a7c1e --- /dev/null +++ b/compiler/testData/diagnostics/tests/override/clashesOnInheritance/kt13355.txt @@ -0,0 +1,39 @@ +package + +public abstract class BaseAny : IFooAny { + public constructor BaseAny(/*0*/ foo: kotlin.Any) + public open override /*1*/ val foo: kotlin.Any + 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 abstract class BaseStr : BaseAny, IFooStr { + public constructor BaseStr() + public open override /*2*/ /*fake_override*/ val foo: kotlin.String + public open override /*2*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + public open override /*2*/ /*fake_override*/ fun hashCode(): kotlin.Int + public open override /*2*/ /*fake_override*/ fun toString(): kotlin.String +} + +public final class C : BaseStr { + public constructor C() + public open override /*1*/ /*fake_override*/ val foo: 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 IFooAny { + public abstract val foo: kotlin.Any + 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 IFooStr : IFooAny { + public abstract override /*1*/ val foo: 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 +} diff --git a/compiler/testData/diagnostics/tests/override/clashesOnInheritance/kt13355viaJava.kt b/compiler/testData/diagnostics/tests/override/clashesOnInheritance/kt13355viaJava.kt new file mode 100644 index 00000000000..41679b53d86 --- /dev/null +++ b/compiler/testData/diagnostics/tests/override/clashesOnInheritance/kt13355viaJava.kt @@ -0,0 +1,47 @@ +// FILE: K.kt +abstract class ATest1 : TestNN.JNullVsNotNull() + +abstract class ATest2 : TestNN.JUnknownImpl(), TestNN.JNotNull + +abstract class ATest3 : TestNN.JUnknownVsNotNull() + +class CTest1 : TestNN.JNullVsNotNull() + +class CTest2 : TestNN.JUnknownImpl(), TestNN.JNotNull + +class CTest3 : TestNN.JUnknownVsNotNull() + +// FILE: TestNN.java +import org.jetbrains.annotations.*; + +public class TestNN { + public interface JNull { + @Nullable Object foo(); + } + + public interface JNotNull { + @NotNull Object foo(); + } + + public static class JNullVsNotNull implements JNull, JNotNull { + public Object foo() { + return this; + } + } + + public static class JNullBase { + @Nullable public Object foo() { + return null; + } + } + + public static class JUnknownImpl extends JNullBase { + public Object foo() { + return this; + } + } + + public static class JUnknownVsNotNull extends JUnknownImpl implements JNotNull { + } +} + diff --git a/compiler/testData/diagnostics/tests/override/clashesOnInheritance/kt13355viaJava.txt b/compiler/testData/diagnostics/tests/override/clashesOnInheritance/kt13355viaJava.txt new file mode 100644 index 00000000000..7119cdc9242 --- /dev/null +++ b/compiler/testData/diagnostics/tests/override/clashesOnInheritance/kt13355viaJava.txt @@ -0,0 +1,106 @@ +package + +public abstract class ATest1 : TestNN.JNullVsNotNull { + public constructor ATest1() + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + public open override /*1*/ /*fake_override*/ fun foo(): kotlin.Any + public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String +} + +public abstract class ATest2 : TestNN.JUnknownImpl, TestNN.JNotNull { + public constructor ATest2() + public open override /*2*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + @org.jetbrains.annotations.NotNull public open override /*2*/ /*fake_override*/ fun foo(): kotlin.Any + public open override /*2*/ /*fake_override*/ fun hashCode(): kotlin.Int + public open override /*2*/ /*fake_override*/ fun toString(): kotlin.String +} + +public abstract class ATest3 : TestNN.JUnknownVsNotNull { + public constructor ATest3() + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + @org.jetbrains.annotations.NotNull public open override /*1*/ /*fake_override*/ fun foo(): kotlin.Any + public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String +} + +public final class CTest1 : TestNN.JNullVsNotNull { + public constructor CTest1() + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + public open override /*1*/ /*fake_override*/ fun foo(): kotlin.Any + public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String +} + +public final class CTest2 : TestNN.JUnknownImpl, TestNN.JNotNull { + public constructor CTest2() + public open override /*2*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + @org.jetbrains.annotations.NotNull public open override /*2*/ /*fake_override*/ fun foo(): kotlin.Any + public open override /*2*/ /*fake_override*/ fun hashCode(): kotlin.Int + public open override /*2*/ /*fake_override*/ fun toString(): kotlin.String +} + +public final class CTest3 : TestNN.JUnknownVsNotNull { + public constructor CTest3() + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + @org.jetbrains.annotations.NotNull public open override /*1*/ /*fake_override*/ fun foo(): kotlin.Any + public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String +} + +public open class TestNN { + public constructor TestNN() + 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 JNotNull { + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + @org.jetbrains.annotations.NotNull public abstract fun foo(): kotlin.Any + public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String + } + + public interface JNull { + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + @org.jetbrains.annotations.Nullable public abstract fun foo(): kotlin.Any? + public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String + } + + public open class JNullBase { + public constructor JNullBase() + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + @org.jetbrains.annotations.Nullable public open fun foo(): kotlin.Any? + public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String + } + + public open class JNullVsNotNull : TestNN.JNull, TestNN.JNotNull { + public constructor JNullVsNotNull() + public open override /*2*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + public open override /*2*/ fun foo(): kotlin.Any + public open override /*2*/ /*fake_override*/ fun hashCode(): kotlin.Int + public open override /*2*/ /*fake_override*/ fun toString(): kotlin.String + } + + public open class JUnknownImpl : TestNN.JNullBase { + public constructor JUnknownImpl() + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + public open override /*1*/ fun foo(): kotlin.Any? + public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String + } + + public open class JUnknownVsNotNull : TestNN.JUnknownImpl, TestNN.JNotNull { + public constructor JUnknownVsNotNull() + public open override /*2*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + @org.jetbrains.annotations.NotNull public open override /*2*/ /*fake_override*/ fun foo(): kotlin.Any + public open override /*2*/ /*fake_override*/ fun hashCode(): kotlin.Int + public open override /*2*/ /*fake_override*/ fun toString(): kotlin.String + } + + // Static members + public final /*synthesized*/ fun JNotNull(/*0*/ function: () -> kotlin.Any): TestNN.JNotNull + public final /*synthesized*/ fun JNull(/*0*/ function: () -> kotlin.Any?): TestNN.JNull +} diff --git a/compiler/testData/diagnostics/tests/override/kt4763.kt b/compiler/testData/diagnostics/tests/override/kt4763.kt index 1cecb093fb9..7176a31711b 100644 --- a/compiler/testData/diagnostics/tests/override/kt4763.kt +++ b/compiler/testData/diagnostics/tests/override/kt4763.kt @@ -6,6 +6,6 @@ open class B { open fun f(): CharSequence = "charSequence" } -class C : B(), A +class C : B(), A -val d: A = object : B(), A {} +val d: A = object : B(), A {} diff --git a/compiler/tests/org/jetbrains/kotlin/checkers/DiagnosticsTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/checkers/DiagnosticsTestGenerated.java index 52fb76151cb..c111a8a3d93 100644 --- a/compiler/tests/org/jetbrains/kotlin/checkers/DiagnosticsTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/checkers/DiagnosticsTestGenerated.java @@ -14613,6 +14613,18 @@ public class DiagnosticsTestGenerated extends AbstractDiagnosticsTest { doTest(fileName); } + @TestMetadata("kt13355.kt") + public void testKt13355() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/override/clashesOnInheritance/kt13355.kt"); + doTest(fileName); + } + + @TestMetadata("kt13355viaJava.kt") + public void testKt13355viaJava() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/override/clashesOnInheritance/kt13355viaJava.kt"); + doTest(fileName); + } + @TestMetadata("kt9550.kt") public void testKt9550() throws Exception { String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/override/clashesOnInheritance/kt9550.kt"); diff --git a/core/util.runtime/src/org/jetbrains/kotlin/utils/addToStdlib.kt b/core/util.runtime/src/org/jetbrains/kotlin/utils/addToStdlib.kt index 7e50a77f0f8..86a30e2edad 100644 --- a/core/util.runtime/src/org/jetbrains/kotlin/utils/addToStdlib.kt +++ b/core/util.runtime/src/org/jetbrains/kotlin/utils/addToStdlib.kt @@ -80,6 +80,7 @@ fun T.check(predicate: (T) -> Boolean): T? = if (predicate(this)) this inline fun Any?.safeAs(): T? = this as? T inline fun Any?.cast(): T = this as T +inline fun Any?.assertedCast(message: () -> String): T = this as? T ?: throw AssertionError(message()) fun constant(calculator: () -> T): T { val cached = constantMap[calculator]