Refine types of type parameters before checking their equality in OverridingUtil
This commit is contained in:
@@ -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<CallableMemberDescriptor> {
|
||||
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<CallableMemberDescriptor>,
|
||||
implementation: CallableMemberDescriptor
|
||||
implementation: CallableMemberDescriptor,
|
||||
kotlinTypeRefiner: KotlinTypeRefiner
|
||||
): List<CallableMemberDescriptor> =
|
||||
abstractOverridden.filter { abstractMember -> !isReturnTypeOkForOverride(abstractMember, implementation) }
|
||||
abstractOverridden.filter { abstractMember -> !isReturnTypeOkForOverride(abstractMember, implementation, kotlinTypeRefiner) }
|
||||
|
||||
private fun getRelevantDirectlyOverridden(
|
||||
overriddenByParent: MutableMap<CallableMemberDescriptor, Set<CallableMemberDescriptor>>,
|
||||
@@ -778,7 +790,8 @@ class OverrideResolver(
|
||||
private fun checkInheritedDescriptorsGroup(
|
||||
descriptor: CallableMemberDescriptor,
|
||||
overriddenDescriptors: Collection<CallableMemberDescriptor>,
|
||||
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<CallableMemberDescriptor>,
|
||||
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<PropertyDescriptor> {
|
||||
"$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(
|
||||
|
||||
@@ -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");
|
||||
}
|
||||
}
|
||||
|
||||
+1
-1
@@ -1,7 +1,7 @@
|
||||
actual typealias Expect = String
|
||||
|
||||
interface Derived : Base {
|
||||
override fun expectInReturnType(): <!RETURN_TYPE_MISMATCH_ON_OVERRIDE!>Expect<!>
|
||||
override fun expectInReturnType(): Expect
|
||||
|
||||
override fun expectInArgument(e: Expect)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user