diff --git a/compiler/fir/analysis-tests/testData/resolve/catchParameter.kt b/compiler/fir/analysis-tests/testData/resolve/catchParameter.kt index e1a5d34d99e..1df7f78f7f3 100644 --- a/compiler/fir/analysis-tests/testData/resolve/catchParameter.kt +++ b/compiler/fir/analysis-tests/testData/resolve/catchParameter.kt @@ -9,15 +9,15 @@ fun test() { try {} catch (e: T) {} - try {} catch (e: () -> Int) {} + try {} catch (e: () -> Int) {} - try {} catch (e: StringType) {} + try {} catch (e: StringType) {} - try {} catch (e: Int = 5) {} + try {} catch (e: Int = 5) {} try {} catch (e: Throwable) {} } inline fun anotherTest() { - try {} catch (e: T) {} + try {} catch (e: T) {} } diff --git a/compiler/fir/checkers/checkers-component-generator/src/org/jetbrains/kotlin/fir/checkers/generator/diagnostics/FirDiagnosticsList.kt b/compiler/fir/checkers/checkers-component-generator/src/org/jetbrains/kotlin/fir/checkers/generator/diagnostics/FirDiagnosticsList.kt index 61d01694a98..0749d331f0e 100644 --- a/compiler/fir/checkers/checkers-component-generator/src/org/jetbrains/kotlin/fir/checkers/generator/diagnostics/FirDiagnosticsList.kt +++ b/compiler/fir/checkers/checkers-component-generator/src/org/jetbrains/kotlin/fir/checkers/generator/diagnostics/FirDiagnosticsList.kt @@ -242,6 +242,19 @@ object DIAGNOSTICS_LIST : DiagnosticList() { parameter("candidate") } + val TYPE_MISMATCH by error { + parameter("expectedType") + parameter("actualType") + } + + val THROWABLE_TYPE_MISMATCH by error { + parameter("actualType") + } + + val CONDITION_TYPE_MISMATCH by error { + parameter("actualType") + } + val ARGUMENT_TYPE_MISMATCH by error { parameter("expectedType") parameter("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 { - parameter("expectedType") - parameter("actualType") - } val RECURSION_IN_IMPLICIT_TYPES by error() val INFERENCE_ERROR by error() val PROJECTION_ON_NON_CLASS_TYPE_ARGUMENT by error() diff --git a/compiler/fir/checkers/gen/org/jetbrains/kotlin/fir/analysis/diagnostics/FirErrors.kt b/compiler/fir/checkers/gen/org/jetbrains/kotlin/fir/analysis/diagnostics/FirErrors.kt index 9c5fb9f0cd3..525705d3a87 100644 --- a/compiler/fir/checkers/gen/org/jetbrains/kotlin/fir/analysis/diagnostics/FirErrors.kt +++ b/compiler/fir/checkers/gen/org/jetbrains/kotlin/fir/analysis/diagnostics/FirErrors.kt @@ -216,6 +216,9 @@ object FirErrors { // Applicability val NONE_APPLICABLE by error1>>(SourceElementPositioningStrategies.REFERENCE_BY_QUALIFIED) val INAPPLICABLE_CANDIDATE by error1>(SourceElementPositioningStrategies.REFERENCE_BY_QUALIFIED) + val TYPE_MISMATCH by error2() + val THROWABLE_TYPE_MISMATCH by error1() + val CONDITION_TYPE_MISMATCH by error1() val ARGUMENT_TYPE_MISMATCH by error2() val NULL_FOR_NONNULL_TYPE by error0() val INAPPLICABLE_LATEINIT_MODIFIER by error1(SourceElementPositioningStrategies.LATEINIT_MODIFIER) @@ -238,7 +241,6 @@ object FirErrors { val NEXT_AMBIGUITY by error1>>(SourceElementPositioningStrategies.REFERENCE_BY_QUALIFIED) // Types & type parameters - val TYPE_MISMATCH by error2() val RECURSION_IN_IMPLICIT_TYPES by error0() val INFERENCE_ERROR by error0() val PROJECTION_ON_NON_CLASS_TYPE_ARGUMENT by error0() diff --git a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/FirHelpers.kt b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/FirHelpers.kt index a8c72f8bc1c..7afd0371317 100644 --- a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/FirHelpers.kt +++ b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/FirHelpers.kt @@ -292,10 +292,8 @@ fun FirClass<*>.findNonInterfaceSupertype(context: CheckerContext): FirTypeRef? val FirFunctionCall.isIterator get() = this.calleeReference.name.asString() == "" -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() { diff --git a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/expression/FirCatchParameterChecker.kt b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/expression/FirCatchParameterChecker.kt index 1b1c1d5b400..5195992239b 100644 --- a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/expression/FirCatchParameterChecker.kt +++ b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/expression/FirCatchParameterChecker.kt @@ -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) } } } diff --git a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/diagnostics/FirDefaultErrorMessages.kt b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/diagnostics/FirDefaultErrorMessages.kt index ba16937106f..4c0be3cd2f4 100644 --- a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/diagnostics/FirDefaultErrorMessages.kt +++ b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/diagnostics/FirDefaultErrorMessages.kt @@ -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") diff --git a/compiler/testData/diagnostics/tests/controlFlowAnalysis/deadCode/deadCodeDifferentExamples.fir.kt b/compiler/testData/diagnostics/tests/controlFlowAnalysis/deadCode/deadCodeDifferentExamples.fir.kt index 6cae426de24..1ff5abf6112 100644 --- a/compiler/testData/diagnostics/tests/controlFlowAnalysis/deadCode/deadCodeDifferentExamples.fir.kt +++ b/compiler/testData/diagnostics/tests/controlFlowAnalysis/deadCode/deadCodeDifferentExamples.fir.kt @@ -109,7 +109,7 @@ fun t7() : Int { return 1 2 } - catch (e : Any) { + catch (e : Any) { 2 } return 1 // this is OK, like in Java @@ -120,7 +120,7 @@ fun t8() : Int { return 1 2 } - catch (e : Any) { + catch (e : Any) { return 1 2 } diff --git a/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/diagnostics/KtFirDataClassConverters.kt b/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/diagnostics/KtFirDataClassConverters.kt index 05955fde1d5..5b71eaf8551 100644 --- a/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/diagnostics/KtFirDataClassConverters.kt +++ b/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/diagnostics/KtFirDataClassConverters.kt @@ -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<*>, diff --git a/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/diagnostics/KtFirDiagnostics.kt b/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/diagnostics/KtFirDiagnostics.kt index f944e769343..f05afe22e60 100644 --- a/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/diagnostics/KtFirDiagnostics.kt +++ b/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/diagnostics/KtFirDiagnostics.kt @@ -602,6 +602,22 @@ sealed class KtFirDiagnostic : KtDiagnosticWithPsi { abstract val candidate: KtSymbol } + abstract class TypeMismatch : KtFirDiagnostic() { + override val diagnosticClass get() = TypeMismatch::class + abstract val expectedType: KtType + abstract val actualType: KtType + } + + abstract class ThrowableTypeMismatch : KtFirDiagnostic() { + override val diagnosticClass get() = ThrowableTypeMismatch::class + abstract val actualType: KtType + } + + abstract class ConditionTypeMismatch : KtFirDiagnostic() { + override val diagnosticClass get() = ConditionTypeMismatch::class + abstract val actualType: KtType + } + abstract class ArgumentTypeMismatch : KtFirDiagnostic() { override val diagnosticClass get() = ArgumentTypeMismatch::class abstract val expectedType: KtType @@ -690,12 +706,6 @@ sealed class KtFirDiagnostic : KtDiagnosticWithPsi { abstract val candidates: List } - abstract class TypeMismatch : KtFirDiagnostic() { - override val diagnosticClass get() = TypeMismatch::class - abstract val expectedType: KtType - abstract val actualType: KtType - } - abstract class RecursionInImplicitTypes : KtFirDiagnostic() { override val diagnosticClass get() = RecursionInImplicitTypes::class } diff --git a/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/diagnostics/KtFirDiagnosticsImpl.kt b/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/diagnostics/KtFirDiagnosticsImpl.kt index 4c35aa692b9..7e530d9587d 100644 --- a/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/diagnostics/KtFirDiagnosticsImpl.kt +++ b/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/diagnostics/KtFirDiagnosticsImpl.kt @@ -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 { + override val firDiagnostic: FirPsiDiagnostic<*> by weakRef(firDiagnostic) +} + +internal class ThrowableTypeMismatchImpl( + override val actualType: KtType, + firDiagnostic: FirPsiDiagnostic<*>, + override val token: ValidityToken, +) : KtFirDiagnostic.ThrowableTypeMismatch(), KtAbstractFirDiagnostic { + override val firDiagnostic: FirPsiDiagnostic<*> by weakRef(firDiagnostic) +} + +internal class ConditionTypeMismatchImpl( + override val actualType: KtType, + firDiagnostic: FirPsiDiagnostic<*>, + override val token: ValidityToken, +) : KtFirDiagnostic.ConditionTypeMismatch(), KtAbstractFirDiagnostic { + 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 { - override val firDiagnostic: FirPsiDiagnostic<*> by weakRef(firDiagnostic) -} - internal class RecursionInImplicitTypesImpl( firDiagnostic: FirPsiDiagnostic<*>, override val token: ValidityToken,