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> {
|
val ARGUMENT_TYPE_MISMATCH by error<PsiElement> {
|
||||||
parameter<ConeKotlinType>("expectedType")
|
parameter<ConeKotlinType>("expectedType")
|
||||||
parameter<ConeKotlinType>("actualType")
|
parameter<ConeKotlinType>("actualType")
|
||||||
|
parameter<Boolean>("isMismatchDueToNullability")
|
||||||
}
|
}
|
||||||
|
|
||||||
val NULL_FOR_NONNULL_TYPE by error<PsiElement> { }
|
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 TYPE_MISMATCH by error2<PsiElement, ConeKotlinType, ConeKotlinType>()
|
||||||
val THROWABLE_TYPE_MISMATCH by error1<PsiElement, ConeKotlinType>()
|
val THROWABLE_TYPE_MISMATCH by error1<PsiElement, ConeKotlinType>()
|
||||||
val CONDITION_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 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)
|
||||||
val VARARG_OUTSIDE_PARENTHESES by error0<KtExpression>()
|
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.FIR
|
||||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirDiagnosticRenderers.FQ_NAMES_IN_TYPES
|
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.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.NULLABLE_STRING
|
||||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirDiagnosticRenderers.RENDER_CLASS_OR_OBJECT
|
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirDiagnosticRenderers.RENDER_CLASS_OR_OBJECT
|
||||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirDiagnosticRenderers.RENDER_TYPE
|
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(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(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(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(ASSIGNMENT_TYPE_MISMATCH, "Assignment type mismatch: actual type is {1} but {0} was expected", RENDER_TYPE, RENDER_TYPE)
|
||||||
map.put(
|
map.put(
|
||||||
RESULT_TYPE_MISMATCH,
|
RESULT_TYPE_MISMATCH,
|
||||||
|
|||||||
+2
-1
@@ -136,7 +136,8 @@ private fun mapInapplicableCandidateError(
|
|||||||
is ArgumentTypeMismatch -> FirErrors.ARGUMENT_TYPE_MISMATCH.on(
|
is ArgumentTypeMismatch -> FirErrors.ARGUMENT_TYPE_MISMATCH.on(
|
||||||
rootCause.argument.source ?: source,
|
rootCause.argument.source ?: source,
|
||||||
rootCause.expectedType,
|
rootCause.expectedType,
|
||||||
rootCause.actualType
|
rootCause.actualType,
|
||||||
|
rootCause.isMismatchDueToNullability
|
||||||
)
|
)
|
||||||
is NullForNotNullType -> FirErrors.NULL_FOR_NONNULL_TYPE.on(
|
is NullForNotNullType -> FirErrors.NULL_FOR_NONNULL_TYPE.on(
|
||||||
rootCause.argument.source ?: source
|
rootCause.argument.source ?: source
|
||||||
|
|||||||
@@ -375,10 +375,18 @@ private fun checkApplicabilityForArgumentType(
|
|||||||
return type
|
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(
|
return ArgumentTypeMismatch(
|
||||||
tryGetConeTypeThatCompatibleWithKtType(actualExpectedType),
|
tryGetConeTypeThatCompatibleWithKtType(actualExpectedType),
|
||||||
tryGetConeTypeThatCompatibleWithKtType(argumentType),
|
tryGetConeTypeThatCompatibleWithKtType(argumentType),
|
||||||
argument
|
argument,
|
||||||
|
isMismatchDueToNullability
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+2
-1
@@ -93,7 +93,8 @@ sealed class UnstableSmartCast(
|
|||||||
class ArgumentTypeMismatch(
|
class ArgumentTypeMismatch(
|
||||||
val expectedType: ConeKotlinType,
|
val expectedType: ConeKotlinType,
|
||||||
val actualType: ConeKotlinType,
|
val actualType: ConeKotlinType,
|
||||||
val argument: FirExpression
|
val argument: FirExpression,
|
||||||
|
val isMismatchDueToNullability: Boolean,
|
||||||
) : ResolutionDiagnostic(INAPPLICABLE)
|
) : ResolutionDiagnostic(INAPPLICABLE)
|
||||||
|
|
||||||
class NullForNotNullType(
|
class NullForNotNullType(
|
||||||
|
|||||||
+1
@@ -961,6 +961,7 @@ internal val KT_DIAGNOSTIC_CONVERTER = KtDiagnosticConverterBuilder.buildConvert
|
|||||||
ArgumentTypeMismatchImpl(
|
ArgumentTypeMismatchImpl(
|
||||||
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,
|
||||||
)
|
)
|
||||||
|
|||||||
+1
@@ -688,6 +688,7 @@ sealed class KtFirDiagnostic<PSI: PsiElement> : KtDiagnosticWithPsi<PSI> {
|
|||||||
override val diagnosticClass get() = ArgumentTypeMismatch::class
|
override val diagnosticClass get() = ArgumentTypeMismatch::class
|
||||||
abstract val expectedType: KtType
|
abstract val expectedType: KtType
|
||||||
abstract val actualType: KtType
|
abstract val actualType: KtType
|
||||||
|
abstract val isMismatchDueToNullability: Boolean
|
||||||
}
|
}
|
||||||
|
|
||||||
abstract class NullForNonnullType : KtFirDiagnostic<PsiElement>() {
|
abstract class NullForNonnullType : KtFirDiagnostic<PsiElement>() {
|
||||||
|
|||||||
+1
@@ -1105,6 +1105,7 @@ internal class ConditionTypeMismatchImpl(
|
|||||||
internal class ArgumentTypeMismatchImpl(
|
internal class ArgumentTypeMismatchImpl(
|
||||||
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.ArgumentTypeMismatch(), KtAbstractFirDiagnostic<PsiElement> {
|
) : KtFirDiagnostic.ArgumentTypeMismatch(), KtAbstractFirDiagnostic<PsiElement> {
|
||||||
|
|||||||
Reference in New Issue
Block a user