Change "most specific return type" definition for fake overrides.
Given overridden descriptors D = d[i]. 1. Find D*, subset of D: returnType(d* from D*) <: returnType(d) for each d from D. Always prefer var to val. 2. Prefer non-flexible return type to flexible. Check for var/val overrides properly (NB: this will report PROPERTY_TYPE_MISMATCH_ON_OVERRIDE for all properties, not just overrides involving vars as it was before).
This commit is contained in:
@@ -499,7 +499,7 @@ public class OverrideResolver {
|
||||
Set<CallableMemberDescriptor> relevantDirectlyOverridden =
|
||||
getRelevantDirectlyOverridden(overriddenDeclarationsByDirectParent, allFilteredOverriddenDeclarations);
|
||||
|
||||
checkInheritedDescriptorsGroup(relevantDirectlyOverridden, reportingStrategy);
|
||||
checkInheritedDescriptorsGroup(relevantDirectlyOverridden, descriptor, reportingStrategy);
|
||||
|
||||
if (kind == DELEGATION && overrideReportStrategyForDelegates != null) {
|
||||
checkOverridesForMember(descriptor, relevantDirectlyOverridden, overrideReportStrategyForDelegates);
|
||||
@@ -816,28 +816,25 @@ public class OverrideResolver {
|
||||
|
||||
private static void checkInheritedDescriptorsGroup(
|
||||
@NotNull Collection<CallableMemberDescriptor> inheritedDescriptors,
|
||||
@NotNull CallableMemberDescriptor mostSpecific,
|
||||
@NotNull CheckInheritedSignaturesReportStrategy reportingStrategy
|
||||
) {
|
||||
// FIXME This algorithm depends on transitiveness of sub-typing relation, which is broken in presence of flexible types.
|
||||
if (inheritedDescriptors.size() > 1) {
|
||||
Iterator<CallableMemberDescriptor> inheritedIterator = inheritedDescriptors.iterator();
|
||||
CallableMemberDescriptor mostSpecificInherited = inheritedIterator.next();
|
||||
while (inheritedIterator.hasNext()) {
|
||||
CallableMemberDescriptor overriddenDescriptor = inheritedIterator.next();
|
||||
if (OverridingUtil.isMoreSpecific(overriddenDescriptor, mostSpecificInherited)) {
|
||||
mostSpecificInherited = overriddenDescriptor;
|
||||
}
|
||||
}
|
||||
PropertyDescriptor mostSpecificProperty = mostSpecific instanceof PropertyDescriptor ? (PropertyDescriptor) mostSpecific : null;
|
||||
|
||||
for (CallableMemberDescriptor inheritedDescriptor : inheritedDescriptors) {
|
||||
if (!OverridingUtil.isMoreSpecific(mostSpecificInherited, inheritedDescriptor)) {
|
||||
if (inheritedDescriptor instanceof PropertyDescriptor) {
|
||||
reportingStrategy.propertyTypeMismatchOnInheritance(mostSpecificInherited, inheritedDescriptor);
|
||||
}
|
||||
else {
|
||||
reportingStrategy.returnTypeMismatchOnInheritance(mostSpecificInherited, inheritedDescriptor);
|
||||
if (mostSpecificProperty != null) {
|
||||
assert inheritedDescriptor instanceof PropertyDescriptor
|
||||
: inheritedDescriptor + " inherited from " + mostSpecificProperty + " is not a property";
|
||||
PropertyDescriptor inheritedPropertyDescriptor = (PropertyDescriptor) inheritedDescriptor;
|
||||
|
||||
if (!isPropertyTypeOkForOverride(inheritedPropertyDescriptor, mostSpecificProperty)) {
|
||||
reportingStrategy.propertyTypeMismatchOnInheritance(mostSpecific, inheritedDescriptor);
|
||||
}
|
||||
}
|
||||
else if (!isReturnTypeOkForOverride(inheritedDescriptor, mostSpecific)) {
|
||||
reportingStrategy.returnTypeMismatchOnInheritance(mostSpecific, inheritedDescriptor);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -935,11 +932,15 @@ public class OverrideResolver {
|
||||
TypeSubstitutor typeSubstitutor = prepareTypeSubstitutor(superDescriptor, subDescriptor);
|
||||
if (typeSubstitutor == null) return false;
|
||||
|
||||
if (!superDescriptor.isVar()) return true;
|
||||
|
||||
KotlinType substitutedSuperReturnType = typeSubstitutor.substitute(superDescriptor.getType(), Variance.OUT_VARIANCE);
|
||||
assert substitutedSuperReturnType != null;
|
||||
return KotlinTypeChecker.DEFAULT.equalTypes(subDescriptor.getType(), substitutedSuperReturnType);
|
||||
|
||||
if (superDescriptor.isVar()) {
|
||||
return KotlinTypeChecker.DEFAULT.equalTypes(subDescriptor.getType(), substitutedSuperReturnType);
|
||||
}
|
||||
else {
|
||||
return KotlinTypeChecker.DEFAULT.isSubtypeOf(subDescriptor.getType(), substitutedSuperReturnType);
|
||||
}
|
||||
}
|
||||
|
||||
private void checkOverrideForComponentFunction(@NotNull final CallableMemberDescriptor componentFunction) {
|
||||
|
||||
Reference in New Issue
Block a user