diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/OverrideResolver.kt b/compiler/frontend/src/org/jetbrains/kotlin/resolve/OverrideResolver.kt index 39e331dafa3..68e3d012988 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/OverrideResolver.kt +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/OverrideResolver.kt @@ -38,9 +38,12 @@ import org.jetbrains.kotlin.psi.* import org.jetbrains.kotlin.resolve.DescriptorUtils.classCanHaveAbstractFakeOverride import org.jetbrains.kotlin.resolve.OverridingUtil.OverrideCompatibilityInfo.Result.OVERRIDABLE import org.jetbrains.kotlin.resolve.calls.callResolverUtil.isOrOverridesSynthesized +import org.jetbrains.kotlin.resolve.descriptorUtil.getKotlinTypeRefiner +import org.jetbrains.kotlin.resolve.descriptorUtil.module import org.jetbrains.kotlin.types.* import org.jetbrains.kotlin.types.checker.KotlinTypeChecker import org.jetbrains.kotlin.types.checker.KotlinTypeRefiner +import org.jetbrains.kotlin.types.checker.NewKotlinTypeCheckerImpl import org.jetbrains.kotlin.types.refinement.TypeRefinement import org.jetbrains.kotlin.utils.addToStdlib.assertedCast import java.util.* @@ -74,7 +77,7 @@ class OverrideResolver( val inheritedMemberErrors = CollectErrorInformationForInheritedMembersStrategy(klass, classDescriptor) - checkInheritedAndDelegatedSignatures(classDescriptor, inheritedMemberErrors, inheritedMemberErrors) + checkInheritedAndDelegatedSignatures(classDescriptor, inheritedMemberErrors, inheritedMemberErrors, kotlinTypeRefiner) inheritedMemberErrors.doReportErrors() } @@ -378,7 +381,7 @@ class OverrideResolver( override fun varOverriddenByVal(overriding: CallableMemberDescriptor, overridden: CallableMemberDescriptor) { throw IllegalStateException("Component functions are not properties") } - }) + }, kotlinTypeRefiner) } private fun checkOverrideForCopyFunction(copyFunction: CallableMemberDescriptor) { @@ -561,18 +564,25 @@ class OverrideResolver( fun getMissingImplementations(classDescriptor: ClassDescriptor): Set { val collector = CollectMissingImplementationsStrategy() - checkInheritedAndDelegatedSignatures(classDescriptor, collector, null) + // Note that it is fine to pass default refiner here. Reason: + // 1. We bind overrides with proper refiners and [checkInheritedAndDelegatedSignatures] skips all properly-bound overrides, + // so we would consider only unbound overrides + // 2. Using default refiner instead of proper one can only increase amount of type mismatches, not decrease it + // Putting 1 and 2 together means that using default refiner might make already unbound overrides even "more unbound", which + // isn't an issue for case of [getMissingImplementations] + checkInheritedAndDelegatedSignatures(classDescriptor, collector, null, KotlinTypeRefiner.Default) return collector.shouldImplement } private fun checkInheritedAndDelegatedSignatures( classDescriptor: ClassDescriptor, inheritedReportStrategy: CheckInheritedSignaturesReportStrategy, - overrideReportStrategyForDelegates: CheckOverrideReportStrategy? + overrideReportStrategyForDelegates: CheckOverrideReportStrategy?, + kotlinTypeRefiner: KotlinTypeRefiner ) { for (member in DescriptorUtils.getAllDescriptors(classDescriptor.defaultType.memberScope)) { if (member is CallableMemberDescriptor) { - checkInheritedAndDelegatedSignatures(member, inheritedReportStrategy, overrideReportStrategyForDelegates) + checkInheritedAndDelegatedSignatures(member, inheritedReportStrategy, overrideReportStrategyForDelegates, kotlinTypeRefiner) } } } @@ -580,7 +590,8 @@ class OverrideResolver( private fun checkInheritedAndDelegatedSignatures( descriptor: CallableMemberDescriptor, reportingStrategy: CheckInheritedSignaturesReportStrategy, - overrideReportStrategyForDelegates: CheckOverrideReportStrategy? + overrideReportStrategyForDelegates: CheckOverrideReportStrategy?, + kotlinTypeRefiner: KotlinTypeRefiner ) { val kind = descriptor.kind if (kind != FAKE_OVERRIDE && kind != DELEGATION) return @@ -606,10 +617,10 @@ class OverrideResolver( return } - checkInheritedDescriptorsGroup(descriptor, relevantDirectlyOverridden, reportingStrategy) + checkInheritedDescriptorsGroup(descriptor, relevantDirectlyOverridden, reportingStrategy, kotlinTypeRefiner) if (kind == DELEGATION && overrideReportStrategyForDelegates != null) { - checkOverridesForMember(descriptor, relevantDirectlyOverridden, overrideReportStrategyForDelegates) + checkOverridesForMember(descriptor, relevantDirectlyOverridden, overrideReportStrategyForDelegates, kotlinTypeRefiner) } if (kind != DELEGATION) { @@ -632,7 +643,7 @@ class OverrideResolver( 1 -> if (kind != DELEGATION) { val implementation = concreteOverridden.first() - collectAbstractMethodsWithMoreSpecificReturnType(abstractOverridden, implementation).forEach { + collectAbstractMethodsWithMoreSpecificReturnType(abstractOverridden, implementation, kotlinTypeRefiner).forEach { reportingStrategy.abstractMemberWithMoreSpecificType(it, implementation) } } @@ -703,9 +714,10 @@ class OverrideResolver( private fun collectAbstractMethodsWithMoreSpecificReturnType( abstractOverridden: List, - implementation: CallableMemberDescriptor + implementation: CallableMemberDescriptor, + kotlinTypeRefiner: KotlinTypeRefiner ): List = - abstractOverridden.filter { abstractMember -> !isReturnTypeOkForOverride(abstractMember, implementation) } + abstractOverridden.filter { abstractMember -> !isReturnTypeOkForOverride(abstractMember, implementation, kotlinTypeRefiner) } private fun getRelevantDirectlyOverridden( overriddenByParent: MutableMap>, @@ -778,7 +790,8 @@ class OverrideResolver( private fun checkInheritedDescriptorsGroup( descriptor: CallableMemberDescriptor, overriddenDescriptors: Collection, - reportingStrategy: CheckInheritedSignaturesReportStrategy + reportingStrategy: CheckInheritedSignaturesReportStrategy, + kotlinTypeRefiner: KotlinTypeRefiner ) { if (overriddenDescriptors.size <= 1) return @@ -792,7 +805,7 @@ class OverrideResolver( reportingStrategy.typeMismatchOnInheritance(propertyDescriptor, overriddenPropertyDescriptor) } } else { - if (!isReturnTypeOkForOverride(overriddenDescriptor, descriptor)) { + if (!isReturnTypeOkForOverride(overriddenDescriptor, descriptor, kotlinTypeRefiner)) { reportingStrategy.typeMismatchOnInheritance(descriptor, overriddenDescriptor) } } @@ -806,7 +819,7 @@ class OverrideResolver( ) { val overriddenDescriptors = declared.overriddenDescriptors - checkOverridesForMember(declared, overriddenDescriptors, reportError) + checkOverridesForMember(declared, overriddenDescriptors, reportError, kotlinTypeRefiner) if (overriddenDescriptors.isEmpty()) { val containingDeclaration = declared.containingDeclaration @@ -829,7 +842,8 @@ class OverrideResolver( private fun checkOverridesForMember( memberDescriptor: CallableMemberDescriptor, overriddenDescriptors: Collection, - reportError: CheckOverrideReportStrategy + reportError: CheckOverrideReportStrategy, + kotlinTypeRefiner: KotlinTypeRefiner ) { val propertyMemberDescriptor = if (memberDescriptor is PropertyDescriptor) memberDescriptor else null @@ -842,10 +856,10 @@ class OverrideResolver( val overriddenProperty = overridden.assertedCast { "$overridden is overridden by property $propertyMemberDescriptor" } - if (!isPropertyTypeOkForOverride(overriddenProperty, propertyMemberDescriptor)) { + if (!isPropertyTypeOkForOverride(overriddenProperty, propertyMemberDescriptor, kotlinTypeRefiner)) { reportError.propertyTypeMismatchOnOverride(propertyMemberDescriptor, overriddenProperty) } - } else if (!isReturnTypeOkForOverride(overridden, memberDescriptor)) { + } else if (!isReturnTypeOkForOverride(overridden, memberDescriptor, kotlinTypeRefiner)) { reportError.returnTypeMismatchOnOverride(memberDescriptor, overridden) } @@ -857,7 +871,8 @@ class OverrideResolver( private fun isReturnTypeOkForOverride( superDescriptor: CallableDescriptor, - subDescriptor: CallableDescriptor + subDescriptor: CallableDescriptor, + kotlinTypeRefiner: KotlinTypeRefiner ): Boolean { val typeSubstitutor = prepareTypeSubstitutor(superDescriptor, subDescriptor) ?: return false @@ -867,7 +882,7 @@ class OverrideResolver( val substitutedSuperReturnType = typeSubstitutor.substitute(superReturnType, Variance.OUT_VARIANCE)!! - return KotlinTypeChecker.DEFAULT.isSubtypeOf(subReturnType, substitutedSuperReturnType) + return NewKotlinTypeCheckerImpl(kotlinTypeRefiner).isSubtypeOf(subReturnType, substitutedSuperReturnType) } private fun prepareTypeSubstitutor( diff --git a/core/descriptors/src/org/jetbrains/kotlin/resolve/OverridingUtil.java b/core/descriptors/src/org/jetbrains/kotlin/resolve/OverridingUtil.java index a5413935fc4..f231960a92d 100644 --- a/core/descriptors/src/org/jetbrains/kotlin/resolve/OverridingUtil.java +++ b/core/descriptors/src/org/jetbrains/kotlin/resolve/OverridingUtil.java @@ -322,7 +322,11 @@ public class OverridingUtil { } for (int i = 0; i < superValueParameters.size(); i++) { - if (!areTypesEquivalent(superValueParameters.get(i), subValueParameters.get(i), typeChecker)) { + if (!areTypesEquivalent( + kotlinTypeRefiner.refineType(superValueParameters.get(i)), + kotlinTypeRefiner.refineType(subValueParameters.get(i)), + typeChecker) + ) { return OverrideCompatibilityInfo.incompatible("Value parameter type mismatch"); } } diff --git a/idea/testData/multiplatform/overrideExpect/jvm/jvm.kt b/idea/testData/multiplatform/overrideExpect/jvm/jvm.kt index 2e8fe89c68f..2fdbc0b6265 100644 --- a/idea/testData/multiplatform/overrideExpect/jvm/jvm.kt +++ b/idea/testData/multiplatform/overrideExpect/jvm/jvm.kt @@ -1,7 +1,7 @@ actual typealias Expect = String interface Derived : Base { - override fun expectInReturnType(): Expect + override fun expectInReturnType(): Expect override fun expectInArgument(e: Expect)