diff --git a/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirOldFrontendDiagnosticsTestGenerated.java b/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirOldFrontendDiagnosticsTestGenerated.java index ef209e6a011..7ae3f1bf26a 100644 --- a/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirOldFrontendDiagnosticsTestGenerated.java +++ b/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirOldFrontendDiagnosticsTestGenerated.java @@ -3609,6 +3609,12 @@ public class FirOldFrontendDiagnosticsTestGenerated extends AbstractFirDiagnosti runTest("compiler/testData/diagnostics/tests/cast/FlexibleTargetType.kt"); } + @Test + @TestMetadata("isAlwaysFalse.kt") + public void testIsAlwaysFalse() throws Exception { + runTest("compiler/testData/diagnostics/tests/cast/isAlwaysFalse.kt"); + } + @Test @TestMetadata("IsErasedAllowForDerivedWithOneSubstitutedAndOneSameGeneric.kt") public void testIsErasedAllowForDerivedWithOneSubstitutedAndOneSameGeneric() throws Exception { diff --git a/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirOldFrontendDiagnosticsWithLightTreeTestGenerated.java b/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirOldFrontendDiagnosticsWithLightTreeTestGenerated.java index 8736daf741f..f1fb0b0d323 100644 --- a/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirOldFrontendDiagnosticsWithLightTreeTestGenerated.java +++ b/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirOldFrontendDiagnosticsWithLightTreeTestGenerated.java @@ -3609,6 +3609,12 @@ public class FirOldFrontendDiagnosticsWithLightTreeTestGenerated extends Abstrac runTest("compiler/testData/diagnostics/tests/cast/FlexibleTargetType.kt"); } + @Test + @TestMetadata("isAlwaysFalse.kt") + public void testIsAlwaysFalse() throws Exception { + runTest("compiler/testData/diagnostics/tests/cast/isAlwaysFalse.kt"); + } + @Test @TestMetadata("IsErasedAllowForDerivedWithOneSubstitutedAndOneSameGeneric.kt") public void testIsErasedAllowForDerivedWithOneSubstitutedAndOneSameGeneric() throws Exception { diff --git a/compiler/frontend/src/org/jetbrains/kotlin/types/expressions/PatternMatchingTypingVisitor.kt b/compiler/frontend/src/org/jetbrains/kotlin/types/expressions/PatternMatchingTypingVisitor.kt index 9e1e6bb5a71..4ea4dbe815b 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/types/expressions/PatternMatchingTypingVisitor.kt +++ b/compiler/frontend/src/org/jetbrains/kotlin/types/expressions/PatternMatchingTypingVisitor.kt @@ -43,6 +43,7 @@ import org.jetbrains.kotlin.types.expressions.ControlStructureTypingUtils.* import org.jetbrains.kotlin.types.expressions.typeInfoFactory.createTypeInfo import org.jetbrains.kotlin.types.expressions.typeInfoFactory.noTypeInfo import org.jetbrains.kotlin.types.typeUtil.containsError +import org.jetbrains.kotlin.types.typeUtil.isAnyOrNullableAny import java.util.* class PatternMatchingTypingVisitor internal constructor(facade: ExpressionTypingInternals) : ExpressionTypingVisitor(facade) { @@ -640,9 +641,9 @@ class PatternMatchingTypingVisitor internal constructor(facade: ExpressionTyping assert(element is KtNullableType) { "element must be instance of " + KtNullableType::class.java.name } context.trace.report(Errors.USELESS_NULLABLE_CHECK.on(element as KtNullableType)) } - checkTypeCompatibility(context, targetType, subjectType, typeReferenceAfterIs) + val typesAreCompatible = checkTypeCompatibility(context, targetType, subjectType, typeReferenceAfterIs) - detectRedundantIs(context, subjectType, targetType, isCheck, negated, subjectDataFlowValue) + detectRedundantIs(context, subjectType, targetType, isCheck, negated, subjectDataFlowValue, typesAreCompatible) if (context.languageVersionSettings.supportsFeature(LanguageFeature.ProperCheckAnnotationsTargetInTypeUsePositions)) { components.annotationChecker.check(typeReferenceAfterIs, context.trace) @@ -662,12 +663,24 @@ class PatternMatchingTypingVisitor internal constructor(facade: ExpressionTyping targetType: KotlinType, isCheck: KtElement, negated: Boolean, - subjectDataFlowValue: DataFlowValue + subjectDataFlowValue: DataFlowValue, + typesAreCompatible: Boolean ) { if (subjectType.containsError() || targetType.containsError()) return val possibleTypes = DataFlowAnalyzer.getAllPossibleTypes(subjectType, context, subjectDataFlowValue, context.languageVersionSettings) + + if (typesAreCompatible && !targetType.isError) { + val nonTrivialTypes = possibleTypes.filterNot { it.isAnyOrNullableAny() } + .takeIf { it.isNotEmpty() } + ?: possibleTypes + + if (nonTrivialTypes.none { CastDiagnosticsUtil.isCastPossible(it, targetType, components.platformToKotlinClassMapper) }) { + context.trace.report(USELESS_IS_CHECK.on(isCheck, negated)) + } + } + if (CastDiagnosticsUtil.isRefinementUseless(possibleTypes, targetType, false)) { context.trace.report(Errors.USELESS_IS_CHECK.on(isCheck, !negated)) } @@ -683,11 +696,11 @@ class PatternMatchingTypingVisitor internal constructor(facade: ExpressionTyping type: KotlinType, subjectType: KotlinType, reportErrorOn: KtElement - ) { + ): Boolean { // TODO : Take smart casts into account? if (TypeIntersector.isIntersectionEmpty(type, subjectType)) { context.trace.report(INCOMPATIBLE_TYPES.on(reportErrorOn, type, subjectType)) - return + return false } checkEnumsForCompatibility(context, reportErrorOn, subjectType, type) @@ -696,5 +709,6 @@ class PatternMatchingTypingVisitor internal constructor(facade: ExpressionTyping if (KotlinBuiltIns.isNullableNothing(type) && !TypeUtils.isNullableType(subjectType)) { context.trace.report(SENSELESS_NULL_IN_WHEN.on(reportErrorOn)) } + return true } } diff --git a/compiler/testData/diagnostics/tests/cast/IsRecursionSustainable.kt b/compiler/testData/diagnostics/tests/cast/IsRecursionSustainable.kt index 73faa4af355..bc3b65f5a76 100644 --- a/compiler/testData/diagnostics/tests/cast/IsRecursionSustainable.kt +++ b/compiler/testData/diagnostics/tests/cast/IsRecursionSustainable.kt @@ -2,5 +2,5 @@ open class RecA: RecB() open class RecB: RecA() open class SelfR: SelfR() -fun test(f: SelfR) = f is RecA -fun test(f: RecB) = f is RecA \ No newline at end of file +fun test(f: SelfR) = f is RecA +fun test(f: RecB) = f is RecA diff --git a/compiler/testData/diagnostics/tests/cast/isAlwaysFalse.fir.kt b/compiler/testData/diagnostics/tests/cast/isAlwaysFalse.fir.kt new file mode 100644 index 00000000000..6db19aa1458 --- /dev/null +++ b/compiler/testData/diagnostics/tests/cast/isAlwaysFalse.fir.kt @@ -0,0 +1,69 @@ +abstract class A +abstract class B : A() + +abstract class AS +abstract class BS : AS() + +interface AI +interface BI : AI + +fun test_1(a: A) { + a is A // always true + a is B + + a is AS // always false + a is BS // always false + + a is AI + a is BI +} + +fun test_2(a: A) { + a !is A // always false + a !is B + + a !is AS // always true + a !is BS // always true + + a !is AI + a !is BI +} + +fun test_3(a: Any) { + if (a is A) { + a is A // always true + a is B + + a is AS // always false + a is BS // always false + + a is AI + a is BI + } +} + +fun test_4(a: A) { + when (a) { + is A -> {} // always true + is B -> {} + + is AS -> {} // always false + is BS -> {} // always false + + is AI -> {} + is BI -> {} + } +} + +fun test_5(a: A) { + when (a) { + !is A -> {} // always false + !is B -> {} + + !is AS -> {} // always true + !is BS -> {} // here a may has type AS (by data flow) + + !is AI -> {} + !is BI -> {} + } +} diff --git a/compiler/testData/diagnostics/tests/cast/isAlwaysFalse.kt b/compiler/testData/diagnostics/tests/cast/isAlwaysFalse.kt new file mode 100644 index 00000000000..8813b9ea556 --- /dev/null +++ b/compiler/testData/diagnostics/tests/cast/isAlwaysFalse.kt @@ -0,0 +1,69 @@ +abstract class A +abstract class B : A() + +abstract class AS +abstract class BS : AS() + +interface AI +interface BI : AI + +fun test_1(a: A) { + a is A // always true + a is B + + a is AS // always false + a is BS // always false + + a is AI + a is BI +} + +fun test_2(a: A) { + a !is A // always false + a !is B + + a !is AS // always true + a !is BS // always true + + a !is AI + a !is BI +} + +fun test_3(a: Any) { + if (a is A) { + a is A // always true + a is B + + a is AS // always false + a is BS // always false + + a is AI + a is BI + } +} + +fun test_4(a: A) { + when (a) { + is A -> {} // always true + is B -> {} + + is AS -> {} // always false + is BS -> {} // always false + + is AI -> {} + is BI -> {} + } +} + +fun test_5(a: A) { + when (a) { + !is A -> {} // always false + !is B -> {} + + !is AS -> {} // always true + !is BS -> {} // here a may has type AS (by data flow) + + !is AI -> {} + !is BI -> {} + } +} diff --git a/compiler/testData/diagnostics/tests/cast/isAlwaysFalse.txt b/compiler/testData/diagnostics/tests/cast/isAlwaysFalse.txt new file mode 100644 index 00000000000..4db3603922b --- /dev/null +++ b/compiler/testData/diagnostics/tests/cast/isAlwaysFalse.txt @@ -0,0 +1,48 @@ +package + +public fun test_1(/*0*/ a: A): kotlin.Unit +public fun test_2(/*0*/ a: A): kotlin.Unit +public fun test_3(/*0*/ a: kotlin.Any): kotlin.Unit +public fun test_4(/*0*/ a: A): kotlin.Unit +public fun test_5(/*0*/ a: A): kotlin.Unit + +public abstract class A { + public constructor A() + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String +} + +public interface AI { + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String +} + +public abstract class AS { + public constructor AS() + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String +} + +public abstract class B : A { + public constructor B() + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String +} + +public interface BI : AI { + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String +} + +public abstract class BS : AS { + public constructor BS() + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String +} + diff --git a/compiler/testData/diagnostics/tests/dataFlowInfoTraversal/smartcasts/SmartcastAmbiguitites.kt b/compiler/testData/diagnostics/tests/dataFlowInfoTraversal/smartcasts/SmartcastAmbiguitites.kt index fd62c2ebc16..96a371f1847 100644 --- a/compiler/testData/diagnostics/tests/dataFlowInfoTraversal/smartcasts/SmartcastAmbiguitites.kt +++ b/compiler/testData/diagnostics/tests/dataFlowInfoTraversal/smartcasts/SmartcastAmbiguitites.kt @@ -9,7 +9,7 @@ class C() { fun test(a : Any?) { if (a is B) { - if (a is C) { + if (a is C) { a.bar(); } } diff --git a/compiler/testData/diagnostics/tests/enum/enumSubjectTypeCheck.kt b/compiler/testData/diagnostics/tests/enum/enumSubjectTypeCheck.kt index 5ef20809c8d..8254a0ab915 100644 --- a/compiler/testData/diagnostics/tests/enum/enumSubjectTypeCheck.kt +++ b/compiler/testData/diagnostics/tests/enum/enumSubjectTypeCheck.kt @@ -30,11 +30,11 @@ fun useEn(x: En) = x fun useEn2(x: En2) = x fun bar(x: Any) { - if (x is En && x is En2) { + if (x is En && x is En2) { when (x) { En.A -> useEn(x) En2.D -> useEn2(x) else -> {} } } -} \ No newline at end of file +} diff --git a/compiler/testData/diagnostics/tests/regressions/kt6508.kt b/compiler/testData/diagnostics/tests/regressions/kt6508.kt index 8ac37083d04..edb38065903 100644 --- a/compiler/testData/diagnostics/tests/regressions/kt6508.kt +++ b/compiler/testData/diagnostics/tests/regressions/kt6508.kt @@ -22,4 +22,4 @@ fun String.gah(view:View ?) { if (view is TextView) view else TextView() as foo.TextView -} \ No newline at end of file +} diff --git a/compiler/testData/diagnostics/tests/scopes/stopResolutionOnAmbiguity.kt b/compiler/testData/diagnostics/tests/scopes/stopResolutionOnAmbiguity.kt index e0cb029626f..c7b2321c37f 100644 --- a/compiler/testData/diagnostics/tests/scopes/stopResolutionOnAmbiguity.kt +++ b/compiler/testData/diagnostics/tests/scopes/stopResolutionOnAmbiguity.kt @@ -11,7 +11,7 @@ class C() { fun test(a : Any?) { if (a is B) { - if (a is C) { + if (a is C) { a.bar(); } } diff --git a/compiler/testData/diagnostics/tests/when/intersectionExhaustivenessComplex.kt b/compiler/testData/diagnostics/tests/when/intersectionExhaustivenessComplex.kt index 3c2ad18612a..63c2b1ed217 100644 --- a/compiler/testData/diagnostics/tests/when/intersectionExhaustivenessComplex.kt +++ b/compiler/testData/diagnostics/tests/when/intersectionExhaustivenessComplex.kt @@ -11,7 +11,7 @@ sealed class B { } fun foo(a: A) { - if (a !is B) return + if (a !is B) return when (a) { is A.A1 -> "" diff --git a/compiler/testData/diagnostics/testsWithStdLib/contracts/smartcasts/deeplyNested.kt b/compiler/testData/diagnostics/testsWithStdLib/contracts/smartcasts/deeplyNested.kt index e90d2f1664e..b5e5353608e 100644 --- a/compiler/testData/diagnostics/testsWithStdLib/contracts/smartcasts/deeplyNested.kt +++ b/compiler/testData/diagnostics/testsWithStdLib/contracts/smartcasts/deeplyNested.kt @@ -78,7 +78,7 @@ fun branchedAndNested(x: Any?, y: Any?) { fun br(y: Any?) { - if (myAssert(y is Int) == Unit && myAssert(y is String) == Unit) { + if (myAssert(y is Int) == Unit && myAssert(y is String) == Unit) { y.length y.inc() } @@ -89,7 +89,7 @@ fun branchedAndNestedWithNativeOperators(x: Any?, y: Any?) { equalsTrue(notEqualsNull(nullWhenNotString(x))) // x is String && ( - (myAssert(y is Int) == Unit && myAssert(y is String) == Unit) // y is Int, String + (myAssert(y is Int) == Unit && myAssert(y is String) == Unit) // y is Int, String || equalsTrue(isInt(y) && isString(y)) // y is Int, String ) diff --git a/compiler/testData/diagnostics/testsWithStdLib/contracts/smartcasts/intersectingInfo.kt b/compiler/testData/diagnostics/testsWithStdLib/contracts/smartcasts/intersectingInfo.kt index a2ec7f07bde..91f928dd872 100644 --- a/compiler/testData/diagnostics/testsWithStdLib/contracts/smartcasts/intersectingInfo.kt +++ b/compiler/testData/diagnostics/testsWithStdLib/contracts/smartcasts/intersectingInfo.kt @@ -45,8 +45,8 @@ fun intersectingInfo2(x: Any?, y: Any?) { // of them is absent in each arg of "||"-operator, so they *shouldn't* lead to smartcast if ((isString(x) && !notIsInt(x) && y is String) || - (!notIsString(x) && isString(y) && y is Int) || - (x is String && !notIsInt(y) && x is Int)) { + (!notIsString(x) && isString(y) && y is Int) || + (x is String && !notIsInt(y) && x is Int)) { x.length x.inc() y.length diff --git a/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/DiagnosticTestGenerated.java b/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/DiagnosticTestGenerated.java index 34ef749cadc..b51151d8835 100644 --- a/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/DiagnosticTestGenerated.java +++ b/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/DiagnosticTestGenerated.java @@ -3615,6 +3615,12 @@ public class DiagnosticTestGenerated extends AbstractDiagnosticTest { runTest("compiler/testData/diagnostics/tests/cast/FlexibleTargetType.kt"); } + @Test + @TestMetadata("isAlwaysFalse.kt") + public void testIsAlwaysFalse() throws Exception { + runTest("compiler/testData/diagnostics/tests/cast/isAlwaysFalse.kt"); + } + @Test @TestMetadata("IsErasedAllowForDerivedWithOneSubstitutedAndOneSameGeneric.kt") public void testIsErasedAllowForDerivedWithOneSubstitutedAndOneSameGeneric() throws Exception { diff --git a/compiler/tests-spec/testData/diagnostics/linked/expressions/when-expression/p-2/pos/2.1.kt b/compiler/tests-spec/testData/diagnostics/linked/expressions/when-expression/p-2/pos/2.1.kt index 2647f5bfff6..d4221fb246e 100644 --- a/compiler/tests-spec/testData/diagnostics/linked/expressions/when-expression/p-2/pos/2.1.kt +++ b/compiler/tests-spec/testData/diagnostics/linked/expressions/when-expression/p-2/pos/2.1.kt @@ -77,7 +77,7 @@ fun case_5(value_1: Boolean) { // TESTCASE NUMBER: 6 fun case_6(value_1: Any) { when { - value_1 is Nothing -> {} + value_1 is Nothing -> {} value_1 is Int -> {} value_1 is Boolean -> {} value_1 is String -> {} diff --git a/compiler/tests-spec/testData/diagnostics/notLinked/contracts/analysis/smartcasts/pos/9.kt b/compiler/tests-spec/testData/diagnostics/notLinked/contracts/analysis/smartcasts/pos/9.kt index 5e4c42bd952..c4888e2fd50 100644 --- a/compiler/tests-spec/testData/diagnostics/notLinked/contracts/analysis/smartcasts/pos/9.kt +++ b/compiler/tests-spec/testData/diagnostics/notLinked/contracts/analysis/smartcasts/pos/9.kt @@ -108,7 +108,7 @@ fun case_8(value_1: Any?) { // TESTCASE NUMBER: 9 fun case_9(value_1: Any?) { - if (funWithReturnsFalse(value_1 is String) || funWithReturnsFalse(value_1 is Int)) { + if (funWithReturnsFalse(value_1 is String) || funWithReturnsFalse(value_1 is Int)) { } else { println(value_1.length) diff --git a/compiler/tests-spec/testData/diagnostics/notLinked/contracts/declarations/contractBuilder/effects/returns/neg/6.kt b/compiler/tests-spec/testData/diagnostics/notLinked/contracts/declarations/contractBuilder/effects/returns/neg/6.kt index c6fe07e0d66..7bb62978635 100644 --- a/compiler/tests-spec/testData/diagnostics/notLinked/contracts/declarations/contractBuilder/effects/returns/neg/6.kt +++ b/compiler/tests-spec/testData/diagnostics/notLinked/contracts/declarations/contractBuilder/effects/returns/neg/6.kt @@ -18,8 +18,8 @@ fun Boolean?.case_1(): Boolean { // TESTCASE NUMBER: 2 fun Boolean>T?.case_2(): Boolean { - contract { returns(true) implies (this@case_2 != null && this@case_2 !is Nothing && this@case_2) } - return this != null && this !is Nothing && this + contract { returns(true) implies (this@case_2 != null && this@case_2 !is Nothing && this@case_2) } + return this != null && this !is Nothing && this } // TESTCASE NUMBER: 3 diff --git a/compiler/tests-spec/testData/diagnostics/notLinked/contracts/declarations/contractFunction/neg/2.kt b/compiler/tests-spec/testData/diagnostics/notLinked/contracts/declarations/contractFunction/neg/2.kt index 0552a6e775d..08b9e5c0b2d 100644 --- a/compiler/tests-spec/testData/diagnostics/notLinked/contracts/declarations/contractFunction/neg/2.kt +++ b/compiler/tests-spec/testData/diagnostics/notLinked/contracts/declarations/contractFunction/neg/2.kt @@ -70,13 +70,13 @@ class case_4 : ClassLevel3() { class case_5 : ClassLevel5() { inner class case_5_1 { fun K.case_5_1_1() { - contract { returns() implies (this@case_5_1 !is ClassLevel1 && this@case_5_1 != null || this@case_5 is ClassLevel1 && this@case_5_1_1 is Float) } - if (!(this@case_5_1 !is ClassLevel1 && this@case_5_1 != null || this@case_5 is ClassLevel1 && this is Float)) throw Exception() + contract { returns() implies (this@case_5_1 !is ClassLevel1 && this@case_5_1 != null || this@case_5 is ClassLevel1 && this@case_5_1_1 is Float) } + if (!(this@case_5_1 !is ClassLevel1 && this@case_5_1 != null || this@case_5 is ClassLevel1 && this is Float)) throw Exception() } fun case_5_1_2() { - contract { returns() implies (this@case_5_1 !is ClassLevel1 || this@case_5 is ClassLevel1 || this@case_5_1 == null) } - if (!(this@case_5_1 !is ClassLevel1 || this@case_5 is ClassLevel1 || this@case_5_1 == null)) throw Exception() + contract { returns() implies (this@case_5_1 !is ClassLevel1 || this@case_5 is ClassLevel1 || this@case_5_1 == null) } + if (!(this@case_5_1 !is ClassLevel1 || this@case_5 is ClassLevel1 || this@case_5_1 == null)) throw Exception() } } } diff --git a/compiler/tests-spec/testData/diagnostics/notLinked/dfa/neg/1.kt b/compiler/tests-spec/testData/diagnostics/notLinked/dfa/neg/1.kt index b7769e9c723..26e1a5fe60e 100644 --- a/compiler/tests-spec/testData/diagnostics/notLinked/dfa/neg/1.kt +++ b/compiler/tests-spec/testData/diagnostics/notLinked/dfa/neg/1.kt @@ -14,7 +14,7 @@ // TESTCASE NUMBER: 1 fun case_1(x: Any?) { - if (x != null is Boolean) { + if (x != null is Boolean) { x x.equals(null) x.propT @@ -97,7 +97,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 @@ -151,12 +151,12 @@ fun case_10() { fun case_11(x: TypealiasNullableStringIndirect?, y: TypealiasNullableStringIndirect) { val t: TypealiasNullableStringIndirect = null - if (x == null is Boolean) { + if (x == null is Boolean) { } else { - if (y != null is Boolean == true) { + if (y != null is Boolean == true) { if ((nullableStringProperty == null) !is Boolean) { - if (t != null is Boolean) { + if (t != null is Boolean) { x x.equals(null) x.propT @@ -190,7 +190,7 @@ fun case_12(x: TypealiasNullableStringIndirect, y: TypealiasNullableStringIndire // TESTCASE NUMBER: 13 fun case_13(x: otherpackage.Case13?) = - if ((x == null !is Boolean) !== true) { + if ((x == null !is Boolean) !== true) { throw Exception() } else { x @@ -208,7 +208,7 @@ class Case14 { fun case_14() { val a = Case14() - if (a.x != null !is Boolean !is Boolean) { + if (a.x != null !is Boolean !is Boolean) { if (a.x != null == true) { if (a.x !== null == false) { if (a.x != null == null) { @@ -219,11 +219,11 @@ fun case_14() { if (a.x != null === false) { if (a.x !== null === true) { if ((a.x != null != true) !is Boolean) { - if (a.x != null is Boolean) { - if (a.x != null is Boolean is Boolean) { - if (a.x !== null is Boolean) { - if (a.x != null is Boolean) { - if ((a.x !== null !is Boolean) == false) { + if (a.x != null is Boolean) { + if (a.x != null is Boolean is Boolean) { + if (a.x !== null is Boolean) { + if (a.x != null is Boolean) { + if ((a.x !== null !is Boolean) == false) { a.x a.x.equals(a.x) } @@ -246,7 +246,7 @@ fun case_14() { // TESTCASE NUMBER: 15 fun case_15(x: EmptyObject) { - val t = if (x === null is Boolean is Boolean is Boolean) "" else { + val t = if (x === null is Boolean is Boolean is Boolean) "" else { x x.equals(null) x.propT @@ -264,7 +264,7 @@ fun case_15(x: EmptyObject) { fun case_16() { val x: TypealiasNullableNothing = null - if (x != null !is Boolean !is Boolean !is Boolean !is Boolean !is Boolean) { + if (x != null !is Boolean !is Boolean !is Boolean !is Boolean !is Boolean) { x x.java } @@ -312,7 +312,7 @@ fun case_19(b: Boolean) { } } else null - if (a != null !is Boolean && a.B19 != null is Boolean && a.B19.C19 != null is Boolean && a.B19.C19.D19 != null == null && a.B19.C19.D19.x != null !== null) { + if (a != null !is Boolean && a.B19 != null is Boolean && a.B19.C19 != null is Boolean && a.B19.C19.D19 != null == null && a.B19.C19.D19.x != null !== null) { a.B19.C19.D19.x a.B19.C19.D19.x.equals(null) a.B19.C19.D19.x.propT @@ -338,7 +338,7 @@ fun case_20(b: Boolean) { } } - if (a.B19.C19.D19 !== null !is Boolean) { + if (a.B19.C19.D19 !== null !is Boolean) { .B19..C19..D19.?")!>a.B19.C19.D19 .B19..C19..D19.?")!>a.B19.C19.D19.equals(null) .B19..C19..D19.?")!>a.B19.C19.D19.propT @@ -354,7 +354,7 @@ fun case_20(b: Boolean) { // TESTCASE NUMBER: 21 fun case_21() { - if (EnumClassWithNullableProperty.B.prop_1 !== null is Boolean == true !is Boolean != true) { + if (EnumClassWithNullableProperty.B.prop_1 !== null is Boolean == true !is Boolean != true) { EnumClassWithNullableProperty.B.prop_1 EnumClassWithNullableProperty.B.prop_1.equals(null) EnumClassWithNullableProperty.B.prop_1.propT @@ -370,7 +370,7 @@ fun case_21() { // TESTCASE NUMBER: 22 fun case_22(a: (() -> Unit)?) { - if (a != null !is Boolean) { + if (a != null !is Boolean) { a() a().equals(null) a().propT @@ -386,7 +386,7 @@ fun case_22(a: (() -> Unit)?) { // TESTCASE NUMBER: 23 fun case_23(a: ((Float) -> Int?)?, b: Float?) { - if (a != null !is Boolean && b !== null is Boolean) { + if (a != null !is Boolean && b !== null is Boolean) { val x = a(b) if (x != null) { x @@ -405,7 +405,7 @@ fun case_23(a: ((Float) -> Int?)?, b: Float?) { // TESTCASE NUMBER: 24 fun case_24(a: ((() -> Unit) -> Unit)?, b: (() -> Unit)?) = - if (a !== null is Boolean && b !== null !is Boolean) { + if (a !== null is Boolean && b !== null !is Boolean) { a( kotlin.Unit)?"), TYPE_MISMATCH!>b) a(b) kotlin.Unit)?")!>b.equals(null) @@ -481,4 +481,4 @@ fun case_27() { Object.prop_1.funNullableT() Object.prop_1.funNullableAny() } -} \ No newline at end of file +} diff --git a/compiler/tests-spec/testData/diagnostics/notLinked/dfa/neg/2.kt b/compiler/tests-spec/testData/diagnostics/notLinked/dfa/neg/2.kt index 0017710c915..3f1990b5596 100644 --- a/compiler/tests-spec/testData/diagnostics/notLinked/dfa/neg/2.kt +++ b/compiler/tests-spec/testData/diagnostics/notLinked/dfa/neg/2.kt @@ -12,7 +12,7 @@ // TESTCASE NUMBER: 1 fun case_1(x: Any?) { - if (x is Nothing) { + if (x is Nothing) { x x.inv() } @@ -20,7 +20,7 @@ fun case_1(x: Any?) { // TESTCASE NUMBER: 2 fun case_2(x: Any) { - if (x is Nothing) { + if (x is Nothing) { x x.inv() } @@ -28,7 +28,7 @@ fun case_2(x: Any) { // TESTCASE NUMBER: 3 fun case_3(x: Any?) { - if (x !is Nothing) else { + if (x !is Nothing) else { x x.inv() } @@ -36,7 +36,7 @@ fun case_3(x: Any?) { // TESTCASE NUMBER: 4 fun case_4(x: Any) { - if (x !is Nothing) else { + if (x !is Nothing) else { x x.inv() } @@ -52,7 +52,7 @@ fun case_5(x: Any?) { // TESTCASE NUMBER: 6 fun case_6(x: Any?) { - if (!(x !is Nothing)) { + if (!(x !is Nothing)) { x x.inv() } @@ -60,7 +60,7 @@ fun case_6(x: Any?) { // TESTCASE NUMBER: 7 fun case_7(x: Any) { - if (!(x is Nothing)) else { + if (!(x is Nothing)) else { x x.inv() } @@ -84,7 +84,7 @@ fun case_9(x: Any?) { // TESTCASE NUMBER: 10 fun case_10(x: Any?) { - if (!!(x !is Nothing)) else { + if (!!(x !is Nothing)) else { x x.inv() } @@ -96,4 +96,4 @@ fun case_11(x: Any?) { x x?.inv() } -} \ No newline at end of file +} diff --git a/compiler/tests-spec/testData/diagnostics/notLinked/dfa/neg/3.kt b/compiler/tests-spec/testData/diagnostics/notLinked/dfa/neg/3.kt index 1dd67eb6210..1385b21a2ae 100644 --- a/compiler/tests-spec/testData/diagnostics/notLinked/dfa/neg/3.kt +++ b/compiler/tests-spec/testData/diagnostics/notLinked/dfa/neg/3.kt @@ -13,7 +13,7 @@ // TESTCASE NUMBER: 1 fun case_1(x: Nothing?) { - if (x is Int) { + if (x is Int) { x x.inv() } @@ -29,7 +29,7 @@ fun case_2(x: Nothing) { // TESTCASE NUMBER: 3 fun case_3(x: Nothing?) { - if (x !is Class) else { + if (x !is Class) else { x x.prop_1 } @@ -53,7 +53,7 @@ fun case_5(x: Nothing?) { // TESTCASE NUMBER: 6 fun case_6(x: Nothing?) { - if (!(x !is Object)) { + if (!(x !is Object)) { x x.prop_1 } @@ -85,7 +85,7 @@ fun case_9(x: Nothing?) { // TESTCASE NUMBER: 10 fun case_10(x: Nothing?) { - if (!!(x !is Interface3)) else { + if (!!(x !is Interface3)) else { x x.itest() x.itest3() diff --git a/compiler/tests-spec/testData/diagnostics/notLinked/dfa/pos/68.kt b/compiler/tests-spec/testData/diagnostics/notLinked/dfa/pos/68.kt index a45b4f355bb..58a2a06e10d 100644 --- a/compiler/tests-spec/testData/diagnostics/notLinked/dfa/pos/68.kt +++ b/compiler/tests-spec/testData/diagnostics/notLinked/dfa/pos/68.kt @@ -47,7 +47,7 @@ fun case_4(x: Any?) { // TESTCASE NUMBER: 5 fun case_5(x: Any?) { - if (x as Nothing? is Nothing) { + if (x as Nothing? is Nothing) { x x.inv() } diff --git a/idea/idea-frontend-fir/idea-fir-low-level-api/tests/org/jetbrains/kotlin/idea/fir/low/level/api/diagnostic/compiler/based/DiagnosisCompilerTestFE10TestdataTestGenerated.java b/idea/idea-frontend-fir/idea-fir-low-level-api/tests/org/jetbrains/kotlin/idea/fir/low/level/api/diagnostic/compiler/based/DiagnosisCompilerTestFE10TestdataTestGenerated.java index 9044aa6759e..4cfec42c36b 100644 --- a/idea/idea-frontend-fir/idea-fir-low-level-api/tests/org/jetbrains/kotlin/idea/fir/low/level/api/diagnostic/compiler/based/DiagnosisCompilerTestFE10TestdataTestGenerated.java +++ b/idea/idea-frontend-fir/idea-fir-low-level-api/tests/org/jetbrains/kotlin/idea/fir/low/level/api/diagnostic/compiler/based/DiagnosisCompilerTestFE10TestdataTestGenerated.java @@ -3609,6 +3609,12 @@ public class DiagnosisCompilerTestFE10TestdataTestGenerated extends AbstractDiag runTest("compiler/testData/diagnostics/tests/cast/FlexibleTargetType.kt"); } + @Test + @TestMetadata("isAlwaysFalse.kt") + public void testIsAlwaysFalse() throws Exception { + runTest("compiler/testData/diagnostics/tests/cast/isAlwaysFalse.kt"); + } + @Test @TestMetadata("IsErasedAllowForDerivedWithOneSubstitutedAndOneSameGeneric.kt") public void testIsErasedAllowForDerivedWithOneSubstitutedAndOneSameGeneric() throws Exception {