diff --git a/compiler/fir/analysis-tests/testData/resolve/extendedCheckers/CanBeValChecker.kt b/compiler/fir/analysis-tests/testData/resolve/extendedCheckers/CanBeValChecker.kt index b2fbb4ee180..5beb1944437 100644 --- a/compiler/fir/analysis-tests/testData/resolve/extendedCheckers/CanBeValChecker.kt +++ b/compiler/fir/analysis-tests/testData/resolve/extendedCheckers/CanBeValChecker.kt @@ -107,7 +107,7 @@ fun foo() { if (bool) a = 4 else a = 42 val b: String - b = false + b = false } fun cycles() { diff --git a/compiler/fir/analysis-tests/testData/resolve/extendedCheckers/canBeReplacedWithOperatorAssignment/mutableList.kt b/compiler/fir/analysis-tests/testData/resolve/extendedCheckers/canBeReplacedWithOperatorAssignment/mutableList.kt index b8e16cb844b..ba4fb09fdd9 100644 --- a/compiler/fir/analysis-tests/testData/resolve/extendedCheckers/canBeReplacedWithOperatorAssignment/mutableList.kt +++ b/compiler/fir/analysis-tests/testData/resolve/extendedCheckers/canBeReplacedWithOperatorAssignment/mutableList.kt @@ -5,5 +5,5 @@ fun foo() { // now, Idea hightlights this code like error (cuz listVar // is mutable and listVar + 4 is immutable) and like warning // (cuz can be replaced with +=) - listVar = listVar + 4 + listVar = listVar + 4 } diff --git a/compiler/fir/analysis-tests/testData/resolve/problems/secondaryConstructorCfg.kt b/compiler/fir/analysis-tests/testData/resolve/problems/secondaryConstructorCfg.kt index c1060e44fdd..6324e674bdb 100644 --- a/compiler/fir/analysis-tests/testData/resolve/problems/secondaryConstructorCfg.kt +++ b/compiler/fir/analysis-tests/testData/resolve/problems/secondaryConstructorCfg.kt @@ -7,7 +7,7 @@ class B(p0: String) { p3 = p1 } init { - p1 = p0.length + p1 = p0.length p3 = "" } } 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 f1df3243773..5f4b860c480 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 @@ -272,6 +272,16 @@ object DIAGNOSTICS_LIST : DiagnosticList() { parameter("name") } + val ASSIGNMENT_TYPE_MISMATCH by error { + parameter("expected") + parameter("actual") + } + + val RESULT_TYPE_MISMATCH by error { + parameter("expected") + parameter("actual") + } + val MANY_LAMBDA_EXPRESSION_ARGUMENTS 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 69932276ff3..6f64df723f6 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 @@ -226,6 +226,8 @@ object FirErrors { val TOO_MANY_ARGUMENTS by error1>() val NO_VALUE_FOR_PARAMETER by error1(SourceElementPositioningStrategies.VALUE_ARGUMENTS) val NAMED_PARAMETER_NOT_FOUND by error1(SourceElementPositioningStrategies.NAME_OF_NAMED_ARGUMENT) + val ASSIGNMENT_TYPE_MISMATCH by error2() + val RESULT_TYPE_MISMATCH by error2() val MANY_LAMBDA_EXPRESSION_ARGUMENTS by error0() // Ambiguity 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 660db72e117..72577d2c92f 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 @@ -11,6 +11,7 @@ import org.jetbrains.kotlin.descriptors.Visibilities import org.jetbrains.kotlin.descriptors.Visibility import org.jetbrains.kotlin.fir.* import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext +import org.jetbrains.kotlin.fir.analysis.diagnostics.* import org.jetbrains.kotlin.fir.analysis.diagnostics.modalityModifier import org.jetbrains.kotlin.fir.analysis.diagnostics.overrideModifier import org.jetbrains.kotlin.fir.analysis.diagnostics.visibilityModifier @@ -33,8 +34,7 @@ import org.jetbrains.kotlin.fir.symbols.impl.* import org.jetbrains.kotlin.fir.types.* import org.jetbrains.kotlin.lexer.KtModifierKeywordToken import org.jetbrains.kotlin.lexer.KtTokens -import org.jetbrains.kotlin.name.ClassId -import org.jetbrains.kotlin.name.FqName +import org.jetbrains.kotlin.name.* import org.jetbrains.kotlin.psi.KtModifierList import org.jetbrains.kotlin.psi.KtParameter.VAL_VAR_TOKEN_SET import org.jetbrains.kotlin.psi.psiUtil.visibilityModifierType @@ -519,3 +519,45 @@ private val FirSimpleFunction.matchesHashCodeSignature: Boolean private val FirSimpleFunction.matchesToStringSignature: Boolean get() = valueParameters.isEmpty() + +fun checkTypeMismatch( + lValueType: ConeKotlinType, + rValue: FirExpression, + context: CheckerContext, + source: FirSourceElement, + reporter: DiagnosticReporter, + isInitializer: Boolean +) { + val rValueType = rValue.typeRef.coneType + val typeContext = context.session.typeContext + + if (!isSubtypeForTypeMismatch(typeContext, subtype = rValueType, supertype = lValueType)) { + if (rValueType is ConeClassLikeType && + rValueType.lookupTag.classId == StandardClassIds.Int && + lValueType.fullyExpandedType(context.session).isIntegerTypeOrNullableIntegerTypeOfAnySize && + rValueType.nullability == ConeNullability.NOT_NULL + ) { + // val p: Byte = 42 or similar situation + // TODO: remove after fix of KT-46047 + return + } + if (lValueType.isExtensionFunctionType || rValueType.isExtensionFunctionType) { + // TODO: remove after fix of KT-45989 + return + } + if (rValue.isNullLiteral && lValueType.nullability == ConeNullability.NOT_NULL) { + reporter.reportOn(rValue.source, FirErrors.NULL_FOR_NONNULL_TYPE, context) + } else { + val diagnosticFactory = when { + isInitializer -> + FirErrors.INITIALIZER_TYPE_MISMATCH + source.kind is FirFakeSourceElementKind.DesugaredIncrementOrDecrement -> + FirErrors.RESULT_TYPE_MISMATCH + else -> + FirErrors.ASSIGNMENT_TYPE_MISMATCH + } + + reporter.report(diagnosticFactory.on(source, lValueType, rValueType), context) + } + } +} \ No newline at end of file diff --git a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/declaration/FirInitializerTypeMismatchChecker.kt b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/declaration/FirInitializerTypeMismatchChecker.kt index 035719fdfad..eed99e0e473 100644 --- a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/declaration/FirInitializerTypeMismatchChecker.kt +++ b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/declaration/FirInitializerTypeMismatchChecker.kt @@ -7,18 +7,12 @@ package org.jetbrains.kotlin.fir.analysis.checkers.declaration import org.jetbrains.kotlin.KtNodeTypes import org.jetbrains.kotlin.fir.FirRealSourceElementKind +import org.jetbrains.kotlin.fir.analysis.checkers.checkTypeMismatch import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext -import org.jetbrains.kotlin.fir.analysis.checkers.isSubtypeForTypeMismatch +import org.jetbrains.kotlin.fir.analysis.checkers.isComponentCall import org.jetbrains.kotlin.fir.analysis.diagnostics.DiagnosticReporter -import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors -import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.INITIALIZER_TYPE_MISMATCH -import org.jetbrains.kotlin.fir.analysis.diagnostics.reportOn import org.jetbrains.kotlin.fir.declarations.FirProperty -import org.jetbrains.kotlin.fir.expressions.FirComponentCall -import org.jetbrains.kotlin.fir.resolve.fullyExpandedType -import org.jetbrains.kotlin.fir.typeContext -import org.jetbrains.kotlin.fir.types.* -import org.jetbrains.kotlin.name.StandardClassIds +import org.jetbrains.kotlin.fir.types.coneType object FirInitializerTypeMismatchChecker : FirPropertyChecker() { override fun check(declaration: FirProperty, context: CheckerContext, reporter: DiagnosticReporter) { @@ -28,28 +22,7 @@ object FirInitializerTypeMismatchChecker : FirPropertyChecker() { if (initializer is FirComponentCall) return if (declaration.returnTypeRef.source?.kind != FirRealSourceElementKind) return val propertyType = declaration.returnTypeRef.coneType - val expressionType = initializer.typeRef.coneTypeSafe() ?: return - val typeContext = context.session.typeContext - if (!isSubtypeForTypeMismatch(typeContext, subtype = expressionType, supertype = propertyType)) { - if (expressionType is ConeClassLikeType && - expressionType.lookupTag.classId == StandardClassIds.Int && - propertyType.fullyExpandedType(context.session).isIntegerTypeOrNullableIntegerTypeOfAnySize && - expressionType.nullability == ConeNullability.NOT_NULL - ) { - // val p: Byte = 42 or similar situation - // TODO: remove after fix of KT-46047 - return - } - if (propertyType.isExtensionFunctionType || expressionType.isExtensionFunctionType) { - // TODO: remove after fix of KT-45989 - return - } - if (initializer.isNullLiteral && propertyType.nullability == ConeNullability.NOT_NULL) { - reporter.reportOn(initializer.source, FirErrors.NULL_FOR_NONNULL_TYPE, context) - } else { - reporter.report(INITIALIZER_TYPE_MISMATCH.on(source, propertyType, expressionType), context) - } - } + checkTypeMismatch(propertyType, initializer, context, source, reporter, true) } } \ No newline at end of file diff --git a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/expression/FirAssignmentTypeMismatchChecker.kt b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/expression/FirAssignmentTypeMismatchChecker.kt index e930c22fd0b..d37ef1c7aec 100644 --- a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/expression/FirAssignmentTypeMismatchChecker.kt +++ b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/expression/FirAssignmentTypeMismatchChecker.kt @@ -5,25 +5,21 @@ package org.jetbrains.kotlin.fir.analysis.checkers.expression +import org.jetbrains.kotlin.fir.analysis.checkers.checkTypeMismatch import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext import org.jetbrains.kotlin.fir.analysis.diagnostics.DiagnosticReporter -import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors -import org.jetbrains.kotlin.fir.analysis.diagnostics.reportOn import org.jetbrains.kotlin.fir.expressions.FirVariableAssignment import org.jetbrains.kotlin.fir.references.FirResolvedNamedReference import org.jetbrains.kotlin.fir.symbols.impl.FirPropertySymbol -import org.jetbrains.kotlin.fir.types.ConeNullability import org.jetbrains.kotlin.fir.types.coneType -import org.jetbrains.kotlin.fir.types.isNullLiteral object FirAssignmentTypeMismatchChecker : FirVariableAssignmentChecker() { override fun check(expression: FirVariableAssignment, context: CheckerContext, reporter: DiagnosticReporter) { - val rValue = expression.rValue - if (rValue.isNullLiteral) { - val leftType = ((expression.lValue as? FirResolvedNamedReference)?.resolvedSymbol as? FirPropertySymbol)?.fir?.returnTypeRef - if (leftType?.coneType?.nullability == ConeNullability.NOT_NULL) { - reporter.reportOn(rValue.source, FirErrors.NULL_FOR_NONNULL_TYPE, context) - } - } + val source = expression.rValue.source ?: return + val lValueType = + ((expression.lValue as? FirResolvedNamedReference)?.resolvedSymbol as? FirPropertySymbol)?.fir?.returnTypeRef?.coneType + ?: return + + checkTypeMismatch(lValueType, expression.rValue, context, source, reporter, false) } } \ No newline at end of file diff --git a/compiler/testData/diagnostics/tests/IncDec.fir.kt b/compiler/testData/diagnostics/tests/IncDec.fir.kt index aae0f0cc705..ed80b43471c 100644 --- a/compiler/testData/diagnostics/tests/IncDec.fir.kt +++ b/compiler/testData/diagnostics/tests/IncDec.fir.kt @@ -22,10 +22,10 @@ class WrongIncDec() { fun testWrongIncDec() { var x = WrongIncDec() - x++ - ++x - x-- - --x + x++ + ++x + x-- + --x } class UnitIncDec() { @@ -35,12 +35,12 @@ class UnitIncDec() { fun testUnitIncDec() { var x = UnitIncDec() - x++ - ++x - x-- - --x - x = x++ - x = x-- - x = ++x - x = --x + x++ + ++x + x-- + --x + x = x++ + x = x-- + x = ++x + x = --x } diff --git a/compiler/testData/diagnostics/tests/generics/capturedParameters/objectLiteral.fir.kt b/compiler/testData/diagnostics/tests/generics/capturedParameters/objectLiteral.fir.kt index 75dabffae95..e2025ae2620 100644 --- a/compiler/testData/diagnostics/tests/generics/capturedParameters/objectLiteral.fir.kt +++ b/compiler/testData/diagnostics/tests/generics/capturedParameters/objectLiteral.fir.kt @@ -13,7 +13,7 @@ class Q { private var y = foo() fun bar() { - x = y + x = y x = foo() y = foo() diff --git a/compiler/testData/diagnostics/tests/generics/innerClasses/iterator.fir.kt b/compiler/testData/diagnostics/tests/generics/innerClasses/iterator.fir.kt index 3cc3ddfffa3..49a3c44cbff 100644 --- a/compiler/testData/diagnostics/tests/generics/innerClasses/iterator.fir.kt +++ b/compiler/testData/diagnostics/tests/generics/innerClasses/iterator.fir.kt @@ -29,7 +29,7 @@ fun commonSupertype(x: E, y: E): E = x fun foo() { var myIt = A().iterator() - myIt = A().iterator() + myIt = A().iterator() val csIt: Iterator = A().iterator() diff --git a/compiler/testData/diagnostics/tests/generics/innerClasses/qualifiedOuter.fir.kt b/compiler/testData/diagnostics/tests/generics/innerClasses/qualifiedOuter.fir.kt index 680ac81cc21..29f126589f7 100644 --- a/compiler/testData/diagnostics/tests/generics/innerClasses/qualifiedOuter.fir.kt +++ b/compiler/testData/diagnostics/tests/generics/innerClasses/qualifiedOuter.fir.kt @@ -11,7 +11,7 @@ class Outer { z.checkType { _() } z.checkType { _.Inner>() } - inner = x + inner = x } class Nested diff --git a/compiler/testData/diagnostics/tests/generics/nullability/smartCastsValueArgument.fir.kt b/compiler/testData/diagnostics/tests/generics/nullability/smartCastsValueArgument.fir.kt index 7af4c403d9b..672d2e18f86 100644 --- a/compiler/testData/diagnostics/tests/generics/nullability/smartCastsValueArgument.fir.kt +++ b/compiler/testData/diagnostics/tests/generics/nullability/smartCastsValueArgument.fir.kt @@ -12,7 +12,7 @@ fun foo(x: T) { if (x != null) {} y1 = x - y2 = x + y2 = x bar1(x) bar1(x) @@ -31,7 +31,7 @@ fun foo(x: T) { if (x is CharSequence) { y1 = x - y2 = x + y2 = x bar1(x) bar2(x) diff --git a/compiler/testData/diagnostics/tests/generics/nullability/tpInBounds.fir.kt b/compiler/testData/diagnostics/tests/generics/nullability/tpInBounds.fir.kt index 46aafea8786..23624fb4fd6 100644 --- a/compiler/testData/diagnostics/tests/generics/nullability/tpInBounds.fir.kt +++ b/compiler/testData/diagnostics/tests/generics/nullability/tpInBounds.fir.kt @@ -24,10 +24,10 @@ class A { } if (1 == 1) { - t = tN + t = tN } - t = y + t = y if (y != null) { t = y diff --git a/compiler/testData/diagnostics/tests/generics/varProjection/setterNotProjectedOutAssign.fir.kt b/compiler/testData/diagnostics/tests/generics/varProjection/setterNotProjectedOutAssign.fir.kt index 43e03f9af31..6519e562bfe 100644 --- a/compiler/testData/diagnostics/tests/generics/varProjection/setterNotProjectedOutAssign.fir.kt +++ b/compiler/testData/diagnostics/tests/generics/varProjection/setterNotProjectedOutAssign.fir.kt @@ -5,6 +5,6 @@ interface Tr { } fun test(t: Tr<*>) { - t.v = t + t.v = t t.v checkType { _>() } -} \ No newline at end of file +} diff --git a/compiler/testData/diagnostics/tests/generics/varProjection/setterProjectedOutAssign.fir.kt b/compiler/testData/diagnostics/tests/generics/varProjection/setterProjectedOutAssign.fir.kt index 6e586fd7c04..e496c211df9 100644 --- a/compiler/testData/diagnostics/tests/generics/varProjection/setterProjectedOutAssign.fir.kt +++ b/compiler/testData/diagnostics/tests/generics/varProjection/setterProjectedOutAssign.fir.kt @@ -8,7 +8,7 @@ interface Tr { fun test(t: Tr<*>) { t.v = null!! - t.v = "" + t.v = "" t.v = null t.v checkType { _() } -} \ No newline at end of file +} diff --git a/compiler/testData/diagnostics/tests/generics/varProjection/setterProjectedOutNoPlusAssign.fir.kt b/compiler/testData/diagnostics/tests/generics/varProjection/setterProjectedOutNoPlusAssign.fir.kt index 48d011721fd..c63e7486b07 100644 --- a/compiler/testData/diagnostics/tests/generics/varProjection/setterProjectedOutNoPlusAssign.fir.kt +++ b/compiler/testData/diagnostics/tests/generics/varProjection/setterProjectedOutNoPlusAssign.fir.kt @@ -7,5 +7,5 @@ interface Tr { fun test(t: Tr) { // resolved as t.v = t.v + null!!, where type of right operand is String, // so TYPE_MISMATCH: String is not <: of Captured(out String) - t.v += null!! -} \ No newline at end of file + t.v += null!! +} diff --git a/compiler/testData/diagnostics/tests/operatorsOverloading/assignmentOperationsCheckReturnType.fir.kt b/compiler/testData/diagnostics/tests/operatorsOverloading/assignmentOperationsCheckReturnType.fir.kt index 6f622c7bf2c..a1298941e5c 100644 --- a/compiler/testData/diagnostics/tests/operatorsOverloading/assignmentOperationsCheckReturnType.fir.kt +++ b/compiler/testData/diagnostics/tests/operatorsOverloading/assignmentOperationsCheckReturnType.fir.kt @@ -3,15 +3,15 @@ fun intBinEq() { x += 'a' x += 1.toByte() x += 1.toShort() - x += 1L - x += 1f - x += 1.0 + x += 1L + x += 1f + x += 1.0 x *= 'a' - x *= 1.toByte() - x *= 1.toShort() - x *= 1L - x *= 1f - x *= 1.0 + x *= 1.toByte() + x *= 1.toShort() + x *= 1L + x *= 1f + x *= 1.0 } fun shortBinEq() { @@ -19,16 +19,16 @@ fun shortBinEq() { x += 'a' x += 1.toByte() x += 1.toShort() - x += 1L - x += 1f - x += 1.0 + x += 1L + x += 1f + x += 1.0 x *= 'a' - x *= 1.toByte() - x *= 1.toShort() - x *= 1L - x *= 1f - x *= 1.0 + x *= 1.toByte() + x *= 1.toShort() + x *= 1L + x *= 1f + x *= 1.0 } class A { @@ -44,5 +44,5 @@ fun overloading() { var y = A() x += y var z = B() - z += x + z += x } diff --git a/compiler/testData/diagnostics/tests/platformTypes/nullabilityWarnings/assignToVar.fir.kt b/compiler/testData/diagnostics/tests/platformTypes/nullabilityWarnings/assignToVar.fir.kt index 0bd4993ff8e..a59e1eda6f7 100644 --- a/compiler/testData/diagnostics/tests/platformTypes/nullabilityWarnings/assignToVar.fir.kt +++ b/compiler/testData/diagnostics/tests/platformTypes/nullabilityWarnings/assignToVar.fir.kt @@ -18,10 +18,10 @@ var n: J? = J() fun test() { v = J.staticNN - v = J.staticN + v = J.staticN v = J.staticJ n = J.staticNN n = J.staticN n = J.staticJ -} \ No newline at end of file +} diff --git a/compiler/testData/diagnostics/tests/properties/inferenceFromGetters/overrides.fir.kt b/compiler/testData/diagnostics/tests/properties/inferenceFromGetters/overrides.fir.kt index 5fcf7b94f99..d1b28d1fe26 100644 --- a/compiler/testData/diagnostics/tests/properties/inferenceFromGetters/overrides.fir.kt +++ b/compiler/testData/diagnostics/tests/properties/inferenceFromGetters/overrides.fir.kt @@ -34,8 +34,8 @@ fun foo(c: C) { c.z checkType { _() } c.y = "" - c.y = 1 + c.y = 1 c.z = "" - c.z = 1 + c.z = 1 } diff --git a/compiler/testData/diagnostics/tests/properties/inferenceFromGetters/vars.fir.kt b/compiler/testData/diagnostics/tests/properties/inferenceFromGetters/vars.fir.kt index 2b23646cc00..e57626a1bc6 100644 --- a/compiler/testData/diagnostics/tests/properties/inferenceFromGetters/vars.fir.kt +++ b/compiler/testData/diagnostics/tests/properties/inferenceFromGetters/vars.fir.kt @@ -14,8 +14,8 @@ fun foo() { noSetter checkType { _() } x = 1 - x = "" + x = "" noSetter = 2 - noSetter = "" + noSetter = "" } diff --git a/compiler/testData/diagnostics/tests/resolve/priority/kt10219.fir.kt b/compiler/testData/diagnostics/tests/resolve/priority/kt10219.fir.kt index ec8217ed65a..3484035cfca 100644 --- a/compiler/testData/diagnostics/tests/resolve/priority/kt10219.fir.kt +++ b/compiler/testData/diagnostics/tests/resolve/priority/kt10219.fir.kt @@ -15,7 +15,7 @@ fun a(c: Calendar) { A().apply { c.apply { timeInMillis = 5 // synthesized variable for get|setTimeInMillis - timeInMillis = "" + timeInMillis = "" } timeInMillis = "" } diff --git a/compiler/testData/diagnostics/tests/smartCasts/incDecToNull.fir.kt b/compiler/testData/diagnostics/tests/smartCasts/incDecToNull.fir.kt index aea96ca9533..db4cd7bc2c9 100644 --- a/compiler/testData/diagnostics/tests/smartCasts/incDecToNull.fir.kt +++ b/compiler/testData/diagnostics/tests/smartCasts/incDecToNull.fir.kt @@ -4,7 +4,7 @@ class IncDec { fun foo(): IncDec { var x = IncDec() - x = x++ - x++ + x = x++ + x++ return x } diff --git a/compiler/testData/diagnostics/tests/subtyping/localAnonymousObjects.fir.kt b/compiler/testData/diagnostics/tests/subtyping/localAnonymousObjects.fir.kt index c730c51833c..0f9fde25c51 100644 --- a/compiler/testData/diagnostics/tests/subtyping/localAnonymousObjects.fir.kt +++ b/compiler/testData/diagnostics/tests/subtyping/localAnonymousObjects.fir.kt @@ -1,5 +1,5 @@ // !DIAGNOSTICS: -ASSIGNED_BUT_NEVER_ACCESSED_VARIABLE -UNUSED_VALUE fun test() { var x = object {} - x = object {} + x = object {} } \ No newline at end of file diff --git a/compiler/testData/diagnostics/tests/subtyping/localClasses.fir.kt b/compiler/testData/diagnostics/tests/subtyping/localClasses.fir.kt index 9306dd94882..9e1ef9ad01b 100644 --- a/compiler/testData/diagnostics/tests/subtyping/localClasses.fir.kt +++ b/compiler/testData/diagnostics/tests/subtyping/localClasses.fir.kt @@ -15,5 +15,5 @@ private fun foo() = run { fun test() { var x = foo(1) - x = foo() -} \ No newline at end of file + x = foo() +} diff --git a/compiler/testData/diagnostics/tests/subtyping/memberAnonymousObjects.fir.kt b/compiler/testData/diagnostics/tests/subtyping/memberAnonymousObjects.fir.kt index f13a0613b9a..8ecc2315fab 100644 --- a/compiler/testData/diagnostics/tests/subtyping/memberAnonymousObjects.fir.kt +++ b/compiler/testData/diagnostics/tests/subtyping/memberAnonymousObjects.fir.kt @@ -1,6 +1,6 @@ class Test { private var x = object {}; init { - x = object {} + x = object {} } } \ No newline at end of file diff --git a/compiler/testData/diagnostics/tests/subtyping/nestedIntoLocalClasses.fir.kt b/compiler/testData/diagnostics/tests/subtyping/nestedIntoLocalClasses.fir.kt index bcd2f8e1689..272f03cc3ad 100644 --- a/compiler/testData/diagnostics/tests/subtyping/nestedIntoLocalClasses.fir.kt +++ b/compiler/testData/diagnostics/tests/subtyping/nestedIntoLocalClasses.fir.kt @@ -19,5 +19,5 @@ private fun foo() = run { fun test() { var x = foo(1) - x = foo() -} \ No newline at end of file + x = foo() +} diff --git a/compiler/testData/diagnostics/tests/subtyping/nestedLocalClasses.fir.kt b/compiler/testData/diagnostics/tests/subtyping/nestedLocalClasses.fir.kt index cfd165e6e6d..ace431c0c07 100644 --- a/compiler/testData/diagnostics/tests/subtyping/nestedLocalClasses.fir.kt +++ b/compiler/testData/diagnostics/tests/subtyping/nestedLocalClasses.fir.kt @@ -19,5 +19,5 @@ private fun foo() = run { fun test() { var x = foo(1) - x = foo() -} \ No newline at end of file + x = foo() +} diff --git a/compiler/testData/diagnostics/tests/subtyping/topLevelAnonymousObjects.fir.kt b/compiler/testData/diagnostics/tests/subtyping/topLevelAnonymousObjects.fir.kt index 61a12cefa27..643151b5c0b 100644 --- a/compiler/testData/diagnostics/tests/subtyping/topLevelAnonymousObjects.fir.kt +++ b/compiler/testData/diagnostics/tests/subtyping/topLevelAnonymousObjects.fir.kt @@ -1,5 +1,5 @@ private var x = object {} fun test() { - x = object {} -} \ No newline at end of file + x = object {} +} diff --git a/compiler/testData/diagnostics/tests/syntheticExtensions/javaProperties/KotlinOverridesJava.fir.kt b/compiler/testData/diagnostics/tests/syntheticExtensions/javaProperties/KotlinOverridesJava.fir.kt index 96fb042fcda..46e18b9869c 100644 --- a/compiler/testData/diagnostics/tests/syntheticExtensions/javaProperties/KotlinOverridesJava.fir.kt +++ b/compiler/testData/diagnostics/tests/syntheticExtensions/javaProperties/KotlinOverridesJava.fir.kt @@ -29,7 +29,7 @@ fun foo(k: KotlinClass) { useString(k.getSomething5()) useString(k.something5) k.setSomething5(1) - k.something5 = 1 + k.something5 = 1 } fun useInt(i: Int) {} diff --git a/compiler/testData/diagnostics/tests/syntheticExtensions/javaProperties/KotlinOverridesJava2.fir.kt b/compiler/testData/diagnostics/tests/syntheticExtensions/javaProperties/KotlinOverridesJava2.fir.kt index 458b84bfd6c..69c22016a2a 100644 --- a/compiler/testData/diagnostics/tests/syntheticExtensions/javaProperties/KotlinOverridesJava2.fir.kt +++ b/compiler/testData/diagnostics/tests/syntheticExtensions/javaProperties/KotlinOverridesJava2.fir.kt @@ -9,7 +9,7 @@ fun foo(k: KotlinClass) { if (k.something == null) return k.setSomething(1) - k.something = 1 + k.something = 1 } fun useString(i: String) {} diff --git a/compiler/testData/diagnostics/tests/syntheticExtensions/javaProperties/OverrideGetterOnly.fir.kt b/compiler/testData/diagnostics/tests/syntheticExtensions/javaProperties/OverrideGetterOnly.fir.kt index 77096c235da..270e349f731 100644 --- a/compiler/testData/diagnostics/tests/syntheticExtensions/javaProperties/OverrideGetterOnly.fir.kt +++ b/compiler/testData/diagnostics/tests/syntheticExtensions/javaProperties/OverrideGetterOnly.fir.kt @@ -4,7 +4,7 @@ fun foo(o: JavaClass2) { useString(o.something) o.something = "" o.setSomething(1) - o.something = 1 // we generate extension property for JavaClass2 with more specific type + o.something = 1 // we generate extension property for JavaClass2 with more specific type o.something += "1" } @@ -19,4 +19,4 @@ public class JavaClass1 { // FILE: JavaClass2.java public class JavaClass2 extends JavaClass1 { public String getSomething() { return ""; } -} \ No newline at end of file +} diff --git a/compiler/testData/diagnostics/tests/varargs/varargInSetter.fir.kt b/compiler/testData/diagnostics/tests/varargs/varargInSetter.fir.kt index 2a9b2059798..56b49f5cd9c 100644 --- a/compiler/testData/diagnostics/tests/varargs/varargInSetter.fir.kt +++ b/compiler/testData/diagnostics/tests/varargs/varargInSetter.fir.kt @@ -1,6 +1,6 @@ class My { var x: String = "" set(vararg value) { - x = value + x = value } -} \ No newline at end of file +} diff --git a/compiler/tests-spec/testData/diagnostics/linked/expressions/prefix-expressions/prefix-decrement-expression/p-5/neg/2.1.fir.kt b/compiler/tests-spec/testData/diagnostics/linked/expressions/prefix-expressions/prefix-decrement-expression/p-5/neg/2.1.fir.kt index 96ac76ea7a6..512e8850fba 100644 --- a/compiler/tests-spec/testData/diagnostics/linked/expressions/prefix-expressions/prefix-decrement-expression/p-5/neg/2.1.fir.kt +++ b/compiler/tests-spec/testData/diagnostics/linked/expressions/prefix-expressions/prefix-decrement-expression/p-5/neg/2.1.fir.kt @@ -6,7 +6,7 @@ fun case1() { var a = Case1() - val res: Any? = ++a + val res: Any? = ++a } @@ -23,7 +23,7 @@ class B() {} fun case2() { var a = Case2() - val res: Any? = ++a + val res: Any? = ++a } class Case2() : C() { diff --git a/compiler/tests-spec/testData/diagnostics/linked/expressions/prefix-expressions/prefix-increment-expression/p-5/neg/2.1.fir.kt b/compiler/tests-spec/testData/diagnostics/linked/expressions/prefix-expressions/prefix-increment-expression/p-5/neg/2.1.fir.kt index 27a763cc10e..e0624495864 100644 --- a/compiler/tests-spec/testData/diagnostics/linked/expressions/prefix-expressions/prefix-increment-expression/p-5/neg/2.1.fir.kt +++ b/compiler/tests-spec/testData/diagnostics/linked/expressions/prefix-expressions/prefix-increment-expression/p-5/neg/2.1.fir.kt @@ -6,7 +6,7 @@ fun case1() { var a = Case1() - val res: Any? = --a + val res: Any? = --a } @@ -23,7 +23,7 @@ class B() {} fun case2() { var a = Case2() - val res: Any? = --a + val res: Any? = --a } class Case2() : C() { diff --git a/compiler/tests-spec/testData/diagnostics/linked/type-system/introduction-1/p-6/neg/2.1.fir.kt b/compiler/tests-spec/testData/diagnostics/linked/type-system/introduction-1/p-6/neg/2.1.fir.kt index f47ecdce07c..ef0a817836b 100644 --- a/compiler/tests-spec/testData/diagnostics/linked/type-system/introduction-1/p-6/neg/2.1.fir.kt +++ b/compiler/tests-spec/testData/diagnostics/linked/type-system/introduction-1/p-6/neg/2.1.fir.kt @@ -53,7 +53,7 @@ fun case_9() { // TESTCASE NUMBER: 10 fun case_10(x: Int?) { var y = 10 - y = x + y = x } // TESTCASE NUMBER: 11 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 d209917bf08..56d7938c201 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 @@ -914,6 +914,22 @@ internal val KT_DIAGNOSTIC_CONVERTER = KtDiagnosticConverterBuilder.buildConvert token, ) } + add(FirErrors.ASSIGNMENT_TYPE_MISMATCH) { firDiagnostic -> + AssignmentTypeMismatchImpl( + firSymbolBuilder.typeBuilder.buildKtType(firDiagnostic.a), + firSymbolBuilder.typeBuilder.buildKtType(firDiagnostic.b), + firDiagnostic as FirPsiDiagnostic<*>, + token, + ) + } + add(FirErrors.RESULT_TYPE_MISMATCH) { firDiagnostic -> + ResultTypeMismatchImpl( + firSymbolBuilder.typeBuilder.buildKtType(firDiagnostic.a), + firSymbolBuilder.typeBuilder.buildKtType(firDiagnostic.b), + firDiagnostic as FirPsiDiagnostic<*>, + token, + ) + } add(FirErrors.OVERLOAD_RESOLUTION_AMBIGUITY) { firDiagnostic -> OverloadResolutionAmbiguityImpl( firDiagnostic.a.map { abstractFirBasedSymbol -> 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 747abc88691..018c605ae1c 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 @@ -649,6 +649,18 @@ sealed class KtFirDiagnostic : KtDiagnosticWithPsi { abstract val name: String } + abstract class AssignmentTypeMismatch : KtFirDiagnostic() { + override val diagnosticClass get() = AssignmentTypeMismatch::class + abstract val expected: KtType + abstract val actual: KtType + } + + abstract class ResultTypeMismatch : KtFirDiagnostic() { + override val diagnosticClass get() = ResultTypeMismatch::class + abstract val expected: KtType + abstract val actual: KtType + } + abstract class ManyLambdaExpressionArguments : KtFirDiagnostic() { override val diagnosticClass get() = ManyLambdaExpressionArguments::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 3f76c797e98..8dc0aeda12c 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 @@ -1046,6 +1046,24 @@ internal class NamedParameterNotFoundImpl( override val firDiagnostic: FirPsiDiagnostic<*> by weakRef(firDiagnostic) } +internal class AssignmentTypeMismatchImpl( + override val expected: KtType, + override val actual: KtType, + firDiagnostic: FirPsiDiagnostic<*>, + override val token: ValidityToken, +) : KtFirDiagnostic.AssignmentTypeMismatch(), KtAbstractFirDiagnostic { + override val firDiagnostic: FirPsiDiagnostic<*> by weakRef(firDiagnostic) +} + +internal class ResultTypeMismatchImpl( + override val expected: KtType, + override val actual: KtType, + firDiagnostic: FirPsiDiagnostic<*>, + override val token: ValidityToken, +) : KtFirDiagnostic.ResultTypeMismatch(), KtAbstractFirDiagnostic { + override val firDiagnostic: FirPsiDiagnostic<*> by weakRef(firDiagnostic) +} + internal class ManyLambdaExpressionArgumentsImpl( firDiagnostic: FirPsiDiagnostic<*>, override val token: ValidityToken, diff --git a/idea/testData/checker/IncDec.fir.kt b/idea/testData/checker/IncDec.fir.kt index aae0f0cc705..139d73e25c2 100644 --- a/idea/testData/checker/IncDec.fir.kt +++ b/idea/testData/checker/IncDec.fir.kt @@ -22,10 +22,10 @@ class WrongIncDec() { fun testWrongIncDec() { var x = WrongIncDec() - x++ - ++x - x-- - --x + x++ + ++x + x-- + --x } class UnitIncDec() { @@ -35,12 +35,12 @@ class UnitIncDec() { fun testUnitIncDec() { var x = UnitIncDec() - x++ - ++x - x-- - --x - x = x++ - x = x-- - x = ++x - x = --x + x++ + ++x + x-- + --x + x = x++ + x = x-- + x = ++x + x = --x }