FIR checker: record whether type mismatch is due to nullability
This is useful for downstream quickfixes.
This commit is contained in:
committed by
teamcityserver
parent
d3e8cc577c
commit
951812f130
+1
-1
@@ -36,7 +36,7 @@ internal class KtFirBuiltInTypes(builtinTypes: BuiltinTypes, builder: KtSymbolBy
|
|||||||
override val NOTHING: KtType by cachedBuiltin(builtinTypes.nothingType)
|
override val NOTHING: KtType by cachedBuiltin(builtinTypes.nothingType)
|
||||||
override val ANY: KtType by cachedBuiltin(builtinTypes.anyType)
|
override val ANY: KtType by cachedBuiltin(builtinTypes.anyType)
|
||||||
|
|
||||||
|
override val THROWABLE: KtType by cachedBuiltin(builtinTypes.throwableType)
|
||||||
override val NULLABLE_ANY: KtType by cachedBuiltin(builtinTypes.nullableAnyType)
|
override val NULLABLE_ANY: KtType by cachedBuiltin(builtinTypes.nullableAnyType)
|
||||||
override val NULLABLE_NOTHING: KtType by cachedBuiltin(builtinTypes.nullableNothingType)
|
override val NULLABLE_NOTHING: KtType by cachedBuiltin(builtinTypes.nullableNothingType)
|
||||||
|
|
||||||
|
|||||||
+7
@@ -1255,6 +1255,7 @@ internal val KT_DIAGNOSTIC_CONVERTER = KtDiagnosticConverterBuilder.buildConvert
|
|||||||
TypeMismatchImpl(
|
TypeMismatchImpl(
|
||||||
firSymbolBuilder.typeBuilder.buildKtType(firDiagnostic.a),
|
firSymbolBuilder.typeBuilder.buildKtType(firDiagnostic.a),
|
||||||
firSymbolBuilder.typeBuilder.buildKtType(firDiagnostic.b),
|
firSymbolBuilder.typeBuilder.buildKtType(firDiagnostic.b),
|
||||||
|
firDiagnostic.c,
|
||||||
firDiagnostic as FirPsiDiagnostic,
|
firDiagnostic as FirPsiDiagnostic,
|
||||||
token,
|
token,
|
||||||
)
|
)
|
||||||
@@ -1262,6 +1263,7 @@ internal val KT_DIAGNOSTIC_CONVERTER = KtDiagnosticConverterBuilder.buildConvert
|
|||||||
add(FirErrors.THROWABLE_TYPE_MISMATCH) { firDiagnostic ->
|
add(FirErrors.THROWABLE_TYPE_MISMATCH) { firDiagnostic ->
|
||||||
ThrowableTypeMismatchImpl(
|
ThrowableTypeMismatchImpl(
|
||||||
firSymbolBuilder.typeBuilder.buildKtType(firDiagnostic.a),
|
firSymbolBuilder.typeBuilder.buildKtType(firDiagnostic.a),
|
||||||
|
firDiagnostic.b,
|
||||||
firDiagnostic as FirPsiDiagnostic,
|
firDiagnostic as FirPsiDiagnostic,
|
||||||
token,
|
token,
|
||||||
)
|
)
|
||||||
@@ -1269,6 +1271,7 @@ internal val KT_DIAGNOSTIC_CONVERTER = KtDiagnosticConverterBuilder.buildConvert
|
|||||||
add(FirErrors.CONDITION_TYPE_MISMATCH) { firDiagnostic ->
|
add(FirErrors.CONDITION_TYPE_MISMATCH) { firDiagnostic ->
|
||||||
ConditionTypeMismatchImpl(
|
ConditionTypeMismatchImpl(
|
||||||
firSymbolBuilder.typeBuilder.buildKtType(firDiagnostic.a),
|
firSymbolBuilder.typeBuilder.buildKtType(firDiagnostic.a),
|
||||||
|
firDiagnostic.b,
|
||||||
firDiagnostic as FirPsiDiagnostic,
|
firDiagnostic as FirPsiDiagnostic,
|
||||||
token,
|
token,
|
||||||
)
|
)
|
||||||
@@ -1345,6 +1348,7 @@ internal val KT_DIAGNOSTIC_CONVERTER = KtDiagnosticConverterBuilder.buildConvert
|
|||||||
AssignmentTypeMismatchImpl(
|
AssignmentTypeMismatchImpl(
|
||||||
firSymbolBuilder.typeBuilder.buildKtType(firDiagnostic.a),
|
firSymbolBuilder.typeBuilder.buildKtType(firDiagnostic.a),
|
||||||
firSymbolBuilder.typeBuilder.buildKtType(firDiagnostic.b),
|
firSymbolBuilder.typeBuilder.buildKtType(firDiagnostic.b),
|
||||||
|
firDiagnostic.c,
|
||||||
firDiagnostic as FirPsiDiagnostic,
|
firDiagnostic as FirPsiDiagnostic,
|
||||||
token,
|
token,
|
||||||
)
|
)
|
||||||
@@ -1711,6 +1715,7 @@ internal val KT_DIAGNOSTIC_CONVERTER = KtDiagnosticConverterBuilder.buildConvert
|
|||||||
firSymbolBuilder.typeBuilder.buildKtType(firDiagnostic.a),
|
firSymbolBuilder.typeBuilder.buildKtType(firDiagnostic.a),
|
||||||
firSymbolBuilder.typeBuilder.buildKtType(firDiagnostic.b),
|
firSymbolBuilder.typeBuilder.buildKtType(firDiagnostic.b),
|
||||||
firSymbolBuilder.buildSymbol(firDiagnostic.c),
|
firSymbolBuilder.buildSymbol(firDiagnostic.c),
|
||||||
|
firDiagnostic.d,
|
||||||
firDiagnostic as FirPsiDiagnostic,
|
firDiagnostic as FirPsiDiagnostic,
|
||||||
token,
|
token,
|
||||||
)
|
)
|
||||||
@@ -1780,6 +1785,7 @@ internal val KT_DIAGNOSTIC_CONVERTER = KtDiagnosticConverterBuilder.buildConvert
|
|||||||
firSymbolBuilder.typeBuilder.buildKtType(firDiagnostic.a),
|
firSymbolBuilder.typeBuilder.buildKtType(firDiagnostic.a),
|
||||||
firDiagnostic.b.source!!.psi as KtExpression,
|
firDiagnostic.b.source!!.psi as KtExpression,
|
||||||
firDiagnostic.c,
|
firDiagnostic.c,
|
||||||
|
firDiagnostic.d,
|
||||||
firDiagnostic as FirPsiDiagnostic,
|
firDiagnostic as FirPsiDiagnostic,
|
||||||
token,
|
token,
|
||||||
)
|
)
|
||||||
@@ -2416,6 +2422,7 @@ internal val KT_DIAGNOSTIC_CONVERTER = KtDiagnosticConverterBuilder.buildConvert
|
|||||||
InitializerTypeMismatchImpl(
|
InitializerTypeMismatchImpl(
|
||||||
firSymbolBuilder.typeBuilder.buildKtType(firDiagnostic.a),
|
firSymbolBuilder.typeBuilder.buildKtType(firDiagnostic.a),
|
||||||
firSymbolBuilder.typeBuilder.buildKtType(firDiagnostic.b),
|
firSymbolBuilder.typeBuilder.buildKtType(firDiagnostic.b),
|
||||||
|
firDiagnostic.c,
|
||||||
firDiagnostic as FirPsiDiagnostic,
|
firDiagnostic as FirPsiDiagnostic,
|
||||||
token,
|
token,
|
||||||
)
|
)
|
||||||
|
|||||||
+7
@@ -904,16 +904,19 @@ sealed class KtFirDiagnostic<PSI : PsiElement> : KtDiagnosticWithPsi<PSI> {
|
|||||||
override val diagnosticClass get() = TypeMismatch::class
|
override val diagnosticClass get() = TypeMismatch::class
|
||||||
abstract val expectedType: KtType
|
abstract val expectedType: KtType
|
||||||
abstract val actualType: KtType
|
abstract val actualType: KtType
|
||||||
|
abstract val isMismatchDueToNullability: Boolean
|
||||||
}
|
}
|
||||||
|
|
||||||
abstract class ThrowableTypeMismatch : KtFirDiagnostic<PsiElement>() {
|
abstract class ThrowableTypeMismatch : KtFirDiagnostic<PsiElement>() {
|
||||||
override val diagnosticClass get() = ThrowableTypeMismatch::class
|
override val diagnosticClass get() = ThrowableTypeMismatch::class
|
||||||
abstract val actualType: KtType
|
abstract val actualType: KtType
|
||||||
|
abstract val isMismatchDueToNullability: Boolean
|
||||||
}
|
}
|
||||||
|
|
||||||
abstract class ConditionTypeMismatch : KtFirDiagnostic<PsiElement>() {
|
abstract class ConditionTypeMismatch : KtFirDiagnostic<PsiElement>() {
|
||||||
override val diagnosticClass get() = ConditionTypeMismatch::class
|
override val diagnosticClass get() = ConditionTypeMismatch::class
|
||||||
abstract val actualType: KtType
|
abstract val actualType: KtType
|
||||||
|
abstract val isMismatchDueToNullability: Boolean
|
||||||
}
|
}
|
||||||
|
|
||||||
abstract class ArgumentTypeMismatch : KtFirDiagnostic<PsiElement>() {
|
abstract class ArgumentTypeMismatch : KtFirDiagnostic<PsiElement>() {
|
||||||
@@ -968,6 +971,7 @@ sealed class KtFirDiagnostic<PSI : PsiElement> : KtDiagnosticWithPsi<PSI> {
|
|||||||
override val diagnosticClass get() = AssignmentTypeMismatch::class
|
override val diagnosticClass get() = AssignmentTypeMismatch::class
|
||||||
abstract val expectedType: KtType
|
abstract val expectedType: KtType
|
||||||
abstract val actualType: KtType
|
abstract val actualType: KtType
|
||||||
|
abstract val isMismatchDueToNullability: Boolean
|
||||||
}
|
}
|
||||||
|
|
||||||
abstract class ResultTypeMismatch : KtFirDiagnostic<KtExpression>() {
|
abstract class ResultTypeMismatch : KtFirDiagnostic<KtExpression>() {
|
||||||
@@ -1216,6 +1220,7 @@ sealed class KtFirDiagnostic<PSI : PsiElement> : KtDiagnosticWithPsi<PSI> {
|
|||||||
abstract val expectedType: KtType
|
abstract val expectedType: KtType
|
||||||
abstract val actualType: KtType
|
abstract val actualType: KtType
|
||||||
abstract val targetFunction: KtSymbol
|
abstract val targetFunction: KtSymbol
|
||||||
|
abstract val isMismatchDueToNullability: Boolean
|
||||||
}
|
}
|
||||||
|
|
||||||
abstract class CyclicGenericUpperBound : KtFirDiagnostic<PsiElement>() {
|
abstract class CyclicGenericUpperBound : KtFirDiagnostic<PsiElement>() {
|
||||||
@@ -1267,6 +1272,7 @@ sealed class KtFirDiagnostic<PSI : PsiElement> : KtDiagnosticWithPsi<PSI> {
|
|||||||
abstract val desiredType: KtType
|
abstract val desiredType: KtType
|
||||||
abstract val subject: KtExpression
|
abstract val subject: KtExpression
|
||||||
abstract val description: String
|
abstract val description: String
|
||||||
|
abstract val isCastToNotNull: Boolean
|
||||||
}
|
}
|
||||||
|
|
||||||
abstract class ExtensionInClassReferenceNotAllowed : KtFirDiagnostic<KtExpression>() {
|
abstract class ExtensionInClassReferenceNotAllowed : KtFirDiagnostic<KtExpression>() {
|
||||||
@@ -1709,6 +1715,7 @@ sealed class KtFirDiagnostic<PSI : PsiElement> : KtDiagnosticWithPsi<PSI> {
|
|||||||
override val diagnosticClass get() = InitializerTypeMismatch::class
|
override val diagnosticClass get() = InitializerTypeMismatch::class
|
||||||
abstract val expectedType: KtType
|
abstract val expectedType: KtType
|
||||||
abstract val actualType: KtType
|
abstract val actualType: KtType
|
||||||
|
abstract val isMismatchDueToNullability: Boolean
|
||||||
}
|
}
|
||||||
|
|
||||||
abstract class GetterVisibilityDiffersFromPropertyVisibility : KtFirDiagnostic<KtModifierListOwner>() {
|
abstract class GetterVisibilityDiffersFromPropertyVisibility : KtFirDiagnostic<KtModifierListOwner>() {
|
||||||
|
|||||||
+7
@@ -1438,6 +1438,7 @@ internal class InapplicableCandidateImpl(
|
|||||||
internal class TypeMismatchImpl(
|
internal class TypeMismatchImpl(
|
||||||
override val expectedType: KtType,
|
override val expectedType: KtType,
|
||||||
override val actualType: KtType,
|
override val actualType: KtType,
|
||||||
|
override val isMismatchDueToNullability: Boolean,
|
||||||
firDiagnostic: FirPsiDiagnostic,
|
firDiagnostic: FirPsiDiagnostic,
|
||||||
override val token: ValidityToken,
|
override val token: ValidityToken,
|
||||||
) : KtFirDiagnostic.TypeMismatch(), KtAbstractFirDiagnostic<PsiElement> {
|
) : KtFirDiagnostic.TypeMismatch(), KtAbstractFirDiagnostic<PsiElement> {
|
||||||
@@ -1446,6 +1447,7 @@ internal class TypeMismatchImpl(
|
|||||||
|
|
||||||
internal class ThrowableTypeMismatchImpl(
|
internal class ThrowableTypeMismatchImpl(
|
||||||
override val actualType: KtType,
|
override val actualType: KtType,
|
||||||
|
override val isMismatchDueToNullability: Boolean,
|
||||||
firDiagnostic: FirPsiDiagnostic,
|
firDiagnostic: FirPsiDiagnostic,
|
||||||
override val token: ValidityToken,
|
override val token: ValidityToken,
|
||||||
) : KtFirDiagnostic.ThrowableTypeMismatch(), KtAbstractFirDiagnostic<PsiElement> {
|
) : KtFirDiagnostic.ThrowableTypeMismatch(), KtAbstractFirDiagnostic<PsiElement> {
|
||||||
@@ -1454,6 +1456,7 @@ internal class ThrowableTypeMismatchImpl(
|
|||||||
|
|
||||||
internal class ConditionTypeMismatchImpl(
|
internal class ConditionTypeMismatchImpl(
|
||||||
override val actualType: KtType,
|
override val actualType: KtType,
|
||||||
|
override val isMismatchDueToNullability: Boolean,
|
||||||
firDiagnostic: FirPsiDiagnostic,
|
firDiagnostic: FirPsiDiagnostic,
|
||||||
override val token: ValidityToken,
|
override val token: ValidityToken,
|
||||||
) : KtFirDiagnostic.ConditionTypeMismatch(), KtAbstractFirDiagnostic<PsiElement> {
|
) : KtFirDiagnostic.ConditionTypeMismatch(), KtAbstractFirDiagnostic<PsiElement> {
|
||||||
@@ -1541,6 +1544,7 @@ internal class NamedParameterNotFoundImpl(
|
|||||||
internal class AssignmentTypeMismatchImpl(
|
internal class AssignmentTypeMismatchImpl(
|
||||||
override val expectedType: KtType,
|
override val expectedType: KtType,
|
||||||
override val actualType: KtType,
|
override val actualType: KtType,
|
||||||
|
override val isMismatchDueToNullability: Boolean,
|
||||||
firDiagnostic: FirPsiDiagnostic,
|
firDiagnostic: FirPsiDiagnostic,
|
||||||
override val token: ValidityToken,
|
override val token: ValidityToken,
|
||||||
) : KtFirDiagnostic.AssignmentTypeMismatch(), KtAbstractFirDiagnostic<KtExpression> {
|
) : KtFirDiagnostic.AssignmentTypeMismatch(), KtAbstractFirDiagnostic<KtExpression> {
|
||||||
@@ -1951,6 +1955,7 @@ internal class ReturnTypeMismatchImpl(
|
|||||||
override val expectedType: KtType,
|
override val expectedType: KtType,
|
||||||
override val actualType: KtType,
|
override val actualType: KtType,
|
||||||
override val targetFunction: KtSymbol,
|
override val targetFunction: KtSymbol,
|
||||||
|
override val isMismatchDueToNullability: Boolean,
|
||||||
firDiagnostic: FirPsiDiagnostic,
|
firDiagnostic: FirPsiDiagnostic,
|
||||||
override val token: ValidityToken,
|
override val token: ValidityToken,
|
||||||
) : KtFirDiagnostic.ReturnTypeMismatch(), KtAbstractFirDiagnostic<KtExpression> {
|
) : KtFirDiagnostic.ReturnTypeMismatch(), KtAbstractFirDiagnostic<KtExpression> {
|
||||||
@@ -2029,6 +2034,7 @@ internal class SmartcastImpossibleImpl(
|
|||||||
override val desiredType: KtType,
|
override val desiredType: KtType,
|
||||||
override val subject: KtExpression,
|
override val subject: KtExpression,
|
||||||
override val description: String,
|
override val description: String,
|
||||||
|
override val isCastToNotNull: Boolean,
|
||||||
firDiagnostic: FirPsiDiagnostic,
|
firDiagnostic: FirPsiDiagnostic,
|
||||||
override val token: ValidityToken,
|
override val token: ValidityToken,
|
||||||
) : KtFirDiagnostic.SmartcastImpossible(), KtAbstractFirDiagnostic<KtExpression> {
|
) : KtFirDiagnostic.SmartcastImpossible(), KtAbstractFirDiagnostic<KtExpression> {
|
||||||
@@ -2747,6 +2753,7 @@ internal class WrongSetterParameterTypeImpl(
|
|||||||
internal class InitializerTypeMismatchImpl(
|
internal class InitializerTypeMismatchImpl(
|
||||||
override val expectedType: KtType,
|
override val expectedType: KtType,
|
||||||
override val actualType: KtType,
|
override val actualType: KtType,
|
||||||
|
override val isMismatchDueToNullability: Boolean,
|
||||||
firDiagnostic: FirPsiDiagnostic,
|
firDiagnostic: FirPsiDiagnostic,
|
||||||
override val token: ValidityToken,
|
override val token: ValidityToken,
|
||||||
) : KtFirDiagnostic.InitializerTypeMismatch(), KtAbstractFirDiagnostic<KtProperty> {
|
) : KtFirDiagnostic.InitializerTypeMismatch(), KtAbstractFirDiagnostic<KtProperty> {
|
||||||
|
|||||||
+2
@@ -96,6 +96,8 @@ public abstract class KtBuiltinTypes : ValidityTokenOwner {
|
|||||||
public abstract val NOTHING: KtType
|
public abstract val NOTHING: KtType
|
||||||
public abstract val ANY: KtType
|
public abstract val ANY: KtType
|
||||||
|
|
||||||
|
public abstract val THROWABLE: KtType
|
||||||
|
|
||||||
public abstract val NULLABLE_ANY: KtType
|
public abstract val NULLABLE_ANY: KtType
|
||||||
public abstract val NULLABLE_NOTHING: KtType
|
public abstract val NULLABLE_NOTHING: KtType
|
||||||
}
|
}
|
||||||
|
|||||||
+7
@@ -401,14 +401,17 @@ object DIAGNOSTICS_LIST : DiagnosticList("FirErrors") {
|
|||||||
val TYPE_MISMATCH by error<PsiElement> {
|
val TYPE_MISMATCH by error<PsiElement> {
|
||||||
parameter<ConeKotlinType>("expectedType")
|
parameter<ConeKotlinType>("expectedType")
|
||||||
parameter<ConeKotlinType>("actualType")
|
parameter<ConeKotlinType>("actualType")
|
||||||
|
parameter<Boolean>("isMismatchDueToNullability")
|
||||||
}
|
}
|
||||||
|
|
||||||
val THROWABLE_TYPE_MISMATCH by error<PsiElement> {
|
val THROWABLE_TYPE_MISMATCH by error<PsiElement> {
|
||||||
parameter<ConeKotlinType>("actualType")
|
parameter<ConeKotlinType>("actualType")
|
||||||
|
parameter<Boolean>("isMismatchDueToNullability")
|
||||||
}
|
}
|
||||||
|
|
||||||
val CONDITION_TYPE_MISMATCH by error<PsiElement> {
|
val CONDITION_TYPE_MISMATCH by error<PsiElement> {
|
||||||
parameter<ConeKotlinType>("actualType")
|
parameter<ConeKotlinType>("actualType")
|
||||||
|
parameter<Boolean>("isMismatchDueToNullability")
|
||||||
}
|
}
|
||||||
|
|
||||||
val ARGUMENT_TYPE_MISMATCH by error<PsiElement> {
|
val ARGUMENT_TYPE_MISMATCH by error<PsiElement> {
|
||||||
@@ -446,6 +449,7 @@ object DIAGNOSTICS_LIST : DiagnosticList("FirErrors") {
|
|||||||
val ASSIGNMENT_TYPE_MISMATCH by error<KtExpression> {
|
val ASSIGNMENT_TYPE_MISMATCH by error<KtExpression> {
|
||||||
parameter<ConeKotlinType>("expectedType")
|
parameter<ConeKotlinType>("expectedType")
|
||||||
parameter<ConeKotlinType>("actualType")
|
parameter<ConeKotlinType>("actualType")
|
||||||
|
parameter<Boolean>("isMismatchDueToNullability")
|
||||||
}
|
}
|
||||||
|
|
||||||
val RESULT_TYPE_MISMATCH by error<KtExpression> {
|
val RESULT_TYPE_MISMATCH by error<KtExpression> {
|
||||||
@@ -579,6 +583,7 @@ object DIAGNOSTICS_LIST : DiagnosticList("FirErrors") {
|
|||||||
parameter<ConeKotlinType>("expectedType")
|
parameter<ConeKotlinType>("expectedType")
|
||||||
parameter<ConeKotlinType>("actualType")
|
parameter<ConeKotlinType>("actualType")
|
||||||
parameter<FirSimpleFunction>("targetFunction")
|
parameter<FirSimpleFunction>("targetFunction")
|
||||||
|
parameter<Boolean>("isMismatchDueToNullability")
|
||||||
}
|
}
|
||||||
|
|
||||||
val CYCLIC_GENERIC_UPPER_BOUND by error<PsiElement>()
|
val CYCLIC_GENERIC_UPPER_BOUND by error<PsiElement>()
|
||||||
@@ -617,6 +622,7 @@ object DIAGNOSTICS_LIST : DiagnosticList("FirErrors") {
|
|||||||
parameter<ConeKotlinType>("desiredType")
|
parameter<ConeKotlinType>("desiredType")
|
||||||
parameter<FirExpression>("subject")
|
parameter<FirExpression>("subject")
|
||||||
parameter<String>("description")
|
parameter<String>("description")
|
||||||
|
parameter<Boolean>("isCastToNotNull")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -874,6 +880,7 @@ object DIAGNOSTICS_LIST : DiagnosticList("FirErrors") {
|
|||||||
val INITIALIZER_TYPE_MISMATCH by error<KtProperty>(PositioningStrategy.PROPERTY_INITIALIZER) {
|
val INITIALIZER_TYPE_MISMATCH by error<KtProperty>(PositioningStrategy.PROPERTY_INITIALIZER) {
|
||||||
parameter<ConeKotlinType>("expectedType")
|
parameter<ConeKotlinType>("expectedType")
|
||||||
parameter<ConeKotlinType>("actualType")
|
parameter<ConeKotlinType>("actualType")
|
||||||
|
parameter<Boolean>("isMismatchDueToNullability")
|
||||||
}
|
}
|
||||||
val GETTER_VISIBILITY_DIFFERS_FROM_PROPERTY_VISIBILITY by error<KtModifierListOwner>(PositioningStrategy.VISIBILITY_MODIFIER)
|
val GETTER_VISIBILITY_DIFFERS_FROM_PROPERTY_VISIBILITY by error<KtModifierListOwner>(PositioningStrategy.VISIBILITY_MODIFIER)
|
||||||
val SETTER_VISIBILITY_INCONSISTENT_WITH_PROPERTY_VISIBILITY by error<KtModifierListOwner>(PositioningStrategy.VISIBILITY_MODIFIER)
|
val SETTER_VISIBILITY_INCONSISTENT_WITH_PROPERTY_VISIBILITY by error<KtModifierListOwner>(PositioningStrategy.VISIBILITY_MODIFIER)
|
||||||
|
|||||||
+7
-7
@@ -300,9 +300,9 @@ object FirErrors {
|
|||||||
// Applicability
|
// Applicability
|
||||||
val NONE_APPLICABLE by error1<PsiElement, Collection<FirBasedSymbol<*>>>(SourceElementPositioningStrategies.REFERENCE_BY_QUALIFIED)
|
val NONE_APPLICABLE by error1<PsiElement, Collection<FirBasedSymbol<*>>>(SourceElementPositioningStrategies.REFERENCE_BY_QUALIFIED)
|
||||||
val INAPPLICABLE_CANDIDATE by error1<PsiElement, FirBasedSymbol<*>>(SourceElementPositioningStrategies.REFERENCE_BY_QUALIFIED)
|
val INAPPLICABLE_CANDIDATE by error1<PsiElement, FirBasedSymbol<*>>(SourceElementPositioningStrategies.REFERENCE_BY_QUALIFIED)
|
||||||
val TYPE_MISMATCH by error2<PsiElement, ConeKotlinType, ConeKotlinType>()
|
val TYPE_MISMATCH by error3<PsiElement, ConeKotlinType, ConeKotlinType, Boolean>()
|
||||||
val THROWABLE_TYPE_MISMATCH by error1<PsiElement, ConeKotlinType>()
|
val THROWABLE_TYPE_MISMATCH by error2<PsiElement, ConeKotlinType, Boolean>()
|
||||||
val CONDITION_TYPE_MISMATCH by error1<PsiElement, ConeKotlinType>()
|
val CONDITION_TYPE_MISMATCH by error2<PsiElement, ConeKotlinType, Boolean>()
|
||||||
val ARGUMENT_TYPE_MISMATCH by error3<PsiElement, ConeKotlinType, ConeKotlinType, Boolean>()
|
val ARGUMENT_TYPE_MISMATCH by error3<PsiElement, ConeKotlinType, ConeKotlinType, Boolean>()
|
||||||
val NULL_FOR_NONNULL_TYPE by error0<PsiElement>()
|
val NULL_FOR_NONNULL_TYPE by error0<PsiElement>()
|
||||||
val INAPPLICABLE_LATEINIT_MODIFIER by error1<KtModifierListOwner, String>(SourceElementPositioningStrategies.LATEINIT_MODIFIER)
|
val INAPPLICABLE_LATEINIT_MODIFIER by error1<KtModifierListOwner, String>(SourceElementPositioningStrategies.LATEINIT_MODIFIER)
|
||||||
@@ -313,7 +313,7 @@ object FirErrors {
|
|||||||
val TOO_MANY_ARGUMENTS by error1<PsiElement, FirCallableSymbol<*>>()
|
val TOO_MANY_ARGUMENTS by error1<PsiElement, FirCallableSymbol<*>>()
|
||||||
val NO_VALUE_FOR_PARAMETER by error1<KtElement, FirValueParameterSymbol>(SourceElementPositioningStrategies.VALUE_ARGUMENTS)
|
val NO_VALUE_FOR_PARAMETER by error1<KtElement, FirValueParameterSymbol>(SourceElementPositioningStrategies.VALUE_ARGUMENTS)
|
||||||
val NAMED_PARAMETER_NOT_FOUND by error1<KtValueArgument, String>(SourceElementPositioningStrategies.NAME_OF_NAMED_ARGUMENT)
|
val NAMED_PARAMETER_NOT_FOUND by error1<KtValueArgument, String>(SourceElementPositioningStrategies.NAME_OF_NAMED_ARGUMENT)
|
||||||
val ASSIGNMENT_TYPE_MISMATCH by error2<KtExpression, ConeKotlinType, ConeKotlinType>()
|
val ASSIGNMENT_TYPE_MISMATCH by error3<KtExpression, ConeKotlinType, ConeKotlinType, Boolean>()
|
||||||
val RESULT_TYPE_MISMATCH by error2<KtExpression, ConeKotlinType, ConeKotlinType>()
|
val RESULT_TYPE_MISMATCH by error2<KtExpression, ConeKotlinType, ConeKotlinType>()
|
||||||
val MANY_LAMBDA_EXPRESSION_ARGUMENTS by error0<KtValueArgument>()
|
val MANY_LAMBDA_EXPRESSION_ARGUMENTS by error0<KtValueArgument>()
|
||||||
val NEW_INFERENCE_NO_INFORMATION_FOR_PARAMETER by error1<KtElement, String>()
|
val NEW_INFERENCE_NO_INFORMATION_FOR_PARAMETER by error1<KtElement, String>()
|
||||||
@@ -368,7 +368,7 @@ object FirErrors {
|
|||||||
val REIFIED_TYPE_PARAMETER_NO_INLINE by error0<KtTypeParameter>(SourceElementPositioningStrategies.REIFIED_MODIFIER)
|
val REIFIED_TYPE_PARAMETER_NO_INLINE by error0<KtTypeParameter>(SourceElementPositioningStrategies.REIFIED_MODIFIER)
|
||||||
val TYPE_PARAMETERS_NOT_ALLOWED by error0<KtDeclaration>(SourceElementPositioningStrategies.TYPE_PARAMETERS_LIST)
|
val TYPE_PARAMETERS_NOT_ALLOWED by error0<KtDeclaration>(SourceElementPositioningStrategies.TYPE_PARAMETERS_LIST)
|
||||||
val TYPE_PARAMETER_OF_PROPERTY_NOT_USED_IN_RECEIVER by error0<KtTypeParameter>()
|
val TYPE_PARAMETER_OF_PROPERTY_NOT_USED_IN_RECEIVER by error0<KtTypeParameter>()
|
||||||
val RETURN_TYPE_MISMATCH by error3<KtExpression, ConeKotlinType, ConeKotlinType, FirSimpleFunction>(SourceElementPositioningStrategies.WHOLE_ELEMENT)
|
val RETURN_TYPE_MISMATCH by error4<KtExpression, ConeKotlinType, ConeKotlinType, FirSimpleFunction, Boolean>(SourceElementPositioningStrategies.WHOLE_ELEMENT)
|
||||||
val CYCLIC_GENERIC_UPPER_BOUND by error0<PsiElement>()
|
val CYCLIC_GENERIC_UPPER_BOUND by error0<PsiElement>()
|
||||||
val DEPRECATED_TYPE_PARAMETER_SYNTAX by error0<KtDeclaration>(SourceElementPositioningStrategies.TYPE_PARAMETERS_LIST)
|
val DEPRECATED_TYPE_PARAMETER_SYNTAX by error0<KtDeclaration>(SourceElementPositioningStrategies.TYPE_PARAMETERS_LIST)
|
||||||
val MISPLACED_TYPE_PARAMETER_CONSTRAINTS by warning0<KtTypeParameter>()
|
val MISPLACED_TYPE_PARAMETER_CONSTRAINTS by warning0<KtTypeParameter>()
|
||||||
@@ -377,7 +377,7 @@ object FirErrors {
|
|||||||
val INCOMPATIBLE_TYPES_WARNING by warning2<KtElement, ConeKotlinType, ConeKotlinType>()
|
val INCOMPATIBLE_TYPES_WARNING by warning2<KtElement, ConeKotlinType, ConeKotlinType>()
|
||||||
val TYPE_VARIANCE_CONFLICT by error4<PsiElement, FirTypeParameterSymbol, Variance, Variance, ConeKotlinType>(SourceElementPositioningStrategies.DECLARATION_SIGNATURE_OR_DEFAULT)
|
val TYPE_VARIANCE_CONFLICT by error4<PsiElement, FirTypeParameterSymbol, Variance, Variance, ConeKotlinType>(SourceElementPositioningStrategies.DECLARATION_SIGNATURE_OR_DEFAULT)
|
||||||
val TYPE_VARIANCE_CONFLICT_IN_EXPANDED_TYPE by error4<PsiElement, FirTypeParameterSymbol, Variance, Variance, ConeKotlinType>(SourceElementPositioningStrategies.DECLARATION_SIGNATURE_OR_DEFAULT)
|
val TYPE_VARIANCE_CONFLICT_IN_EXPANDED_TYPE by error4<PsiElement, FirTypeParameterSymbol, Variance, Variance, ConeKotlinType>(SourceElementPositioningStrategies.DECLARATION_SIGNATURE_OR_DEFAULT)
|
||||||
val SMARTCAST_IMPOSSIBLE by error3<KtExpression, ConeKotlinType, FirExpression, String>()
|
val SMARTCAST_IMPOSSIBLE by error4<KtExpression, ConeKotlinType, FirExpression, String, Boolean>()
|
||||||
|
|
||||||
// Reflection
|
// Reflection
|
||||||
val EXTENSION_IN_CLASS_REFERENCE_NOT_ALLOWED by error1<KtExpression, FirCallableSymbol<*>>(SourceElementPositioningStrategies.REFERENCE_BY_QUALIFIED)
|
val EXTENSION_IN_CLASS_REFERENCE_NOT_ALLOWED by error1<KtExpression, FirCallableSymbol<*>>(SourceElementPositioningStrategies.REFERENCE_BY_QUALIFIED)
|
||||||
@@ -482,7 +482,7 @@ object FirErrors {
|
|||||||
val CONST_VAL_WITHOUT_INITIALIZER by error0<KtProperty>(SourceElementPositioningStrategies.CONST_MODIFIER)
|
val CONST_VAL_WITHOUT_INITIALIZER by error0<KtProperty>(SourceElementPositioningStrategies.CONST_MODIFIER)
|
||||||
val CONST_VAL_WITH_NON_CONST_INITIALIZER by error0<KtExpression>()
|
val CONST_VAL_WITH_NON_CONST_INITIALIZER by error0<KtExpression>()
|
||||||
val WRONG_SETTER_PARAMETER_TYPE by error2<KtTypeReference, ConeKotlinType, ConeKotlinType>()
|
val WRONG_SETTER_PARAMETER_TYPE by error2<KtTypeReference, ConeKotlinType, ConeKotlinType>()
|
||||||
val INITIALIZER_TYPE_MISMATCH by error2<KtProperty, ConeKotlinType, ConeKotlinType>(SourceElementPositioningStrategies.PROPERTY_INITIALIZER)
|
val INITIALIZER_TYPE_MISMATCH by error3<KtProperty, ConeKotlinType, ConeKotlinType, Boolean>(SourceElementPositioningStrategies.PROPERTY_INITIALIZER)
|
||||||
val GETTER_VISIBILITY_DIFFERS_FROM_PROPERTY_VISIBILITY by error0<KtModifierListOwner>(SourceElementPositioningStrategies.VISIBILITY_MODIFIER)
|
val GETTER_VISIBILITY_DIFFERS_FROM_PROPERTY_VISIBILITY by error0<KtModifierListOwner>(SourceElementPositioningStrategies.VISIBILITY_MODIFIER)
|
||||||
val SETTER_VISIBILITY_INCONSISTENT_WITH_PROPERTY_VISIBILITY by error0<KtModifierListOwner>(SourceElementPositioningStrategies.VISIBILITY_MODIFIER)
|
val SETTER_VISIBILITY_INCONSISTENT_WITH_PROPERTY_VISIBILITY by error0<KtModifierListOwner>(SourceElementPositioningStrategies.VISIBILITY_MODIFIER)
|
||||||
val WRONG_SETTER_RETURN_TYPE by error0<KtTypeReference>()
|
val WRONG_SETTER_RETURN_TYPE by error0<KtTypeReference>()
|
||||||
|
|||||||
@@ -576,7 +576,14 @@ fun checkTypeMismatch(
|
|||||||
reporter.reportOn(rValue.source, FirErrors.NULL_FOR_NONNULL_TYPE, context)
|
reporter.reportOn(rValue.source, FirErrors.NULL_FOR_NONNULL_TYPE, context)
|
||||||
}
|
}
|
||||||
isInitializer -> {
|
isInitializer -> {
|
||||||
reporter.reportOn(source, FirErrors.INITIALIZER_TYPE_MISMATCH, lValueType, rValueType, context)
|
reporter.reportOn(
|
||||||
|
source,
|
||||||
|
FirErrors.INITIALIZER_TYPE_MISMATCH,
|
||||||
|
lValueType,
|
||||||
|
rValueType,
|
||||||
|
context.session.typeContext.isTypeMismatchDueToNullability(rValueType, lValueType),
|
||||||
|
context
|
||||||
|
)
|
||||||
}
|
}
|
||||||
source.kind is FirFakeSourceElementKind.DesugaredIncrementOrDecrement -> {
|
source.kind is FirFakeSourceElementKind.DesugaredIncrementOrDecrement -> {
|
||||||
if (!lValueType.isNullable && rValueType.isNullable) {
|
if (!lValueType.isNullable && rValueType.isNullable) {
|
||||||
@@ -591,7 +598,14 @@ fun checkTypeMismatch(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
else -> {
|
else -> {
|
||||||
reporter.reportOn(source, FirErrors.ASSIGNMENT_TYPE_MISMATCH, lValueType, rValueType, context)
|
reporter.reportOn(
|
||||||
|
source,
|
||||||
|
FirErrors.ASSIGNMENT_TYPE_MISMATCH,
|
||||||
|
lValueType,
|
||||||
|
rValueType,
|
||||||
|
context.session.typeContext.isTypeMismatchDueToNullability(rValueType, lValueType),
|
||||||
|
context
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -603,7 +617,13 @@ internal fun checkCondition(condition: FirExpression, context: CheckerContext, r
|
|||||||
coneType !is ConeKotlinErrorType &&
|
coneType !is ConeKotlinErrorType &&
|
||||||
!coneType.isSubtypeOf(context.session.typeContext, context.session.builtinTypes.booleanType.type)
|
!coneType.isSubtypeOf(context.session.typeContext, context.session.builtinTypes.booleanType.type)
|
||||||
) {
|
) {
|
||||||
reporter.reportOn(condition.source, FirErrors.CONDITION_TYPE_MISMATCH, coneType, context)
|
reporter.reportOn(
|
||||||
|
condition.source,
|
||||||
|
FirErrors.CONDITION_TYPE_MISMATCH,
|
||||||
|
coneType,
|
||||||
|
coneType.isNullableBoolean,
|
||||||
|
context
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+12
-1
@@ -12,6 +12,8 @@ import org.jetbrains.kotlin.fir.analysis.diagnostics.DiagnosticReporter
|
|||||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors
|
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors
|
||||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.reportOn
|
import org.jetbrains.kotlin.fir.analysis.diagnostics.reportOn
|
||||||
import org.jetbrains.kotlin.fir.expressions.FirTryExpression
|
import org.jetbrains.kotlin.fir.expressions.FirTryExpression
|
||||||
|
import org.jetbrains.kotlin.fir.resolve.inference.inferenceComponents
|
||||||
|
import org.jetbrains.kotlin.fir.resolve.isTypeMismatchDueToNullability
|
||||||
import org.jetbrains.kotlin.fir.types.ConeTypeParameterType
|
import org.jetbrains.kotlin.fir.types.ConeTypeParameterType
|
||||||
import org.jetbrains.kotlin.fir.types.coneType
|
import org.jetbrains.kotlin.fir.types.coneType
|
||||||
|
|
||||||
@@ -42,7 +44,16 @@ object FirCatchParameterChecker : FirTryExpressionChecker() {
|
|||||||
|
|
||||||
val session = context.session
|
val session = context.session
|
||||||
if (!coneType.isSubtypeOfThrowable(session)) {
|
if (!coneType.isSubtypeOfThrowable(session)) {
|
||||||
reporter.reportOn(source, FirErrors.THROWABLE_TYPE_MISMATCH, coneType, context)
|
reporter.reportOn(
|
||||||
|
source,
|
||||||
|
FirErrors.THROWABLE_TYPE_MISMATCH,
|
||||||
|
coneType,
|
||||||
|
context.session.inferenceComponents.ctx.isTypeMismatchDueToNullability(
|
||||||
|
coneType,
|
||||||
|
session.builtinTypes.throwableType.type
|
||||||
|
),
|
||||||
|
context
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+6
-2
@@ -17,9 +17,9 @@ import org.jetbrains.kotlin.fir.expressions.FirExpressionWithSmartcast
|
|||||||
import org.jetbrains.kotlin.fir.expressions.FirReturnExpression
|
import org.jetbrains.kotlin.fir.expressions.FirReturnExpression
|
||||||
import org.jetbrains.kotlin.fir.expressions.FirWhenExpression
|
import org.jetbrains.kotlin.fir.expressions.FirWhenExpression
|
||||||
import org.jetbrains.kotlin.fir.expressions.isExhaustive
|
import org.jetbrains.kotlin.fir.expressions.isExhaustive
|
||||||
|
import org.jetbrains.kotlin.fir.resolve.isTypeMismatchDueToNullability
|
||||||
import org.jetbrains.kotlin.fir.typeContext
|
import org.jetbrains.kotlin.fir.typeContext
|
||||||
import org.jetbrains.kotlin.fir.types.*
|
import org.jetbrains.kotlin.fir.types.*
|
||||||
import org.jetbrains.kotlin.types.SmartcastStability
|
|
||||||
|
|
||||||
object FirFunctionReturnTypeMismatchChecker : FirReturnExpressionChecker() {
|
object FirFunctionReturnTypeMismatchChecker : FirReturnExpressionChecker() {
|
||||||
override fun check(expression: FirReturnExpression, context: CheckerContext, reporter: DiagnosticReporter) {
|
override fun check(expression: FirReturnExpression, context: CheckerContext, reporter: DiagnosticReporter) {
|
||||||
@@ -38,7 +38,9 @@ object FirFunctionReturnTypeMismatchChecker : FirReturnExpressionChecker() {
|
|||||||
if (resultExpression.isNullLiteral && functionReturnType.nullability == ConeNullability.NOT_NULL) {
|
if (resultExpression.isNullLiteral && functionReturnType.nullability == ConeNullability.NOT_NULL) {
|
||||||
reporter.reportOn(resultExpression.source, NULL_FOR_NONNULL_TYPE, context)
|
reporter.reportOn(resultExpression.source, NULL_FOR_NONNULL_TYPE, context)
|
||||||
} else {
|
} else {
|
||||||
if (resultExpression is FirExpressionWithSmartcast && resultExpression.smartcastStability != SmartcastStability.STABLE_VALUE &&
|
val isDueToNullability =
|
||||||
|
context.session.typeContext.isTypeMismatchDueToNullability(returnExpressionType, functionReturnType)
|
||||||
|
if (resultExpression is FirExpressionWithSmartcast && !resultExpression.isStable &&
|
||||||
isSubtypeForTypeMismatch(typeContext, subtype = resultExpression.smartcastType.coneType, supertype = functionReturnType)
|
isSubtypeForTypeMismatch(typeContext, subtype = resultExpression.smartcastType.coneType, supertype = functionReturnType)
|
||||||
) {
|
) {
|
||||||
reporter.reportOn(
|
reporter.reportOn(
|
||||||
@@ -47,6 +49,7 @@ object FirFunctionReturnTypeMismatchChecker : FirReturnExpressionChecker() {
|
|||||||
functionReturnType,
|
functionReturnType,
|
||||||
resultExpression,
|
resultExpression,
|
||||||
resultExpression.smartcastStability.description,
|
resultExpression.smartcastStability.description,
|
||||||
|
isDueToNullability,
|
||||||
context
|
context
|
||||||
)
|
)
|
||||||
} else {
|
} else {
|
||||||
@@ -56,6 +59,7 @@ object FirFunctionReturnTypeMismatchChecker : FirReturnExpressionChecker() {
|
|||||||
functionReturnType,
|
functionReturnType,
|
||||||
returnExpressionType,
|
returnExpressionType,
|
||||||
targetElement,
|
targetElement,
|
||||||
|
isDueToNullability,
|
||||||
context
|
context
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
+9
-8
@@ -812,9 +812,9 @@ class FirDefaultErrorMessages {
|
|||||||
map.put(REDUNDANT_SPREAD_OPERATOR_IN_NAMED_FORM_IN_ANNOTATION, "Redundant spread (*) operator");
|
map.put(REDUNDANT_SPREAD_OPERATOR_IN_NAMED_FORM_IN_ANNOTATION, "Redundant spread (*) operator");
|
||||||
map.put(REDUNDANT_SPREAD_OPERATOR_IN_NAMED_FORM_IN_FUNCTION, "Redundant spread (*) operator");
|
map.put(REDUNDANT_SPREAD_OPERATOR_IN_NAMED_FORM_IN_FUNCTION, "Redundant spread (*) operator");
|
||||||
|
|
||||||
map.put(TYPE_MISMATCH, "Type mismatch: inferred type is {1} but {0} was expected", TO_STRING, TO_STRING)
|
map.put(TYPE_MISMATCH, "Type mismatch: inferred type is {1} but {0} was expected", TO_STRING, TO_STRING, NOT_RENDERED)
|
||||||
map.put(THROWABLE_TYPE_MISMATCH, "Throwable type mismatch: actual type is {0}", TO_STRING)
|
map.put(THROWABLE_TYPE_MISMATCH, "Throwable type mismatch: actual type is {0}", TO_STRING, NOT_RENDERED)
|
||||||
map.put(CONDITION_TYPE_MISMATCH, "Condition type mismatch: inferred type is {0} but Boolean was expected", TO_STRING)
|
map.put(CONDITION_TYPE_MISMATCH, "Condition type mismatch: inferred type is {0} but Boolean was expected", TO_STRING, NOT_RENDERED)
|
||||||
map.put(
|
map.put(
|
||||||
ARGUMENT_TYPE_MISMATCH,
|
ARGUMENT_TYPE_MISMATCH,
|
||||||
"Argument type mismatch: actual type is {1} but {0} was expected",
|
"Argument type mismatch: actual type is {1} but {0} was expected",
|
||||||
@@ -822,12 +822,12 @@ class FirDefaultErrorMessages {
|
|||||||
RENDER_TYPE,
|
RENDER_TYPE,
|
||||||
NOT_RENDERED
|
NOT_RENDERED
|
||||||
)
|
)
|
||||||
map.put(ASSIGNMENT_TYPE_MISMATCH, "Assignment type mismatch: actual type is {1} but {0} was expected", RENDER_TYPE, RENDER_TYPE)
|
map.put(ASSIGNMENT_TYPE_MISMATCH, "Assignment type mismatch: actual type is {1} but {0} was expected", RENDER_TYPE, RENDER_TYPE, NOT_RENDERED)
|
||||||
map.put(
|
map.put(
|
||||||
RESULT_TYPE_MISMATCH,
|
RESULT_TYPE_MISMATCH,
|
||||||
"Function return type mismatch: actual type is {1} but {0} was expected",
|
"Function return type mismatch: actual type is {1} but {0} was expected",
|
||||||
RENDER_TYPE,
|
RENDER_TYPE,
|
||||||
RENDER_TYPE
|
RENDER_TYPE,
|
||||||
)
|
)
|
||||||
|
|
||||||
// Ambiguity
|
// Ambiguity
|
||||||
@@ -921,7 +921,8 @@ class FirDefaultErrorMessages {
|
|||||||
"Smart cast to ''{0}'' is impossible, because ''{1}'' is a {2}",
|
"Smart cast to ''{0}'' is impossible, because ''{1}'' is a {2}",
|
||||||
RENDER_TYPE,
|
RENDER_TYPE,
|
||||||
FIR,
|
FIR,
|
||||||
TO_STRING
|
TO_STRING,
|
||||||
|
NOT_RENDERED
|
||||||
)
|
)
|
||||||
|
|
||||||
map.put(
|
map.put(
|
||||||
@@ -966,7 +967,7 @@ class FirDefaultErrorMessages {
|
|||||||
|
|
||||||
map.put(NO_RETURN_IN_FUNCTION_WITH_BLOCK_BODY, "A 'return' expression required in a function with a block body ('{...}')")
|
map.put(NO_RETURN_IN_FUNCTION_WITH_BLOCK_BODY, "A 'return' expression required in a function with a block body ('{...}')")
|
||||||
|
|
||||||
map.put(RETURN_TYPE_MISMATCH, "Return type mismatch: expected {0}, actual {1}", RENDER_TYPE, RENDER_TYPE, NOT_RENDERED)
|
map.put(RETURN_TYPE_MISMATCH, "Return type mismatch: expected {0}, actual {1}", RENDER_TYPE, RENDER_TYPE, NOT_RENDERED, NOT_RENDERED)
|
||||||
|
|
||||||
map.put(CYCLIC_GENERIC_UPPER_BOUND, "Type parameter has cyclic upper bounds")
|
map.put(CYCLIC_GENERIC_UPPER_BOUND, "Type parameter has cyclic upper bounds")
|
||||||
|
|
||||||
@@ -1279,7 +1280,7 @@ class FirDefaultErrorMessages {
|
|||||||
RENDER_TYPE,
|
RENDER_TYPE,
|
||||||
RENDER_TYPE
|
RENDER_TYPE
|
||||||
)
|
)
|
||||||
map.put(INITIALIZER_TYPE_MISMATCH, "Initializer type mismatch: expected {0}, actual {1}", RENDER_TYPE, RENDER_TYPE)
|
map.put(INITIALIZER_TYPE_MISMATCH, "Initializer type mismatch: expected {0}, actual {1}", RENDER_TYPE, RENDER_TYPE, NOT_RENDERED)
|
||||||
map.put(GETTER_VISIBILITY_DIFFERS_FROM_PROPERTY_VISIBILITY, "Getter visibility must be the same as property visibility")
|
map.put(GETTER_VISIBILITY_DIFFERS_FROM_PROPERTY_VISIBILITY, "Getter visibility must be the same as property visibility")
|
||||||
map.put(
|
map.put(
|
||||||
SETTER_VISIBILITY_INCONSISTENT_WITH_PROPERTY_VISIBILITY,
|
SETTER_VISIBILITY_INCONSISTENT_WITH_PROPERTY_VISIBILITY,
|
||||||
|
|||||||
+24
-4
@@ -20,6 +20,7 @@ import org.jetbrains.kotlin.fir.resolve.inference.ConeTypeVariableForLambdaRetur
|
|||||||
import org.jetbrains.kotlin.fir.resolve.inference.model.ConeArgumentConstraintPosition
|
import org.jetbrains.kotlin.fir.resolve.inference.model.ConeArgumentConstraintPosition
|
||||||
import org.jetbrains.kotlin.fir.resolve.inference.model.ConeExpectedTypeConstraintPosition
|
import org.jetbrains.kotlin.fir.resolve.inference.model.ConeExpectedTypeConstraintPosition
|
||||||
import org.jetbrains.kotlin.fir.resolve.inference.model.ConeLambdaArgumentConstraintPosition
|
import org.jetbrains.kotlin.fir.resolve.inference.model.ConeLambdaArgumentConstraintPosition
|
||||||
|
import org.jetbrains.kotlin.fir.resolve.isTypeMismatchDueToNullability
|
||||||
import org.jetbrains.kotlin.fir.symbols.impl.FirBackingFieldSymbol
|
import org.jetbrains.kotlin.fir.symbols.impl.FirBackingFieldSymbol
|
||||||
import org.jetbrains.kotlin.fir.symbols.impl.FirNamedFunctionSymbol
|
import org.jetbrains.kotlin.fir.symbols.impl.FirNamedFunctionSymbol
|
||||||
import org.jetbrains.kotlin.fir.typeContext
|
import org.jetbrains.kotlin.fir.typeContext
|
||||||
@@ -60,7 +61,8 @@ private fun ConeDiagnostic.toFirDiagnostic(
|
|||||||
unstableSmartcast.argument.source,
|
unstableSmartcast.argument.source,
|
||||||
unstableSmartcast.targetType,
|
unstableSmartcast.targetType,
|
||||||
unstableSmartcast.argument,
|
unstableSmartcast.argument,
|
||||||
unstableSmartcast.argument.smartcastStability.description
|
unstableSmartcast.argument.smartcastStability.description,
|
||||||
|
unstableSmartcast.isCastToNotNull
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
else -> FirErrors.NONE_APPLICABLE.createOn(source, this.candidates.map { it.symbol })
|
else -> FirErrors.NONE_APPLICABLE.createOn(source, this.candidates.map { it.symbol })
|
||||||
@@ -203,7 +205,8 @@ private fun mapInapplicableCandidateError(
|
|||||||
rootCause.argument.source,
|
rootCause.argument.source,
|
||||||
rootCause.targetType,
|
rootCause.targetType,
|
||||||
rootCause.argument,
|
rootCause.argument,
|
||||||
rootCause.argument.smartcastStability.description
|
rootCause.argument.smartcastStability.description,
|
||||||
|
rootCause.isCastToNotNull
|
||||||
)
|
)
|
||||||
else -> genericDiagnostic
|
else -> genericDiagnostic
|
||||||
}
|
}
|
||||||
@@ -278,12 +281,13 @@ private fun ConstraintSystemError.toDiagnostic(
|
|||||||
else -> null
|
else -> null
|
||||||
}
|
}
|
||||||
|
|
||||||
|
val typeMismatchDueToNullability = typeContext.isTypeMismatchDueToNullability(lowerConeType, upperConeType)
|
||||||
argument?.let {
|
argument?.let {
|
||||||
return FirErrors.ARGUMENT_TYPE_MISMATCH.createOn(
|
return FirErrors.ARGUMENT_TYPE_MISMATCH.createOn(
|
||||||
it.source ?: source,
|
it.source ?: source,
|
||||||
lowerConeType,
|
lowerConeType,
|
||||||
upperConeType,
|
upperConeType,
|
||||||
isArgumentTypeMismatchDueToNullability(lowerConeType, upperConeType, typeContext)
|
typeMismatchDueToNullability
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -299,7 +303,12 @@ private fun ConstraintSystemError.toDiagnostic(
|
|||||||
else
|
else
|
||||||
upperConeType.withNullability(ConeNullability.NULLABLE, typeContext)
|
upperConeType.withNullability(ConeNullability.NULLABLE, typeContext)
|
||||||
|
|
||||||
FirErrors.TYPE_MISMATCH.createOn(qualifiedAccessSource ?: source, upperConeType, inferredType)
|
FirErrors.TYPE_MISMATCH.createOn(
|
||||||
|
qualifiedAccessSource ?: source,
|
||||||
|
upperConeType,
|
||||||
|
inferredType,
|
||||||
|
typeMismatchDueToNullability
|
||||||
|
)
|
||||||
}
|
}
|
||||||
is ExplicitTypeParameterConstraintPosition<*>,
|
is ExplicitTypeParameterConstraintPosition<*>,
|
||||||
is DelegatedPropertyConstraintPosition<*> -> {
|
is DelegatedPropertyConstraintPosition<*> -> {
|
||||||
@@ -418,3 +427,14 @@ private fun <A, B, C> FirDiagnosticFactory3<A, B, C>.createOn(
|
|||||||
): FirDiagnosticWithParameters3<A, B, C>? {
|
): FirDiagnosticWithParameters3<A, B, C>? {
|
||||||
return element?.let { on(it, a, b, c, positioningStrategy = null) }
|
return element?.let { on(it, a, b, c, positioningStrategy = null) }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@OptIn(InternalDiagnosticFactoryMethod::class)
|
||||||
|
private fun <A, B, C, D> FirDiagnosticFactory4<A, B, C, D>.createOn(
|
||||||
|
element: FirSourceElement?,
|
||||||
|
a: A,
|
||||||
|
b: B,
|
||||||
|
c: C,
|
||||||
|
d: D
|
||||||
|
): FirDiagnosticWithParameters4<A, B, C, D>? {
|
||||||
|
return element?.let { on(it, a, b, c, d, positioningStrategy = null) }
|
||||||
|
}
|
||||||
|
|||||||
@@ -63,6 +63,7 @@ val ConeKotlinType.isNothing: Boolean get() = isBuiltinType(StandardClassIds.Not
|
|||||||
val ConeKotlinType.isNullableNothing: Boolean get() = isBuiltinType(StandardClassIds.Nothing, true)
|
val ConeKotlinType.isNullableNothing: Boolean get() = isBuiltinType(StandardClassIds.Nothing, true)
|
||||||
val ConeKotlinType.isUnit: Boolean get() = isBuiltinType(StandardClassIds.Unit, false)
|
val ConeKotlinType.isUnit: Boolean get() = isBuiltinType(StandardClassIds.Unit, false)
|
||||||
val ConeKotlinType.isBoolean: Boolean get() = isBuiltinType(StandardClassIds.Boolean, false)
|
val ConeKotlinType.isBoolean: Boolean get() = isBuiltinType(StandardClassIds.Boolean, false)
|
||||||
|
val ConeKotlinType.isNullableBoolean: Boolean get() = isBuiltinType(StandardClassIds.Boolean, true)
|
||||||
val ConeKotlinType.isBooleanOrNullableBoolean: Boolean get() = isAnyOfBuiltinType(setOf(StandardClassIds.Boolean))
|
val ConeKotlinType.isBooleanOrNullableBoolean: Boolean get() = isAnyOfBuiltinType(setOf(StandardClassIds.Boolean))
|
||||||
val ConeKotlinType.isEnum: Boolean get() = isBuiltinType(StandardClassIds.Enum, false)
|
val ConeKotlinType.isEnum: Boolean get() = isBuiltinType(StandardClassIds.Enum, false)
|
||||||
val ConeKotlinType.isString: Boolean get() = isBuiltinType(StandardClassIds.String, false)
|
val ConeKotlinType.isString: Boolean get() = isBuiltinType(StandardClassIds.String, false)
|
||||||
|
|||||||
@@ -46,6 +46,7 @@ import org.jetbrains.kotlin.fir.types.builder.buildResolvedTypeRef
|
|||||||
import org.jetbrains.kotlin.fir.types.impl.ConeClassLikeTypeImpl
|
import org.jetbrains.kotlin.fir.types.impl.ConeClassLikeTypeImpl
|
||||||
import org.jetbrains.kotlin.name.*
|
import org.jetbrains.kotlin.name.*
|
||||||
import org.jetbrains.kotlin.resolve.ForbiddenNamedArgumentsTarget
|
import org.jetbrains.kotlin.resolve.ForbiddenNamedArgumentsTarget
|
||||||
|
import org.jetbrains.kotlin.types.AbstractTypeChecker
|
||||||
import org.jetbrains.kotlin.types.SmartcastStability
|
import org.jetbrains.kotlin.types.SmartcastStability
|
||||||
import org.jetbrains.kotlin.utils.addToStdlib.safeAs
|
import org.jetbrains.kotlin.utils.addToStdlib.safeAs
|
||||||
|
|
||||||
@@ -549,3 +550,15 @@ fun FirClassLikeDeclaration.getContainingDeclaration(session: FirSession): FirCl
|
|||||||
|
|
||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun ConeTypeContext.isTypeMismatchDueToNullability(
|
||||||
|
actualType: ConeKotlinType,
|
||||||
|
expectedType: ConeKotlinType
|
||||||
|
): Boolean {
|
||||||
|
return actualType.isNullableType() && !expectedType.isNullableType() && AbstractTypeChecker.isSubtypeOf(
|
||||||
|
this,
|
||||||
|
actualType,
|
||||||
|
expectedType.withNullability(ConeNullability.NULLABLE, this)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -16,6 +16,7 @@ import org.jetbrains.kotlin.fir.resolve.ScopeSession
|
|||||||
import org.jetbrains.kotlin.fir.resolve.createFunctionalType
|
import org.jetbrains.kotlin.fir.resolve.createFunctionalType
|
||||||
import org.jetbrains.kotlin.fir.resolve.fullyExpandedType
|
import org.jetbrains.kotlin.fir.resolve.fullyExpandedType
|
||||||
import org.jetbrains.kotlin.fir.resolve.inference.*
|
import org.jetbrains.kotlin.fir.resolve.inference.*
|
||||||
|
import org.jetbrains.kotlin.fir.resolve.isTypeMismatchDueToNullability
|
||||||
import org.jetbrains.kotlin.fir.resolve.transformers.body.resolve.resultType
|
import org.jetbrains.kotlin.fir.resolve.transformers.body.resolve.resultType
|
||||||
import org.jetbrains.kotlin.fir.resolve.transformers.ensureResolvedTypeDeclaration
|
import org.jetbrains.kotlin.fir.resolve.transformers.ensureResolvedTypeDeclaration
|
||||||
import org.jetbrains.kotlin.fir.returnExpressions
|
import org.jetbrains.kotlin.fir.returnExpressions
|
||||||
@@ -340,18 +341,6 @@ private fun Candidate.captureTypeFromExpressionOrNull(argumentType: ConeKotlinTy
|
|||||||
) as? ConeKotlinType
|
) as? ConeKotlinType
|
||||||
}
|
}
|
||||||
|
|
||||||
fun isArgumentTypeMismatchDueToNullability(
|
|
||||||
argumentType: ConeKotlinType,
|
|
||||||
actualExpectedType: ConeKotlinType,
|
|
||||||
typeContext: ConeTypeContext
|
|
||||||
): Boolean {
|
|
||||||
return AbstractTypeChecker.isSubtypeOf(
|
|
||||||
typeContext,
|
|
||||||
argumentType,
|
|
||||||
actualExpectedType.withNullability(ConeNullability.NULLABLE, typeContext)
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun checkApplicabilityForArgumentType(
|
private fun checkApplicabilityForArgumentType(
|
||||||
csBuilder: ConstraintSystemBuilder,
|
csBuilder: ConstraintSystemBuilder,
|
||||||
argument: FirExpression,
|
argument: FirExpression,
|
||||||
@@ -394,7 +383,7 @@ private fun checkApplicabilityForArgumentType(
|
|||||||
argument,
|
argument,
|
||||||
// Reaching here means argument types mismatch, and we want to record whether it's due to the nullability by checking a subtype
|
// Reaching here means argument types mismatch, and we want to record whether it's due to the nullability by checking a subtype
|
||||||
// relation with nullable expected type.
|
// relation with nullable expected type.
|
||||||
isArgumentTypeMismatchDueToNullability(argumentType, actualExpectedType, context.session.typeContext)
|
context.session.typeContext.isTypeMismatchDueToNullability(argumentType, actualExpectedType)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -410,7 +399,16 @@ private fun checkApplicabilityForArgumentType(
|
|||||||
if (smartcastExpression != null && !smartcastExpression.isStable) {
|
if (smartcastExpression != null && !smartcastExpression.isStable) {
|
||||||
val unstableType = smartcastExpression.smartcastType.coneType
|
val unstableType = smartcastExpression.smartcastType.coneType
|
||||||
if (csBuilder.addSubtypeConstraintIfCompatible(unstableType, expectedType, position)) {
|
if (csBuilder.addSubtypeConstraintIfCompatible(unstableType, expectedType, position)) {
|
||||||
sink.reportDiagnostic(UnstableSmartCast(smartcastExpression, expectedType))
|
sink.reportDiagnostic(
|
||||||
|
UnstableSmartCast(
|
||||||
|
smartcastExpression,
|
||||||
|
expectedType,
|
||||||
|
context.session.typeContext.isTypeMismatchDueToNullability(
|
||||||
|
argumentType,
|
||||||
|
expectedType
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-1
@@ -78,7 +78,7 @@ object LowerPriorityToPreserveCompatibilityDiagnostic : ResolutionDiagnostic(RES
|
|||||||
|
|
||||||
object CandidateChosenUsingOverloadResolutionByLambdaAnnotation : ResolutionDiagnostic(RESOLVED)
|
object CandidateChosenUsingOverloadResolutionByLambdaAnnotation : ResolutionDiagnostic(RESOLVED)
|
||||||
|
|
||||||
class UnstableSmartCast(val argument: FirExpressionWithSmartcast, val targetType: ConeKotlinType) : ResolutionDiagnostic(UNSTABLE_SMARTCAST)
|
class UnstableSmartCast(val argument: FirExpressionWithSmartcast, val targetType: ConeKotlinType, val isCastToNotNull: Boolean) : ResolutionDiagnostic(UNSTABLE_SMARTCAST)
|
||||||
|
|
||||||
class ArgumentTypeMismatch(
|
class ArgumentTypeMismatch(
|
||||||
val expectedType: ConeKotlinType,
|
val expectedType: ConeKotlinType,
|
||||||
|
|||||||
+11
-1
@@ -15,6 +15,7 @@ import org.jetbrains.kotlin.fir.declarations.utils.modality
|
|||||||
import org.jetbrains.kotlin.fir.expressions.*
|
import org.jetbrains.kotlin.fir.expressions.*
|
||||||
import org.jetbrains.kotlin.fir.references.FirSuperReference
|
import org.jetbrains.kotlin.fir.references.FirSuperReference
|
||||||
import org.jetbrains.kotlin.fir.resolve.inference.*
|
import org.jetbrains.kotlin.fir.resolve.inference.*
|
||||||
|
import org.jetbrains.kotlin.fir.resolve.isTypeMismatchDueToNullability
|
||||||
import org.jetbrains.kotlin.fir.resolve.toSymbol
|
import org.jetbrains.kotlin.fir.resolve.toSymbol
|
||||||
import org.jetbrains.kotlin.fir.scopes.FirUnstableSmartcastTypeScope
|
import org.jetbrains.kotlin.fir.scopes.FirUnstableSmartcastTypeScope
|
||||||
import org.jetbrains.kotlin.fir.symbols.SyntheticSymbol
|
import org.jetbrains.kotlin.fir.symbols.SyntheticSymbol
|
||||||
@@ -121,7 +122,16 @@ object CheckDispatchReceiver : ResolutionStage() {
|
|||||||
!explicitReceiverExpression.isStable &&
|
!explicitReceiverExpression.isStable &&
|
||||||
(isCandidateFromUnstableSmartcast || (isReceiverNullable && !explicitReceiverExpression.smartcastType.canBeNull))
|
(isCandidateFromUnstableSmartcast || (isReceiverNullable && !explicitReceiverExpression.smartcastType.canBeNull))
|
||||||
) {
|
) {
|
||||||
sink.yieldDiagnostic(UnstableSmartCast(explicitReceiverExpression, explicitReceiverExpression.smartcastType.coneType))
|
sink.yieldDiagnostic(
|
||||||
|
UnstableSmartCast(
|
||||||
|
explicitReceiverExpression,
|
||||||
|
explicitReceiverExpression.smartcastType.coneType,
|
||||||
|
context.session.typeContext.isTypeMismatchDueToNullability(
|
||||||
|
explicitReceiverExpression.originalType.coneType,
|
||||||
|
explicitReceiverExpression.smartcastType.coneType
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
} else if (isReceiverNullable) {
|
} else if (isReceiverNullable) {
|
||||||
sink.yieldDiagnostic(UnsafeCall(dispatchReceiverValueType))
|
sink.yieldDiagnostic(UnsafeCall(dispatchReceiverValueType))
|
||||||
}
|
}
|
||||||
|
|||||||
+6
-2
@@ -9,9 +9,13 @@ import org.jetbrains.kotlin.fir.FirSession
|
|||||||
import org.jetbrains.kotlin.fir.declarations.FirAnonymousFunction
|
import org.jetbrains.kotlin.fir.declarations.FirAnonymousFunction
|
||||||
import org.jetbrains.kotlin.fir.expressions.FirAnonymousFunctionExpression
|
import org.jetbrains.kotlin.fir.expressions.FirAnonymousFunctionExpression
|
||||||
import org.jetbrains.kotlin.fir.expressions.FirCallableReferenceAccess
|
import org.jetbrains.kotlin.fir.expressions.FirCallableReferenceAccess
|
||||||
import org.jetbrains.kotlin.fir.resolve.calls.*
|
import org.jetbrains.kotlin.fir.resolve.calls.ArgumentTypeMismatch
|
||||||
|
import org.jetbrains.kotlin.fir.resolve.calls.Candidate
|
||||||
|
import org.jetbrains.kotlin.fir.resolve.calls.CheckerSink
|
||||||
|
import org.jetbrains.kotlin.fir.resolve.calls.ResolutionContext
|
||||||
import org.jetbrains.kotlin.fir.resolve.createFunctionalType
|
import org.jetbrains.kotlin.fir.resolve.createFunctionalType
|
||||||
import org.jetbrains.kotlin.fir.resolve.inference.model.ConeArgumentConstraintPosition
|
import org.jetbrains.kotlin.fir.resolve.inference.model.ConeArgumentConstraintPosition
|
||||||
|
import org.jetbrains.kotlin.fir.resolve.isTypeMismatchDueToNullability
|
||||||
import org.jetbrains.kotlin.fir.typeContext
|
import org.jetbrains.kotlin.fir.typeContext
|
||||||
import org.jetbrains.kotlin.fir.types.*
|
import org.jetbrains.kotlin.fir.types.*
|
||||||
import org.jetbrains.kotlin.resolve.calls.inference.ConstraintSystemBuilder
|
import org.jetbrains.kotlin.resolve.calls.inference.ConstraintSystemBuilder
|
||||||
@@ -63,7 +67,7 @@ fun Candidate.preprocessLambdaArgument(
|
|||||||
lambdaType,
|
lambdaType,
|
||||||
expectedType,
|
expectedType,
|
||||||
argument,
|
argument,
|
||||||
isArgumentTypeMismatchDueToNullability(lambdaType, expectedType, context.session.typeContext)
|
context.session.typeContext.isTypeMismatchDueToNullability(lambdaType, expectedType)
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user