Support new form of definitely non-nullable types: T & Any
^KT-26245 In Progress
This commit is contained in:
committed by
teamcityserver
parent
cdd8d1c163
commit
302eacbf59
@@ -161,6 +161,8 @@ public interface Errors {
|
||||
DiagnosticFactory0<KtNullableType> REDUNDANT_NULLABLE = DiagnosticFactory0.create(WARNING, NULLABLE_TYPE);
|
||||
DiagnosticFactory0<KtDefinitelyNotNullType> DEFINITELY_NOT_NULLABLE_NOT_APPLICABLE = DiagnosticFactory0.create(ERROR);
|
||||
DiagnosticFactory0<KtNullableType> NULLABLE_ON_DEFINITELY_NOT_NULLABLE = DiagnosticFactory0.create(ERROR);
|
||||
DiagnosticFactory0<KtTypeReference> INCORRECT_LEFT_COMPONENT_OF_INTERSECTION = DiagnosticFactory0.create(ERROR);
|
||||
DiagnosticFactory0<KtTypeReference> INCORRECT_RIGHT_COMPONENT_OF_INTERSECTION = DiagnosticFactory0.create(ERROR);
|
||||
DiagnosticFactory2<KtElement, Integer, DeclarationDescriptor> WRONG_NUMBER_OF_TYPE_ARGUMENTS = DiagnosticFactory2.create(ERROR);
|
||||
DiagnosticFactory1<KtElement, ClassDescriptor> OUTER_CLASS_ARGUMENTS_REQUIRED = DiagnosticFactory1.create(ERROR);
|
||||
DiagnosticFactory1<KtElement, String> TYPE_ARGUMENTS_NOT_ALLOWED = DiagnosticFactory1.create(ERROR);
|
||||
|
||||
+2
@@ -696,6 +696,8 @@ public class DefaultErrorMessages {
|
||||
MAP.put(REDUNDANT_NULLABLE, "Redundant '?'");
|
||||
MAP.put(DEFINITELY_NOT_NULLABLE_NOT_APPLICABLE, "'!!' is only applicable to type parameters with nullable upper bounds");
|
||||
MAP.put(NULLABLE_ON_DEFINITELY_NOT_NULLABLE, "'!!' type cannot be marked as nullable");
|
||||
MAP.put(INCORRECT_LEFT_COMPONENT_OF_INTERSECTION, "Intersection types are only supported for definitely non-nullable types: left part should be a type parameter with nullable bounds");
|
||||
MAP.put(INCORRECT_RIGHT_COMPONENT_OF_INTERSECTION, "Intersection types are only supported for definitely non-nullable types: right part should be non-nullable Any");
|
||||
MAP.put(UNSAFE_CALL, "Only safe (?.) or non-null asserted (!!.) calls are allowed on a nullable receiver of type {0}", RENDER_TYPE);
|
||||
MAP.put(UNSAFE_IMPLICIT_INVOKE_CALL, "Reference has a nullable type ''{0}'', use explicit ''?.invoke()'' to make a function-like call instead", RENDER_TYPE);
|
||||
MAP.put(AMBIGUOUS_LABEL, "Ambiguous label");
|
||||
|
||||
@@ -55,9 +55,7 @@ import org.jetbrains.kotlin.resolve.source.getPsi
|
||||
import org.jetbrains.kotlin.resolve.source.toSourceElement
|
||||
import org.jetbrains.kotlin.types.*
|
||||
import org.jetbrains.kotlin.types.Variance.*
|
||||
import org.jetbrains.kotlin.types.typeUtil.containsTypeAliasParameters
|
||||
import org.jetbrains.kotlin.types.typeUtil.containsTypeAliases
|
||||
import org.jetbrains.kotlin.types.typeUtil.isArrayOfNothing
|
||||
import org.jetbrains.kotlin.types.typeUtil.*
|
||||
import org.jetbrains.kotlin.utils.addToStdlib.safeAs
|
||||
import kotlin.math.min
|
||||
|
||||
@@ -319,6 +317,57 @@ class TypeResolver(
|
||||
result = type(definitelyNotNullKotlinType)
|
||||
}
|
||||
|
||||
override fun visitIntersectionType(intersectionType: KtIntersectionType) {
|
||||
val leftType = resolvePossiblyBareType(c, intersectionType.getLeftTypeRef() ?: return).let {
|
||||
when {
|
||||
it.isBare -> error("There should not be bare types for intersections")
|
||||
else -> it.actualType
|
||||
}
|
||||
}
|
||||
|
||||
// Just in case of early return
|
||||
result = type(leftType)
|
||||
|
||||
val rightType = resolvePossiblyBareType(c, intersectionType.getRightTypeRef() ?: return).let {
|
||||
when {
|
||||
it.isBare -> error("There should not be bare types for intersections")
|
||||
else -> it.actualType
|
||||
}
|
||||
}
|
||||
|
||||
if (!languageVersionSettings.supportsFeature(LanguageFeature.DefinitelyNotNullTypeParameters)) {
|
||||
c.trace.report(
|
||||
UNSUPPORTED_FEATURE.on(
|
||||
intersectionType,
|
||||
LanguageFeature.DefinitelyNotNullTypeParameters to languageVersionSettings
|
||||
)
|
||||
)
|
||||
return
|
||||
}
|
||||
|
||||
if (!leftType.isTypeParameter() || leftType.isMarkedNullable || !TypeUtils.isNullableType(leftType)) {
|
||||
c.trace.report(INCORRECT_LEFT_COMPONENT_OF_INTERSECTION.on(intersectionType.getLeftTypeRef()!!))
|
||||
return
|
||||
}
|
||||
|
||||
if (!rightType.isAny()) {
|
||||
c.trace.report(INCORRECT_RIGHT_COMPONENT_OF_INTERSECTION.on(intersectionType.getRightTypeRef()!!))
|
||||
return
|
||||
}
|
||||
|
||||
val definitelyNotNullType =
|
||||
DefinitelyNotNullType.makeDefinitelyNotNull(leftType.unwrap())
|
||||
?: error(
|
||||
"Definitely not-nullable type is not created for type parameter with nullable upper bound ${
|
||||
TypeUtils.getTypeParameterDescriptorOrNull(
|
||||
leftType
|
||||
)!!
|
||||
}"
|
||||
)
|
||||
|
||||
result = type(definitelyNotNullType)
|
||||
}
|
||||
|
||||
override fun visitFunctionType(type: KtFunctionType) {
|
||||
val receiverTypeRef = type.receiverTypeReference
|
||||
val receiverType = if (receiverTypeRef == null) null else resolveType(c.noBareTypes(), receiverTypeRef)
|
||||
|
||||
Reference in New Issue
Block a user