FIR: introduce separate THROWABLE_TYPE_MISMATCH
This commit is contained in:
@@ -9,15 +9,15 @@ fun <T : Throwable> test() {
|
||||
|
||||
try {} catch (<!TYPE_PARAMETER_IN_CATCH_CLAUSE!>e: T<!>) {}
|
||||
|
||||
try {} catch (<!TYPE_MISMATCH!>e: () -> Int<!>) {}
|
||||
try {} catch (<!THROWABLE_TYPE_MISMATCH!>e: () -> Int<!>) {}
|
||||
|
||||
try {} catch (<!TYPE_MISMATCH!>e: StringType<!>) {}
|
||||
try {} catch (<!THROWABLE_TYPE_MISMATCH!>e: StringType<!>) {}
|
||||
|
||||
try {} catch (<!CATCH_PARAMETER_WITH_DEFAULT_VALUE, TYPE_MISMATCH!>e: Int = 5<!>) {}
|
||||
try {} catch (<!CATCH_PARAMETER_WITH_DEFAULT_VALUE, THROWABLE_TYPE_MISMATCH!>e: Int = 5<!>) {}
|
||||
|
||||
try {} catch (e: Throwable) {}
|
||||
}
|
||||
|
||||
inline fun <reified T> anotherTest() {
|
||||
try {} catch (<!REIFIED_TYPE_IN_CATCH_CLAUSE, TYPE_MISMATCH!>e: T<!>) {}
|
||||
try {} catch (<!REIFIED_TYPE_IN_CATCH_CLAUSE, THROWABLE_TYPE_MISMATCH!>e: T<!>) {}
|
||||
}
|
||||
|
||||
+13
-4
@@ -242,6 +242,19 @@ object DIAGNOSTICS_LIST : DiagnosticList() {
|
||||
parameter<Symbol>("candidate")
|
||||
}
|
||||
|
||||
val TYPE_MISMATCH by error<PsiElement> {
|
||||
parameter<ConeKotlinType>("expectedType")
|
||||
parameter<ConeKotlinType>("actualType")
|
||||
}
|
||||
|
||||
val THROWABLE_TYPE_MISMATCH by error<PsiElement> {
|
||||
parameter<ConeKotlinType>("actualType")
|
||||
}
|
||||
|
||||
val CONDITION_TYPE_MISMATCH by error<PsiElement> {
|
||||
parameter<ConeKotlinType>("actualType")
|
||||
}
|
||||
|
||||
val ARGUMENT_TYPE_MISMATCH by error<PsiElement> {
|
||||
parameter<ConeKotlinType>("expectedType")
|
||||
parameter<ConeKotlinType>("actualType")
|
||||
@@ -304,10 +317,6 @@ object DIAGNOSTICS_LIST : DiagnosticList() {
|
||||
}
|
||||
|
||||
val TYPES_AND_TYPE_PARAMETERS by object : DiagnosticGroup("Types & type parameters") {
|
||||
val TYPE_MISMATCH by error<PsiElement> {
|
||||
parameter<ConeKotlinType>("expectedType")
|
||||
parameter<ConeKotlinType>("actualType")
|
||||
}
|
||||
val RECURSION_IN_IMPLICIT_TYPES by error<PsiElement>()
|
||||
val INFERENCE_ERROR by error<PsiElement>()
|
||||
val PROJECTION_ON_NON_CLASS_TYPE_ARGUMENT by error<PsiElement>()
|
||||
|
||||
+3
-1
@@ -216,6 +216,9 @@ object FirErrors {
|
||||
// Applicability
|
||||
val NONE_APPLICABLE by error1<PsiElement, Collection<AbstractFirBasedSymbol<*>>>(SourceElementPositioningStrategies.REFERENCE_BY_QUALIFIED)
|
||||
val INAPPLICABLE_CANDIDATE by error1<PsiElement, AbstractFirBasedSymbol<*>>(SourceElementPositioningStrategies.REFERENCE_BY_QUALIFIED)
|
||||
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 NULL_FOR_NONNULL_TYPE by error0<PsiElement>()
|
||||
val INAPPLICABLE_LATEINIT_MODIFIER by error1<KtModifierListOwner, String>(SourceElementPositioningStrategies.LATEINIT_MODIFIER)
|
||||
@@ -238,7 +241,6 @@ object FirErrors {
|
||||
val NEXT_AMBIGUITY by error1<PsiElement, Collection<AbstractFirBasedSymbol<*>>>(SourceElementPositioningStrategies.REFERENCE_BY_QUALIFIED)
|
||||
|
||||
// Types & type parameters
|
||||
val TYPE_MISMATCH by error2<PsiElement, ConeKotlinType, ConeKotlinType>()
|
||||
val RECURSION_IN_IMPLICIT_TYPES by error0<PsiElement>()
|
||||
val INFERENCE_ERROR by error0<PsiElement>()
|
||||
val PROJECTION_ON_NON_CLASS_TYPE_ARGUMENT by error0<PsiElement>()
|
||||
|
||||
@@ -292,10 +292,8 @@ fun FirClass<*>.findNonInterfaceSupertype(context: CheckerContext): FirTypeRef?
|
||||
val FirFunctionCall.isIterator
|
||||
get() = this.calleeReference.name.asString() == "<iterator>"
|
||||
|
||||
internal fun throwableClassLikeType(session: FirSession) = session.builtinTypes.throwableType.type
|
||||
|
||||
fun ConeKotlinType.isSubtypeOfThrowable(session: FirSession) =
|
||||
throwableClassLikeType(session).isSupertypeOf(session.typeContext, this.fullyExpandedType(session))
|
||||
session.builtinTypes.throwableType.type.isSupertypeOf(session.typeContext, this.fullyExpandedType(session))
|
||||
|
||||
val FirValueParameter.hasValOrVar: Boolean
|
||||
get() {
|
||||
|
||||
+1
-2
@@ -7,7 +7,6 @@ package org.jetbrains.kotlin.fir.analysis.checkers.expression
|
||||
|
||||
import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext
|
||||
import org.jetbrains.kotlin.fir.analysis.checkers.isSubtypeOfThrowable
|
||||
import org.jetbrains.kotlin.fir.analysis.checkers.throwableClassLikeType
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.DiagnosticReporter
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.reportOn
|
||||
@@ -37,7 +36,7 @@ object FirCatchParameterChecker : FirTryExpressionChecker() {
|
||||
|
||||
val session = context.session
|
||||
if (!coneType.isSubtypeOfThrowable(session)) {
|
||||
reporter.reportOn(catchParameter.source, FirErrors.TYPE_MISMATCH, throwableClassLikeType(session), coneType, context)
|
||||
reporter.reportOn(catchParameter.source, FirErrors.THROWABLE_TYPE_MISMATCH, coneType, context)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+5
-1
@@ -63,6 +63,7 @@ import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.COMPONENT_FUNCTIO
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.COMPONENT_FUNCTION_MISSING
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.COMPONENT_FUNCTION_ON_NULLABLE
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.COMPONENT_FUNCTION_RETURN_TYPE_MISMATCH
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.CONDITION_TYPE_MISMATCH
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.CONFLICTING_OVERLOADS
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.CONFLICTING_PROJECTION
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.CONFLICTING_UPPER_BOUNDS
|
||||
@@ -272,6 +273,7 @@ import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.SUPER_CALL_FROM_P
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.SUPER_IS_NOT_AN_EXPRESSION
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.SUPER_NOT_AVAILABLE
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.SYNTAX
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.THROWABLE_TYPE_MISMATCH
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.TOO_MANY_ARGUMENTS
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.TOPLEVEL_TYPEALIASES_ONLY
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.TYPE_ARGUMENTS_NOT_ALLOWED
|
||||
@@ -524,6 +526,9 @@ class FirDefaultErrorMessages : DefaultErrorMessages.Extension {
|
||||
map.put(NAMED_PARAMETER_NOT_FOUND, "Cannot find a parameter with this name: {0}", TO_STRING)
|
||||
map.put(MANY_LAMBDA_EXPRESSION_ARGUMENTS, "Only one lambda expression is allowed outside a parenthesized argument list")
|
||||
|
||||
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(ASSIGNMENT_TYPE_MISMATCH, "Assignment type mismatch: actual type is {1} but {0} was expected", RENDER_TYPE, RENDER_TYPE)
|
||||
map.put(
|
||||
@@ -541,7 +546,6 @@ class FirDefaultErrorMessages : DefaultErrorMessages.Extension {
|
||||
map.put(NEXT_AMBIGUITY, "Method ''next()'' is ambiguous for this expression: {0}", SYMBOLS)
|
||||
|
||||
// Types & type parameters
|
||||
map.put(TYPE_MISMATCH, "Type mismatch: inferred type is {1} but {0} was expected", TO_STRING, TO_STRING)
|
||||
map.put(RECURSION_IN_IMPLICIT_TYPES, "Recursion in implicit types")
|
||||
map.put(INFERENCE_ERROR, "Inference error")
|
||||
map.put(PROJECTION_ON_NON_CLASS_TYPE_ARGUMENT, "Projections are not allowed on type arguments of functions and properties")
|
||||
|
||||
Vendored
+2
-2
@@ -109,7 +109,7 @@ fun t7() : Int {
|
||||
return 1
|
||||
2
|
||||
}
|
||||
catch (<!TYPE_MISMATCH!>e : Any<!>) {
|
||||
catch (<!THROWABLE_TYPE_MISMATCH!>e : Any<!>) {
|
||||
2
|
||||
}
|
||||
return 1 // this is OK, like in Java
|
||||
@@ -120,7 +120,7 @@ fun t8() : Int {
|
||||
return 1
|
||||
2
|
||||
}
|
||||
catch (<!TYPE_MISMATCH!>e : Any<!>) {
|
||||
catch (<!THROWABLE_TYPE_MISMATCH!>e : Any<!>) {
|
||||
return 1
|
||||
2
|
||||
}
|
||||
|
||||
+22
-8
@@ -841,6 +841,28 @@ internal val KT_DIAGNOSTIC_CONVERTER = KtDiagnosticConverterBuilder.buildConvert
|
||||
token,
|
||||
)
|
||||
}
|
||||
add(FirErrors.TYPE_MISMATCH) { firDiagnostic ->
|
||||
TypeMismatchImpl(
|
||||
firSymbolBuilder.typeBuilder.buildKtType(firDiagnostic.a),
|
||||
firSymbolBuilder.typeBuilder.buildKtType(firDiagnostic.b),
|
||||
firDiagnostic as FirPsiDiagnostic<*>,
|
||||
token,
|
||||
)
|
||||
}
|
||||
add(FirErrors.THROWABLE_TYPE_MISMATCH) { firDiagnostic ->
|
||||
ThrowableTypeMismatchImpl(
|
||||
firSymbolBuilder.typeBuilder.buildKtType(firDiagnostic.a),
|
||||
firDiagnostic as FirPsiDiagnostic<*>,
|
||||
token,
|
||||
)
|
||||
}
|
||||
add(FirErrors.CONDITION_TYPE_MISMATCH) { firDiagnostic ->
|
||||
ConditionTypeMismatchImpl(
|
||||
firSymbolBuilder.typeBuilder.buildKtType(firDiagnostic.a),
|
||||
firDiagnostic as FirPsiDiagnostic<*>,
|
||||
token,
|
||||
)
|
||||
}
|
||||
add(FirErrors.ARGUMENT_TYPE_MISMATCH) { firDiagnostic ->
|
||||
ArgumentTypeMismatchImpl(
|
||||
firSymbolBuilder.typeBuilder.buildKtType(firDiagnostic.a),
|
||||
@@ -975,14 +997,6 @@ internal val KT_DIAGNOSTIC_CONVERTER = KtDiagnosticConverterBuilder.buildConvert
|
||||
token,
|
||||
)
|
||||
}
|
||||
add(FirErrors.TYPE_MISMATCH) { firDiagnostic ->
|
||||
TypeMismatchImpl(
|
||||
firSymbolBuilder.typeBuilder.buildKtType(firDiagnostic.a),
|
||||
firSymbolBuilder.typeBuilder.buildKtType(firDiagnostic.b),
|
||||
firDiagnostic as FirPsiDiagnostic<*>,
|
||||
token,
|
||||
)
|
||||
}
|
||||
add(FirErrors.RECURSION_IN_IMPLICIT_TYPES) { firDiagnostic ->
|
||||
RecursionInImplicitTypesImpl(
|
||||
firDiagnostic as FirPsiDiagnostic<*>,
|
||||
|
||||
+16
-6
@@ -602,6 +602,22 @@ sealed class KtFirDiagnostic<PSI: PsiElement> : KtDiagnosticWithPsi<PSI> {
|
||||
abstract val candidate: KtSymbol
|
||||
}
|
||||
|
||||
abstract class TypeMismatch : KtFirDiagnostic<PsiElement>() {
|
||||
override val diagnosticClass get() = TypeMismatch::class
|
||||
abstract val expectedType: KtType
|
||||
abstract val actualType: KtType
|
||||
}
|
||||
|
||||
abstract class ThrowableTypeMismatch : KtFirDiagnostic<PsiElement>() {
|
||||
override val diagnosticClass get() = ThrowableTypeMismatch::class
|
||||
abstract val actualType: KtType
|
||||
}
|
||||
|
||||
abstract class ConditionTypeMismatch : KtFirDiagnostic<PsiElement>() {
|
||||
override val diagnosticClass get() = ConditionTypeMismatch::class
|
||||
abstract val actualType: KtType
|
||||
}
|
||||
|
||||
abstract class ArgumentTypeMismatch : KtFirDiagnostic<PsiElement>() {
|
||||
override val diagnosticClass get() = ArgumentTypeMismatch::class
|
||||
abstract val expectedType: KtType
|
||||
@@ -690,12 +706,6 @@ sealed class KtFirDiagnostic<PSI: PsiElement> : KtDiagnosticWithPsi<PSI> {
|
||||
abstract val candidates: List<KtSymbol>
|
||||
}
|
||||
|
||||
abstract class TypeMismatch : KtFirDiagnostic<PsiElement>() {
|
||||
override val diagnosticClass get() = TypeMismatch::class
|
||||
abstract val expectedType: KtType
|
||||
abstract val actualType: KtType
|
||||
}
|
||||
|
||||
abstract class RecursionInImplicitTypes : KtFirDiagnostic<PsiElement>() {
|
||||
override val diagnosticClass get() = RecursionInImplicitTypes::class
|
||||
}
|
||||
|
||||
+25
-9
@@ -969,6 +969,31 @@ internal class InapplicableCandidateImpl(
|
||||
override val firDiagnostic: FirPsiDiagnostic<*> by weakRef(firDiagnostic)
|
||||
}
|
||||
|
||||
internal class TypeMismatchImpl(
|
||||
override val expectedType: KtType,
|
||||
override val actualType: KtType,
|
||||
firDiagnostic: FirPsiDiagnostic<*>,
|
||||
override val token: ValidityToken,
|
||||
) : KtFirDiagnostic.TypeMismatch(), KtAbstractFirDiagnostic<PsiElement> {
|
||||
override val firDiagnostic: FirPsiDiagnostic<*> by weakRef(firDiagnostic)
|
||||
}
|
||||
|
||||
internal class ThrowableTypeMismatchImpl(
|
||||
override val actualType: KtType,
|
||||
firDiagnostic: FirPsiDiagnostic<*>,
|
||||
override val token: ValidityToken,
|
||||
) : KtFirDiagnostic.ThrowableTypeMismatch(), KtAbstractFirDiagnostic<PsiElement> {
|
||||
override val firDiagnostic: FirPsiDiagnostic<*> by weakRef(firDiagnostic)
|
||||
}
|
||||
|
||||
internal class ConditionTypeMismatchImpl(
|
||||
override val actualType: KtType,
|
||||
firDiagnostic: FirPsiDiagnostic<*>,
|
||||
override val token: ValidityToken,
|
||||
) : KtFirDiagnostic.ConditionTypeMismatch(), KtAbstractFirDiagnostic<PsiElement> {
|
||||
override val firDiagnostic: FirPsiDiagnostic<*> by weakRef(firDiagnostic)
|
||||
}
|
||||
|
||||
internal class ArgumentTypeMismatchImpl(
|
||||
override val expectedType: KtType,
|
||||
override val actualType: KtType,
|
||||
@@ -1111,15 +1136,6 @@ internal class NextAmbiguityImpl(
|
||||
override val firDiagnostic: FirPsiDiagnostic<*> by weakRef(firDiagnostic)
|
||||
}
|
||||
|
||||
internal class TypeMismatchImpl(
|
||||
override val expectedType: KtType,
|
||||
override val actualType: KtType,
|
||||
firDiagnostic: FirPsiDiagnostic<*>,
|
||||
override val token: ValidityToken,
|
||||
) : KtFirDiagnostic.TypeMismatch(), KtAbstractFirDiagnostic<PsiElement> {
|
||||
override val firDiagnostic: FirPsiDiagnostic<*> by weakRef(firDiagnostic)
|
||||
}
|
||||
|
||||
internal class RecursionInImplicitTypesImpl(
|
||||
firDiagnostic: FirPsiDiagnostic<*>,
|
||||
override val token: ValidityToken,
|
||||
|
||||
Reference in New Issue
Block a user