FIR: store in ARGUMENT_TYPE_MISMATCH whether it's due to nullability
This commit is contained in:
committed by
Ilya Kirillov
parent
cceb7197a5
commit
9106ae4f5f
+1
@@ -288,6 +288,7 @@ object DIAGNOSTICS_LIST : DiagnosticList() {
|
||||
val ARGUMENT_TYPE_MISMATCH by error<PsiElement> {
|
||||
parameter<ConeKotlinType>("expectedType")
|
||||
parameter<ConeKotlinType>("actualType")
|
||||
parameter<Boolean>("isMismatchDueToNullability")
|
||||
}
|
||||
|
||||
val NULL_FOR_NONNULL_TYPE by error<PsiElement> { }
|
||||
|
||||
+1
-1
@@ -235,7 +235,7 @@ object FirErrors {
|
||||
val TYPE_MISMATCH by error2<PsiElement, ConeKotlinType, ConeKotlinType>()
|
||||
val THROWABLE_TYPE_MISMATCH by error1<PsiElement, ConeKotlinType>()
|
||||
val CONDITION_TYPE_MISMATCH by error1<PsiElement, ConeKotlinType>()
|
||||
val ARGUMENT_TYPE_MISMATCH by error2<PsiElement, ConeKotlinType, ConeKotlinType>()
|
||||
val ARGUMENT_TYPE_MISMATCH by error3<PsiElement, ConeKotlinType, ConeKotlinType, Boolean>()
|
||||
val NULL_FOR_NONNULL_TYPE by error0<PsiElement>()
|
||||
val INAPPLICABLE_LATEINIT_MODIFIER by error1<KtModifierListOwner, String>(SourceElementPositioningStrategies.LATEINIT_MODIFIER)
|
||||
val VARARG_OUTSIDE_PARENTHESES by error0<KtExpression>()
|
||||
|
||||
+2
-1
@@ -13,6 +13,7 @@ import org.jetbrains.kotlin.fir.analysis.diagnostics.FirDiagnosticRenderers.DECL
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirDiagnosticRenderers.FIR
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirDiagnosticRenderers.FQ_NAMES_IN_TYPES
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirDiagnosticRenderers.NAME
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirDiagnosticRenderers.NOT_RENDERED
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirDiagnosticRenderers.NULLABLE_STRING
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirDiagnosticRenderers.RENDER_CLASS_OR_OBJECT
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirDiagnosticRenderers.RENDER_TYPE
|
||||
@@ -563,7 +564,7 @@ class FirDefaultErrorMessages : DefaultErrorMessages.Extension {
|
||||
map.put(TYPE_MISMATCH, "Type mismatch: inferred type is {1} but {0} was expected", TO_STRING, TO_STRING)
|
||||
map.put(THROWABLE_TYPE_MISMATCH, "Throwable type mismatch: actual type is {0}", TO_STRING)
|
||||
map.put(CONDITION_TYPE_MISMATCH, "Condition type mismatch: inferred type is {0} but Boolean was expected", TO_STRING)
|
||||
map.put(ARGUMENT_TYPE_MISMATCH, "Argument type mismatch: actual type is {1} but {0} was expected", RENDER_TYPE, RENDER_TYPE)
|
||||
map.put(ARGUMENT_TYPE_MISMATCH, "Argument type mismatch: actual type is {1} but {0} was expected", RENDER_TYPE, RENDER_TYPE, NOT_RENDERED)
|
||||
map.put(ASSIGNMENT_TYPE_MISMATCH, "Assignment type mismatch: actual type is {1} but {0} was expected", RENDER_TYPE, RENDER_TYPE)
|
||||
map.put(
|
||||
RESULT_TYPE_MISMATCH,
|
||||
|
||||
+2
-1
@@ -136,7 +136,8 @@ private fun mapInapplicableCandidateError(
|
||||
is ArgumentTypeMismatch -> FirErrors.ARGUMENT_TYPE_MISMATCH.on(
|
||||
rootCause.argument.source ?: source,
|
||||
rootCause.expectedType,
|
||||
rootCause.actualType
|
||||
rootCause.actualType,
|
||||
rootCause.isMismatchDueToNullability
|
||||
)
|
||||
is NullForNotNullType -> FirErrors.NULL_FOR_NONNULL_TYPE.on(
|
||||
rootCause.argument.source ?: source
|
||||
|
||||
@@ -375,10 +375,18 @@ private fun checkApplicabilityForArgumentType(
|
||||
return type
|
||||
}
|
||||
|
||||
// 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.
|
||||
val isMismatchDueToNullability = AbstractTypeChecker.isSubtypeOf(
|
||||
context.session.typeContext,
|
||||
argumentType,
|
||||
actualExpectedType.withNullability(ConeNullability.NULLABLE, context.session.typeContext)
|
||||
)
|
||||
return ArgumentTypeMismatch(
|
||||
tryGetConeTypeThatCompatibleWithKtType(actualExpectedType),
|
||||
tryGetConeTypeThatCompatibleWithKtType(argumentType),
|
||||
argument
|
||||
argument,
|
||||
isMismatchDueToNullability
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
+2
-1
@@ -93,7 +93,8 @@ sealed class UnstableSmartCast(
|
||||
class ArgumentTypeMismatch(
|
||||
val expectedType: ConeKotlinType,
|
||||
val actualType: ConeKotlinType,
|
||||
val argument: FirExpression
|
||||
val argument: FirExpression,
|
||||
val isMismatchDueToNullability: Boolean,
|
||||
) : ResolutionDiagnostic(INAPPLICABLE)
|
||||
|
||||
class NullForNotNullType(
|
||||
|
||||
+1
@@ -961,6 +961,7 @@ internal val KT_DIAGNOSTIC_CONVERTER = KtDiagnosticConverterBuilder.buildConvert
|
||||
ArgumentTypeMismatchImpl(
|
||||
firSymbolBuilder.typeBuilder.buildKtType(firDiagnostic.a),
|
||||
firSymbolBuilder.typeBuilder.buildKtType(firDiagnostic.b),
|
||||
firDiagnostic.c,
|
||||
firDiagnostic as FirPsiDiagnostic<*>,
|
||||
token,
|
||||
)
|
||||
|
||||
+1
@@ -688,6 +688,7 @@ sealed class KtFirDiagnostic<PSI: PsiElement> : KtDiagnosticWithPsi<PSI> {
|
||||
override val diagnosticClass get() = ArgumentTypeMismatch::class
|
||||
abstract val expectedType: KtType
|
||||
abstract val actualType: KtType
|
||||
abstract val isMismatchDueToNullability: Boolean
|
||||
}
|
||||
|
||||
abstract class NullForNonnullType : KtFirDiagnostic<PsiElement>() {
|
||||
|
||||
+1
@@ -1105,6 +1105,7 @@ internal class ConditionTypeMismatchImpl(
|
||||
internal class ArgumentTypeMismatchImpl(
|
||||
override val expectedType: KtType,
|
||||
override val actualType: KtType,
|
||||
override val isMismatchDueToNullability: Boolean,
|
||||
firDiagnostic: FirPsiDiagnostic<*>,
|
||||
override val token: ValidityToken,
|
||||
) : KtFirDiagnostic.ArgumentTypeMismatch(), KtAbstractFirDiagnostic<PsiElement> {
|
||||
|
||||
Reference in New Issue
Block a user