fixup! [FIR] Ignore some `USELESS_IS_CHECK` in `when`s Still report `USELESS_IS_CHECK` in `when`s with only one branch.
diff --git a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/expression/FirCastOperatorsChecker.kt b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/expression/FirCastOperatorsChecker.kt index 1285b83..fbc0291 100644 --- a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/expression/FirCastOperatorsChecker.kt +++ b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/expression/FirCastOperatorsChecker.kt
@@ -126,7 +126,7 @@ expression.source, FirErrors.USELESS_IS_CHECK, expression.operation != FirOperation.IS, context, ) Applicability.USELESS_IS_CHECK -> when { - !isLastBranchOfExhaustiveWhen(l, context) -> reportOn( + !isLastBranchOfExhaustiveWhen(l, r, context) -> reportOn( expression.source, FirErrors.USELESS_IS_CHECK, expression.operation == FirOperation.IS, context, ) } @@ -140,7 +140,7 @@ } } - private fun isLastBranchOfExhaustiveWhen(l: ArgumentInfo, context: CheckerContext): Boolean { + private fun isLastBranchOfExhaustiveWhen(l: ArgumentInfo, r: ConeKotlinType, context: CheckerContext): Boolean { if (context.containingElements.size < 2) { return false } @@ -151,6 +151,8 @@ && whenExpression.isExhaustive && whenBranch == whenExpression.branches.lastOrNull() // Ensures it's not redundantly exhaustive && !l.argument.resolvedType.isNothing + // Having an exhaustive `when` with only one branch is useless in general + && (whenExpression.branches.size > 1 || l.smartCastTypeInfo.type.equalTypes(r, context.session)) } private fun getImpossibilityDiagnostic(l: TypeInfo, rType: ConeKotlinType, context: CheckerContext) = when {
diff --git a/compiler/testData/diagnostics/tests/sealed/ExhaustiveOnRoot.fir.kt b/compiler/testData/diagnostics/tests/sealed/ExhaustiveOnRoot.fir.kt index d94a8d8..8ee0a9f 100644 --- a/compiler/testData/diagnostics/tests/sealed/ExhaustiveOnRoot.fir.kt +++ b/compiler/testData/diagnostics/tests/sealed/ExhaustiveOnRoot.fir.kt
@@ -20,5 +20,5 @@ fun test3(x: Expr): String = when (x) { - is Stmt -> "stmt" + <!USELESS_IS_CHECK!>is Stmt<!> -> "stmt" } \ No newline at end of file
diff --git a/compiler/testData/diagnostics/tests/when/ExhaustiveSelftype.fir.kt b/compiler/testData/diagnostics/tests/when/ExhaustiveSelftype.fir.kt index 2ab7331..47ccbb0 100644 --- a/compiler/testData/diagnostics/tests/when/ExhaustiveSelftype.fir.kt +++ b/compiler/testData/diagnostics/tests/when/ExhaustiveSelftype.fir.kt
@@ -4,12 +4,12 @@ fun testCharSequence(x: CharSequence): Int { var i = 0 - i += when (x) { is Any -> 1 } + i += when (x) { <!USELESS_IS_CHECK!>is Any<!> -> 1 } i += when (x) { is CharSequence -> 1 } i += <!NO_ELSE_IN_WHEN!>when<!> (x) { is String -> 1 } - i += when (x) { is Any? -> 1 } - i += when (x) { is CharSequence? -> 1 } + i += when (x) { <!USELESS_IS_CHECK!>is Any?<!> -> 1 } + i += when (x) { <!USELESS_IS_CHECK!>is CharSequence?<!> -> 1 } i += <!NO_ELSE_IN_WHEN!>when<!> (x) { is String? -> 1 } return i @@ -22,7 +22,7 @@ i += <!NO_ELSE_IN_WHEN!>when<!> (x) { is CharSequence -> 1 } i += <!NO_ELSE_IN_WHEN!>when<!> (x) { is String -> 1 } - i += when (x) { is Any? -> 1 } + i += when (x) { <!USELESS_IS_CHECK!>is Any?<!> -> 1 } i += when (x) { is CharSequence? -> 1 } i += <!NO_ELSE_IN_WHEN!>when<!> (x) { is String? -> 1 }
diff --git a/compiler/testData/diagnostics/tests/when/nullableSubjectWithIsCheck.fir.kt b/compiler/testData/diagnostics/tests/when/nullableSubjectWithIsCheck.fir.kt index 8954419..776d776 100644 --- a/compiler/testData/diagnostics/tests/when/nullableSubjectWithIsCheck.fir.kt +++ b/compiler/testData/diagnostics/tests/when/nullableSubjectWithIsCheck.fir.kt
@@ -190,5 +190,5 @@ } fun isNullable(a: Int?) = when (a) { - is Number? -> false + <!USELESS_IS_CHECK!>is Number?<!> -> false }