FIR/FE1.0: keep flexibility when approximating local types

This commit is contained in:
pyos
2022-09-12 18:08:35 +02:00
committed by teamcity
parent adcbc5ec99
commit be5c4a91a4
14 changed files with 222 additions and 28 deletions
@@ -621,6 +621,8 @@ public interface Errors {
DiagnosticFactory1.create(ERROR, DECLARATION_SIGNATURE);
DiagnosticFactory1<KtDeclaration, KotlinType> APPROXIMATED_LOCAL_TYPE_WILL_BECOME_NULLABLE =
DiagnosticFactory1.create(WARNING, DECLARATION_SIGNATURE);
DiagnosticFactory1<KtDeclaration, KotlinType> APPROXIMATED_LOCAL_TYPE_WILL_BECOME_FLEXIBLE =
DiagnosticFactory1.create(WARNING, DECLARATION_SIGNATURE);
DiagnosticFactory1<KtNamedDeclaration, TypeParameterDescriptor>
KCLASS_WITH_NULLABLE_TYPE_PARAMETER_IN_SIGNATURE = DiagnosticFactory1.create(ERROR, PositioningStrategies.DECLARATION_NAME);
@@ -1069,6 +1069,8 @@ public class DefaultErrorMessages {
MAP.put(AMBIGUOUS_ANONYMOUS_TYPE_INFERRED, "Right-hand side has anonymous type. Please specify type explicitly", TO_STRING);
MAP.put(APPROXIMATED_LOCAL_TYPE_WILL_BECOME_NULLABLE,
"Declaration return type inferred as ''{0}'' instead of ''{0}?''. This will be fixed in Kotlin 1.9. Please specify the type explicitly to avoid future errors or unexpected changes in behavior. See https://youtrack.jetbrains.com/issue/KT-53982 for details.", TO_STRING);
MAP.put(APPROXIMATED_LOCAL_TYPE_WILL_BECOME_FLEXIBLE,
"Declaration return type inferred as ''{0}'' but it may be nullable. This will be fixed in Kotlin 1.9. Please specify the type explicitly to avoid unexpected changes in behavior. See https://youtrack.jetbrains.com/issue/KT-53982 for details.", TO_STRING);
MAP.put(KCLASS_WITH_NULLABLE_TYPE_PARAMETER_IN_SIGNATURE,
"Declaration has an inconsistent return type. Please add upper bound Any for type parameter ''{0}'' or specify return type explicitly", NAME);
@@ -1094,10 +1094,22 @@ public class DescriptorResolver {
substitutedSuperType = approximatingSuperType;
}
UnwrappedType unwrapped = type.unwrap();
boolean lowerNullable = FlexibleTypesKt.lowerIfFlexible(unwrapped).isMarkedNullable();
boolean upperNullable = FlexibleTypesKt.upperIfFlexible(unwrapped).isMarkedNullable();
if (languageVersionSettings.supportsFeature(LanguageFeature.KeepNullabilityWhenApproximatingLocalType)) {
return TypeUtils.makeNullableIfNeeded(substitutedSuperType, type.isMarkedNullable());
} else if (type.isMarkedNullable()) {
trace.report(APPROXIMATED_LOCAL_TYPE_WILL_BECOME_NULLABLE.on(declaration, substitutedSuperType));
if (lowerNullable != upperNullable) {
return KotlinTypeFactory.flexibleType(
FlexibleTypesKt.lowerIfFlexible(substitutedSuperType),
FlexibleTypesKt.upperIfFlexible(substitutedSuperType).makeNullableAsSpecified(true));
}
return TypeUtils.makeNullableIfNeeded(substitutedSuperType, upperNullable);
} else if (upperNullable) {
if (lowerNullable) {
trace.report(APPROXIMATED_LOCAL_TYPE_WILL_BECOME_NULLABLE.on(declaration, substitutedSuperType));
} else {
trace.report(APPROXIMATED_LOCAL_TYPE_WILL_BECOME_FLEXIBLE.on(declaration, substitutedSuperType));
}
}
return substitutedSuperType;
}