From 263b876e6ed318f2f30fd46e43e7fa2347965efa Mon Sep 17 00:00:00 2001 From: Tianyu Geng Date: Wed, 28 Jul 2021 13:29:37 -0700 Subject: [PATCH] FIR: extends scope of SENSELESS_COMPARISON FE1.0 only reports SENSELESS_COMPARISON if one of the operand is `null`. This change makes FIR reports also in case one of the operand has type `Nothing?`. In addition, fix handling of type alias in ConeTypeContext#isNullableType --- .../diagnostics/FirDiagnosticsList.kt | 2 +- .../fir/analysis/diagnostics/FirErrors.kt | 2 +- .../FirEqualityCompatibilityChecker.kt | 37 +++++++++---------- .../kotlin/fir/types/ConeTypeContext.kt | 4 +- .../ElseOnNullableEnumWithSmartCast.fir.kt | 2 +- .../when-expression/p-6/pos/5.2.fir.kt | 4 +- .../contractBuilder/common/neg/3.fir.kt | 4 +- .../diagnostics/notLinked/dfa/neg/1.fir.kt | 28 +++++++------- .../diagnostics/notLinked/dfa/neg/16.fir.kt | 12 +++--- .../diagnostics/notLinked/dfa/pos/1.fir.kt | 30 +++++++-------- .../diagnostics/notLinked/dfa/pos/3.fir.kt | 14 +++---- .../diagnostics/notLinked/dfa/pos/37.fir.kt | 4 +- .../diagnostics/notLinked/dfa/pos/6.fir.kt | 18 ++++----- .../diagnostics/notLinked/dfa/pos/7.fir.kt | 30 +++++++-------- .../api/fir/diagnostics/KtFirDiagnostics.kt | 2 +- .../fir/diagnostics/KtFirDiagnosticsImpl.kt | 2 +- 16 files changed, 97 insertions(+), 98 deletions(-) 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 492d40c8829..d0f37f3ddd7 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 @@ -948,7 +948,7 @@ object DIAGNOSTICS_LIST : DiagnosticList("FirErrors") { parameter>("reachable") parameter>("unreachable") } - val SENSELESS_COMPARISON by warning { + val SENSELESS_COMPARISON by warning { parameter("expression") parameter("compareResult") } 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 183a6e06a6c..379112c7055 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 @@ -507,7 +507,7 @@ object FirErrors { val VARIABLE_WITH_NO_TYPE_NO_INITIALIZER by error0(SourceElementPositioningStrategies.DECLARATION_NAME) val INITIALIZATION_BEFORE_DECLARATION by error1>() val UNREACHABLE_CODE by warning2, Set>(SourceElementPositioningStrategies.UNREACHABLE_CODE) - val SENSELESS_COMPARISON by warning2() + val SENSELESS_COMPARISON by warning2() val SENSELESS_NULL_IN_WHEN by warning0() // Nullability diff --git a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/expression/FirEqualityCompatibilityChecker.kt b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/expression/FirEqualityCompatibilityChecker.kt index 200b106612b..1183d0e3b44 100644 --- a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/expression/FirEqualityCompatibilityChecker.kt +++ b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/expression/FirEqualityCompatibilityChecker.kt @@ -16,8 +16,6 @@ import org.jetbrains.kotlin.fir.analysis.diagnostics.reportOn import org.jetbrains.kotlin.fir.declarations.FirFile import org.jetbrains.kotlin.fir.declarations.utils.isEnumClass import org.jetbrains.kotlin.fir.expressions.FirEqualityOperatorCall -import org.jetbrains.kotlin.fir.expressions.FirExpression -import org.jetbrains.kotlin.fir.expressions.FirExpressionWithSmartcastToNull import org.jetbrains.kotlin.fir.expressions.FirOperation import org.jetbrains.kotlin.fir.render import org.jetbrains.kotlin.fir.resolve.inference.inferenceComponents @@ -29,21 +27,19 @@ object FirEqualityCompatibilityChecker : FirEqualityOperatorCallChecker() { override fun check(expression: FirEqualityOperatorCall, context: CheckerContext, reporter: DiagnosticReporter) { val arguments = expression.argumentList.arguments if (arguments.size != 2) return - val lExpr = arguments[0] - val rExpr = arguments[1] - checkCompatibility(lExpr, rExpr, context, expression, reporter) - checkSensibleness(lExpr, rExpr, context, expression, reporter) + val lType = arguments[0].typeRef.coneType + val rType = arguments[1].typeRef.coneType + checkCompatibility(lType, rType, context, expression, reporter) + checkSensibleness(lType, rType, context, expression, reporter) } private fun checkCompatibility( - lExpr: FirExpression, - rExpr: FirExpression, + lType: ConeKotlinType, + rType: ConeKotlinType, context: CheckerContext, expression: FirEqualityOperatorCall, reporter: DiagnosticReporter ) { - val lType = lExpr.typeRef.coneType - val rType = rExpr.typeRef.coneType // If one of the type is already `Nothing?`, we skip reporting further comparison. This is to allow comparing with `null`, which has // type `Nothing?` if (lType.isNullableNothing || rType.isNullableNothing) return @@ -115,32 +111,33 @@ object FirEqualityCompatibilityChecker : FirEqualityOperatorCallChecker() { } private fun checkSensibleness( - lExpr: FirExpression, - rExpr: FirExpression, + lType: ConeKotlinType, + rType: ConeKotlinType, context: CheckerContext, expression: FirEqualityOperatorCall, reporter: DiagnosticReporter ) { - val expressionComparedWithNull = when { - lExpr.isNullLiteral -> rExpr - rExpr.isNullLiteral -> lExpr + val type = when { + rType.isNullableNothing -> lType + lType.isNullableNothing -> rType else -> return } - val type = expressionComparedWithNull.typeRef.coneType if (type is ConeKotlinErrorType) return val isPositiveCompare = expression.operation == FirOperation.EQ || expression.operation == FirOperation.IDENTITY val compareResult = with(context.session.typeContext) { when { // `null` literal has type `Nothing?` - type.isNullableNothing || (expressionComparedWithNull is FirExpressionWithSmartcastToNull && expressionComparedWithNull.isStable) -> isPositiveCompare + type.isNullableNothing -> isPositiveCompare !type.isNullableType() -> !isPositiveCompare else -> return } } - if (expression.source?.elementType == KtNodeTypes.BINARY_EXPRESSION) { - reporter.reportOn(expression.source, FirErrors.SENSELESS_COMPARISON, expression, compareResult, context) - } else { + // We only report `SENSELESS_NULL_IN_WHEN` if `lType = type` because `lType` is the type of the when subject. This diagnostic is + // only intended for cases where the branch condition contains a null. + if (expression.source?.elementType != KtNodeTypes.BINARY_EXPRESSION && type === lType) { reporter.reportOn(expression.source, FirErrors.SENSELESS_NULL_IN_WHEN, context) + } else { + reporter.reportOn(expression.source, FirErrors.SENSELESS_COMPARISON, expression, compareResult, context) } } } diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/types/ConeTypeContext.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/types/ConeTypeContext.kt index 31eddfdb4ab..e6dd7c8d967 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/types/ConeTypeContext.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/types/ConeTypeContext.kt @@ -16,15 +16,16 @@ import org.jetbrains.kotlin.fir.expressions.FirNamedArgumentExpression import org.jetbrains.kotlin.fir.expressions.FirVarargArgumentsExpression import org.jetbrains.kotlin.fir.expressions.arguments import org.jetbrains.kotlin.fir.resolve.correspondingSupertypesCache +import org.jetbrains.kotlin.fir.resolve.directExpansionType import org.jetbrains.kotlin.fir.resolve.fullyExpandedType import org.jetbrains.kotlin.fir.resolve.inference.inferenceComponents import org.jetbrains.kotlin.fir.resolve.substitution.ConeSubstitutor import org.jetbrains.kotlin.fir.resolve.substitution.substitutorByMap import org.jetbrains.kotlin.fir.resolve.toSymbol import org.jetbrains.kotlin.fir.resolve.transformers.body.resolve.firUnsafe -import org.jetbrains.kotlin.fir.symbols.ensureResolved import org.jetbrains.kotlin.fir.symbols.ConeClassLikeLookupTag import org.jetbrains.kotlin.fir.symbols.ConeTypeParameterLookupTag +import org.jetbrains.kotlin.fir.symbols.ensureResolved import org.jetbrains.kotlin.fir.symbols.impl.* import org.jetbrains.kotlin.name.FqName import org.jetbrains.kotlin.name.FqNameUnsafe @@ -443,6 +444,7 @@ interface ConeTypeContext : TypeSystemContext, TypeSystemOptimizationContext, Ty } } is ConeIntersectionType -> intersectedTypes.all { it.isNullableType() } + is ConeClassLikeType -> directExpansionType(session)?.isNullableType() ?: false else -> false } } diff --git a/compiler/testData/diagnostics/tests/when/ElseOnNullableEnumWithSmartCast.fir.kt b/compiler/testData/diagnostics/tests/when/ElseOnNullableEnumWithSmartCast.fir.kt index 5c9fb47e6d2..8ef6944f6b0 100644 --- a/compiler/testData/diagnostics/tests/when/ElseOnNullableEnumWithSmartCast.fir.kt +++ b/compiler/testData/diagnostics/tests/when/ElseOnNullableEnumWithSmartCast.fir.kt @@ -15,6 +15,6 @@ fun foo(e: E, something: Any?): Int { return when (e) { E.A -> 1 E.B -> 2 - something -> 3 + something -> 3 } } diff --git a/compiler/tests-spec/testData/diagnostics/linked/expressions/when-expression/p-6/pos/5.2.fir.kt b/compiler/tests-spec/testData/diagnostics/linked/expressions/when-expression/p-6/pos/5.2.fir.kt index b56bd3c7c46..a938a70e4ba 100644 --- a/compiler/tests-spec/testData/diagnostics/linked/expressions/when-expression/p-6/pos/5.2.fir.kt +++ b/compiler/tests-spec/testData/diagnostics/linked/expressions/when-expression/p-6/pos/5.2.fir.kt @@ -225,8 +225,8 @@ fun case_23(value_1: Nothing) { // TESTCASE NUMBER: 24 fun case_24(value_1: Nothing?) = when (value_1) { - throw Exception(), return "" -> "" - null, return return return "", throw throw throw Exception() -> "" + throw Exception(), return "" -> "" + null, return return return "", throw throw throw Exception() -> "" else -> "" } diff --git a/compiler/tests-spec/testData/diagnostics/notLinked/contracts/declarations/contractBuilder/common/neg/3.fir.kt b/compiler/tests-spec/testData/diagnostics/notLinked/contracts/declarations/contractBuilder/common/neg/3.fir.kt index f9988a01f6b..c6d637546ba 100644 --- a/compiler/tests-spec/testData/diagnostics/notLinked/contracts/declarations/contractBuilder/common/neg/3.fir.kt +++ b/compiler/tests-spec/testData/diagnostics/notLinked/contracts/declarations/contractBuilder/common/neg/3.fir.kt @@ -23,8 +23,8 @@ fun case_3(value_1: String?, value_2: Boolean): Boolean { // TESTCASE NUMBER: 4 fun case_4(value_1: Nothing?, value_2: Boolean?): Boolean? { - contract { returns(null) implies (value_1 == null || value_2 != null || value_2 == false) } - return if (value_1 == null || value_2 != null || value_2 == false) null else true + contract { returns(null) implies (value_1 == null || value_2 != null || value_2 == false) } + return if (value_1 == null || value_2 != null || value_2 == false) null else true } // TESTCASE NUMBER: 5 diff --git a/compiler/tests-spec/testData/diagnostics/notLinked/dfa/neg/1.fir.kt b/compiler/tests-spec/testData/diagnostics/notLinked/dfa/neg/1.fir.kt index fda4d8fd56b..428c2b20023 100644 --- a/compiler/tests-spec/testData/diagnostics/notLinked/dfa/neg/1.fir.kt +++ b/compiler/tests-spec/testData/diagnostics/notLinked/dfa/neg/1.fir.kt @@ -87,7 +87,7 @@ fun case_6(x: EmptyClass?) { // TESTCASE NUMBER: 7 fun case_7() { - if (nullableNumberProperty != null || nullableNumberProperty != null is Boolean) { + if (nullableNumberProperty != null || nullableNumberProperty != null is Boolean) { nullableNumberProperty nullableNumberProperty.equals(null) nullableNumberProperty.propT @@ -103,8 +103,8 @@ fun case_7() { // TESTCASE NUMBER: 8 fun case_8(x: TypealiasNullableString) { - if (x !== null === null && x != null != null) x.get(0) - if (x !== null != null && x != null === null) x.get(0) + if (x !== null === null && x != null != null) x.get(0) + if (x !== null != null && x != null === null) x.get(0) } // TESTCASE NUMBER: 9 @@ -165,17 +165,17 @@ fun case_11(x: TypealiasNullableStringIndirect?, y: TypealiasNullableStringIndir // TESTCASE NUMBER: 12 fun case_12(x: TypealiasNullableStringIndirect, y: TypealiasNullableStringIndirect) = - if ((x == null) !is Boolean === false) "1" - else if ((y === null !== null) is Boolean) x - else if (y === null != null) x.equals(null) - else if (y === null != null) x.propT - else if (y === null != null) x.propAny - else if (y === null != null) x.propNullableT - else if (y === null != null) x.propNullableAny - else if (y === null != null) x.funT() - else if (y === null != null) x.funAny() - else if (y === null != null) x.funNullableT() - else if (y === null != null) x.funNullableAny() + if ((x == null) !is Boolean === false) "1" + else if ((y === null !== null) is Boolean) x + else if (y === null != null) x.equals(null) + else if (y === null != null) x.propT + else if (y === null != null) x.propAny + else if (y === null != null) x.propNullableT + else if (y === null != null) x.propNullableAny + else if (y === null != null) x.funT() + else if (y === null != null) x.funAny() + else if (y === null != null) x.funNullableT() + else if (y === null != null) x.funNullableAny() else "-1" // TESTCASE NUMBER: 13 diff --git a/compiler/tests-spec/testData/diagnostics/notLinked/dfa/neg/16.fir.kt b/compiler/tests-spec/testData/diagnostics/notLinked/dfa/neg/16.fir.kt index 90998c0e058..9a020277170 100644 --- a/compiler/tests-spec/testData/diagnostics/notLinked/dfa/neg/16.fir.kt +++ b/compiler/tests-spec/testData/diagnostics/notLinked/dfa/neg/16.fir.kt @@ -9,7 +9,7 @@ */ fun case_1(x: ClassWithCustomEquals) { val y = null - if (x == y) { + if (x == y) { x x.inv() } @@ -29,7 +29,7 @@ fun case_2(x: ClassWithCustomEquals) { * ISSUES: KT-28243 */ fun case_3(x: ClassWithCustomEquals, y: Nothing?) { - if (x == y) { + if (x == y) { x x.inv() } @@ -42,7 +42,7 @@ fun case_3(x: ClassWithCustomEquals, y: Nothing?) { */ fun case_4(x: ClassWithCustomEquals) { val y = null - if (y == x) { + if (y == x) { x x.inv() } @@ -54,7 +54,7 @@ fun case_4(x: ClassWithCustomEquals) { * ISSUES: KT-28243 */ fun case_5(x: ClassWithCustomEquals, y: Nothing?) { - if (y == x) { + if (y == x) { x x.inv() } @@ -67,7 +67,7 @@ fun case_5(x: ClassWithCustomEquals, y: Nothing?) { */ fun case_6(x: ClassWithCustomEquals) { val y = null - if (x == y == true) { + if (x == y == true) { x x.inv() } @@ -87,7 +87,7 @@ fun case_7(x: ClassWithCustomEquals) { * ISSUES: KT-28243 */ fun case_8(x: ClassWithCustomEquals, y: Nothing?) { - if (!(y == x) == false) { + if (!(y == x) == false) { x x.inv() } diff --git a/compiler/tests-spec/testData/diagnostics/notLinked/dfa/pos/1.fir.kt b/compiler/tests-spec/testData/diagnostics/notLinked/dfa/pos/1.fir.kt index 56daadcf095..a998c86a7e3 100644 --- a/compiler/tests-spec/testData/diagnostics/notLinked/dfa/pos/1.fir.kt +++ b/compiler/tests-spec/testData/diagnostics/notLinked/dfa/pos/1.fir.kt @@ -138,16 +138,16 @@ fun case_7() { // TESTCASE NUMBER: 8 fun case_8(x: TypealiasNullableString) { - if (x !== null && x != null) x - if (x !== null && x != null) x.equals(null) - if (x !== null && x != null) x.propT - if (x !== null && x != null) x.propAny - if (x !== null && x != null) x.propNullableT - if (x !== null && x != null) x.propNullableAny - if (x !== null && x != null) x.funT() - if (x !== null && x != null) x.funAny() - if (x !== null && x != null) x.funNullableT() - if (x !== null && x != null) x.funNullableAny() + if (x !== null && x != null) x + if (x !== null && x != null) x.equals(null) + if (x !== null && x != null) x.propT + if (x !== null && x != null) x.propAny + if (x !== null && x != null) x.propNullableT + if (x !== null && x != null) x.propNullableAny + if (x !== null && x != null) x.funT() + if (x !== null && x != null) x.funAny() + if (x !== null && x != null) x.funNullableT() + if (x !== null && x != null) x.funNullableAny() } // TESTCASE NUMBER: 9 @@ -195,9 +195,9 @@ fun case_11(x: TypealiasNullableStringIndirect?, y: TypealiasNullableStringIndir if (x == null) { } else { - if (y != null) { + if (y != null) { if (nullableStringProperty == null) { - if (t != null) { + if (t != null) { x x.equals(null) x.propT @@ -216,8 +216,8 @@ fun case_11(x: TypealiasNullableStringIndirect?, y: TypealiasNullableStringIndir // TESTCASE NUMBER: 12 fun case_12(x: TypealiasNullableStringIndirect, y: TypealiasNullableStringIndirect) = - if (x == null) "1" -else if (y === null) x + if (x == null) "1" +else if (y === null) x else if (y === null) x.equals(null) else if (y === null) x.propT else if (y === null) x.propAny @@ -321,7 +321,7 @@ fun case_15(x: EmptyObject) { fun case_16() { val x: TypealiasNullableNothing = null - if (x != null) { + if (x != null) { x } } diff --git a/compiler/tests-spec/testData/diagnostics/notLinked/dfa/pos/3.fir.kt b/compiler/tests-spec/testData/diagnostics/notLinked/dfa/pos/3.fir.kt index 5e34fbdb736..f2cde2ca2cd 100644 --- a/compiler/tests-spec/testData/diagnostics/notLinked/dfa/pos/3.fir.kt +++ b/compiler/tests-spec/testData/diagnostics/notLinked/dfa/pos/3.fir.kt @@ -67,7 +67,7 @@ fun case_7() { // TESTCASE NUMBER: 8 fun case_8(x: TypealiasNullableString) { - if (x == null && x == null) + if (x == null && x == null) x } @@ -102,9 +102,9 @@ fun case_11(x: TypealiasNullableString?, y: TypealiasNullableString) { if (x != null) { } else { - if (y == null) { + if (y == null) { if (nullableStringProperty != null) { - if (z == null) { + if (z == null) { x } } @@ -113,8 +113,8 @@ fun case_11(x: TypealiasNullableString?, y: TypealiasNullableString) { } // TESTCASE NUMBER: 12 -fun case_12(x: TypealiasNullableString, y: TypealiasNullableString) = if (x != null && true && true && true) "1" - else if (y != null) x +fun case_12(x: TypealiasNullableString, y: TypealiasNullableString) = if (x != null && true && true && true) "1" + else if (y != null) x else "-1" // TESTCASE NUMBER: 13 @@ -171,7 +171,7 @@ fun case_14() { // TESTCASE NUMBER: 15 fun case_15(x: TypealiasNullableString) { - val t = if (x != null) "" else { + val t = if (x != null) "" else { x } } @@ -180,7 +180,7 @@ fun case_15(x: TypealiasNullableString) { fun case_16() { val x: TypealiasNullableNothing = null - if (x == null || false || false || false) { + if (x == null || false || false || false) { x } } diff --git a/compiler/tests-spec/testData/diagnostics/notLinked/dfa/pos/37.fir.kt b/compiler/tests-spec/testData/diagnostics/notLinked/dfa/pos/37.fir.kt index e47c015aded..d58cfcb56da 100644 --- a/compiler/tests-spec/testData/diagnostics/notLinked/dfa/pos/37.fir.kt +++ b/compiler/tests-spec/testData/diagnostics/notLinked/dfa/pos/37.fir.kt @@ -196,10 +196,10 @@ fun case_17(x: Boolean?, y: Boolean?) { true -> x!! false -> x!! null -> if (true) if (true) if (true) if (true) if (true) when (y) { - true -> when (y) { + true -> when (y) { else -> if (true) if (true) if (true) if (true) if (true) x!! else x!! else x!! else x!! else x!! else x!! } - false -> x!! + false -> x!! null -> if (true) if (true) if (true) if (true) if (true) x!! else x!! else x!! else x!! else x!! else x!! } else x!! else x!! else x!! else x!! else x!! } diff --git a/compiler/tests-spec/testData/diagnostics/notLinked/dfa/pos/6.fir.kt b/compiler/tests-spec/testData/diagnostics/notLinked/dfa/pos/6.fir.kt index 79c6bd0f599..34217d16672 100644 --- a/compiler/tests-spec/testData/diagnostics/notLinked/dfa/pos/6.fir.kt +++ b/compiler/tests-spec/testData/diagnostics/notLinked/dfa/pos/6.fir.kt @@ -38,7 +38,7 @@ fun case_1(x: Any?) { */ fun case_2(x: Nothing?) { val y = null - if (x !== y) { + if (x !== y) { x x.hashCode() } @@ -221,7 +221,7 @@ fun case_11(x: TypealiasNullableString?, y: TypealiasNullableString) { // TESTCASE NUMBER: 12 fun case_12(x: TypealiasNullableString, y: TypealiasNullableString, z1: Nothing?, z2: Nothing?) = if (x == z1 || x == z2) "1" - else if (y === z1 && y == z2) { + else if (y === z1 && y == z2) { x x.equals(null) x.propT @@ -281,7 +281,7 @@ fun case_14() { // TESTCASE NUMBER: 15 fun case_15(x: TypealiasNullableString) { val y = null - val z = if (x === null || y == x && x === y || null === x) "" else { + val z = if (x === null || y == x && x === y || null === x) "" else { x x.equals(null) x.propT @@ -677,7 +677,7 @@ fun case_33(a: ((Float) -> Int?)?, b: Float?, c: Boolean?) { fun case_34(z1: Boolean?) { var z = null - if (true && true && true && true && EnumClassWithNullableProperty.A.prop_1 != implicitNullableNothingProperty && EnumClassWithNullableProperty.A.prop_1 !== null && EnumClassWithNullableProperty.A.prop_1 !== z || z1 != implicitNullableNothingProperty || z1!! && true && true) { + if (true && true && true && true && EnumClassWithNullableProperty.A.prop_1 != implicitNullableNothingProperty && EnumClassWithNullableProperty.A.prop_1 !== null && EnumClassWithNullableProperty.A.prop_1 !== z || z1 != implicitNullableNothingProperty || z1!! && true && true) { } else { EnumClassWithNullableProperty.A.prop_1 @@ -712,7 +712,7 @@ fun case_35(a: DeepObject.A.B.C.D.E.F.G.J?) { fun case_36(x: Any) { var z = null - if (x == z) { + if (x == z) { x x.java } @@ -720,7 +720,7 @@ fun case_36(x: Any) { // TESTCASE NUMBER: 37 fun case_37(x: Nothing?, y: Nothing?) { - if (x == y) { + if (x == y) { x x.hashCode() } @@ -733,7 +733,7 @@ fun case_37(x: Nothing?, y: Nothing?) { fun case_38() { val z = null - if (Object.prop_2 != z) + if (Object.prop_2 != z) else { Object.prop_2 Object.prop_2.java @@ -771,7 +771,7 @@ fun case_41(x: EmptyClass?, z: Nothing?) { // TESTCASE NUMBER: 42 fun case_42() { - if (EmptyObject == nullableNothingProperty || EmptyObject === nullableNothingProperty) { + if (EmptyObject == nullableNothingProperty || EmptyObject === nullableNothingProperty) { EmptyObject EmptyObject.equals(null) EmptyObject.propT @@ -992,7 +992,7 @@ fun case_56() { fun case_57(a: (() -> Unit)) { var z = null - if (a == z) { + if (a == z) { ")!>a ")!>a.java } diff --git a/compiler/tests-spec/testData/diagnostics/notLinked/dfa/pos/7.fir.kt b/compiler/tests-spec/testData/diagnostics/notLinked/dfa/pos/7.fir.kt index 7f5871e7419..0fb144585f9 100644 --- a/compiler/tests-spec/testData/diagnostics/notLinked/dfa/pos/7.fir.kt +++ b/compiler/tests-spec/testData/diagnostics/notLinked/dfa/pos/7.fir.kt @@ -192,9 +192,9 @@ fun case_11(x: TypealiasNullableString?, y: TypealiasNullableString) { } else { if (x != null) { - if (y != null || y != null) { + if (y != null || y != null) { if (stringProperty == null && nullableNothingProperty == null) { - if (t != null || t != null) { + if (t != null || t != null) { x x.equals(null) x.propT @@ -213,8 +213,8 @@ fun case_11(x: TypealiasNullableString?, y: TypealiasNullableString) { } // TESTCASE NUMBER: 12 -fun case_12(x: TypealiasNullableString, y: TypealiasNullableString) = if (x == null) "1" - else if (y === null || y === null) { +fun case_12(x: TypealiasNullableString, y: TypealiasNullableString) = if (x == null) "1" + else if (y === null || y === null) { x.equals(null) x.propT x.propAny @@ -229,7 +229,7 @@ fun case_12(x: TypealiasNullableString, y: TypealiasNullableString) = if (x == null || x === y) { + if (x == null || x === y) { throw Exception() } else { x.equals(null) @@ -247,7 +247,7 @@ fun case_13(x: orherpackage.EmptyClass13?, y: Nothing?) = // TESTCASE NUMBER: 14 fun case_14() { val a = Class() - if (a.prop_6 != a.prop_7) { + if (a.prop_6 != a.prop_7) { a.prop_6 a.prop_6.equals(null) a.prop_6.propT @@ -264,7 +264,7 @@ fun case_14() { // TESTCASE NUMBER: 15 fun case_15(x: TypealiasString?) { var y = null - val t = if (x === null || x == y && x === y) "" else { + val t = if (x === null || x == y && x === y) "" else { x.equals(null) x.propT x.propAny @@ -290,7 +290,7 @@ fun case_16() { } // TESTCASE NUMBER: 17 -val case_17 = if (nullableIntProperty == null || nullableNothingProperty === nullableIntProperty) 0 else { +val case_17 = if (nullableIntProperty == null || nullableNothingProperty === nullableIntProperty) 0 else { nullableIntProperty.equals(null) nullableIntProperty.propT nullableIntProperty.propAny @@ -309,7 +309,7 @@ val case_17 = if (nullableIntPropert * ISSUES: KT-28328 */ fun case_18(a: DeepObject.A.B.C.D.E.F.G.J?, b: Nothing?) { - if (a != null || b !== a || false) { + if (a != null || b !== a || false) { a a.equals(null) a.propT @@ -371,7 +371,7 @@ fun case_20(b: Boolean) { } } - if (a.B19.C19.D19 !== null || a.y != a.B19.C19.D19) { + if (a.B19.C19.D19 !== null || a.y != a.B19.C19.D19) { a.B19.C19.D19 a.B19.C19.D19.equals(null) a.B19.C19.D19.propT @@ -388,7 +388,7 @@ fun case_20(b: Boolean) { // TESTCASE NUMBER: 21 fun case_21() { val y = null - if (EnumClassWithNullableProperty.A.prop_1 !== null && y != EnumClassWithNullableProperty.A.prop_1) { + if (EnumClassWithNullableProperty.A.prop_1 !== null && y != EnumClassWithNullableProperty.A.prop_1) { EnumClassWithNullableProperty.A.prop_1 EnumClassWithNullableProperty.A.prop_1.equals(null) EnumClassWithNullableProperty.A.prop_1.propT @@ -405,7 +405,7 @@ fun case_21() { // TESTCASE NUMBER: 22 fun case_22(a: (() -> Unit)?) { var y = null - if (a != null || y != a) { + if (a != null || y != a) { a() ?")!>a.equals(null) ?")!>a.propT @@ -423,7 +423,7 @@ fun case_22(a: (() -> Unit)?) { fun case_23(a: ((Float) -> Int?)?, b: Float?, c: Nothing?) { if (a != null && b !== null || a != c && b !== c) { val x = a(b) - if (x != null || c !== x) { + if (x != null || c !== x) { x x.equals(null) x.propT @@ -473,7 +473,7 @@ fun case_25(b: Boolean) { val y = if (b) x else null - if (y !== null || x()!!.b != y) { + if (y !== null || x()!!.b != y) { if (x()!!.b != y) { val z = ?")!>y() @@ -516,7 +516,7 @@ fun case_26(a: ((Float) -> Int?)?, b: Float?) { // TESTCASE NUMBER: 27 fun case_27(y: Nothing?) { - if (Object.prop_1 == null == true == true == true == true == true == true == true == true == true == true == true == true == true == true || y == Object.prop_1 == true == true == true == false == false) + if (Object.prop_1 == null == true == true == true == true == true == true == true == true == true == true == true == true == true == true || y == Object.prop_1 == true == true == true == false == false) else { Object.prop_1 Object.prop_1.equals(null) 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 4747ce5a85e..f6ae724659b 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 @@ -1825,7 +1825,7 @@ sealed class KtFirDiagnostic : KtDiagnosticWithPsi { abstract val unreachable: List } - abstract class SenselessComparison : KtFirDiagnostic() { + abstract class SenselessComparison : KtFirDiagnostic() { override val diagnosticClass get() = SenselessComparison::class abstract val expression: KtExpression abstract val compareResult: Boolean 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 eebb58af85f..06f45adab48 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 @@ -2944,7 +2944,7 @@ internal class SenselessComparisonImpl( override val compareResult: Boolean, firDiagnostic: FirPsiDiagnostic, override val token: ValidityToken, -) : KtFirDiagnostic.SenselessComparison(), KtAbstractFirDiagnostic { +) : KtFirDiagnostic.SenselessComparison(), KtAbstractFirDiagnostic { override val firDiagnostic: FirPsiDiagnostic by weakRef(firDiagnostic) }