diff --git a/compiler/frontend/src/org/jetbrains/kotlin/types/expressions/DataFlowAnalyzer.java b/compiler/frontend/src/org/jetbrains/kotlin/types/expressions/DataFlowAnalyzer.java index 80d6adf55d4..b805fcc9ec2 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/types/expressions/DataFlowAnalyzer.java +++ b/compiler/frontend/src/org/jetbrains/kotlin/types/expressions/DataFlowAnalyzer.java @@ -85,8 +85,11 @@ public class DataFlowAnalyzer { DataFlowInfo dataFlowInfo = extractDataFlowInfoFromCondition(expression.getLeft(), conditionValue, context); KtExpression expressionRight = expression.getRight(); if (expressionRight != null) { - DataFlowInfo rightInfo = extractDataFlowInfoFromCondition(expressionRight, conditionValue, context); boolean and = operationToken == KtTokens.ANDAND; + DataFlowInfo rightInfo = extractDataFlowInfoFromCondition( + expressionRight, conditionValue, + and == conditionValue ? context.replaceDataFlowInfo(dataFlowInfo) : context + ); if (and == conditionValue) { // this means: and && conditionValue || !and && !conditionValue dataFlowInfo = dataFlowInfo.and(rightInfo); } diff --git a/compiler/testData/diagnostics/tests/smartCasts/comparisonUnderAnd.kt b/compiler/testData/diagnostics/tests/smartCasts/comparisonUnderAnd.kt new file mode 100644 index 00000000000..c797a019214 --- /dev/null +++ b/compiler/testData/diagnostics/tests/smartCasts/comparisonUnderAnd.kt @@ -0,0 +1,38 @@ +fun foo(x : String?, y : String?) { + if (y != null && x == y) { + // Both not null + x.length + y.length + } + else { + x.length + y.length + } + if (y != null || x == y) { + x.length + y.length + } + else { + // y == null but x != y + x.length + y.length + } + if (y == null && x != y) { + // y == null but x != y + x.length + y.length + } + else { + x.length + y.length + } + if (y == null || x != y) { + x.length + y.length + } + else { + // Both not null + x.length + y.length + } +} \ No newline at end of file diff --git a/compiler/testData/diagnostics/tests/smartCasts/comparisonUnderAnd.txt b/compiler/testData/diagnostics/tests/smartCasts/comparisonUnderAnd.txt new file mode 100644 index 00000000000..c752ca6226b --- /dev/null +++ b/compiler/testData/diagnostics/tests/smartCasts/comparisonUnderAnd.txt @@ -0,0 +1,3 @@ +package + +public fun foo(/*0*/ x: kotlin.String?, /*1*/ y: kotlin.String?): kotlin.Unit diff --git a/compiler/testData/diagnostics/tests/smartCasts/complexComparison.kt b/compiler/testData/diagnostics/tests/smartCasts/complexComparison.kt new file mode 100644 index 00000000000..f9d0d54bc81 --- /dev/null +++ b/compiler/testData/diagnostics/tests/smartCasts/complexComparison.kt @@ -0,0 +1,22 @@ +fun foo(x: String?, y: String?, z: String?, w: String?) { + if (x != null && y != null && (x == z || y == z)) + z.length + else + z.length + if (x != null || y != null || (x != z && y != z)) + z.length + else + z.length + if (x == null || y == null || (x != z && y != z)) + z.length + else + z.length + if (x != null && y == x && z == y && w == z) + w.length + else + w.length + if ((x != null && y == x) || (z != null && y == z)) + y.length + else + y.length +} \ No newline at end of file diff --git a/compiler/testData/diagnostics/tests/smartCasts/complexComparison.txt b/compiler/testData/diagnostics/tests/smartCasts/complexComparison.txt new file mode 100644 index 00000000000..b935bc5fd2e --- /dev/null +++ b/compiler/testData/diagnostics/tests/smartCasts/complexComparison.txt @@ -0,0 +1,3 @@ +package + +public fun foo(/*0*/ x: kotlin.String?, /*1*/ y: kotlin.String?, /*2*/ z: kotlin.String?, /*3*/ w: kotlin.String?): kotlin.Unit diff --git a/compiler/tests/org/jetbrains/kotlin/checkers/JetDiagnosticsTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/checkers/JetDiagnosticsTestGenerated.java index 3373ae214f1..e87ff1a0553 100644 --- a/compiler/tests/org/jetbrains/kotlin/checkers/JetDiagnosticsTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/checkers/JetDiagnosticsTestGenerated.java @@ -14298,6 +14298,18 @@ public class JetDiagnosticsTestGenerated extends AbstractJetDiagnosticsTest { doTest(fileName); } + @TestMetadata("comparisonUnderAnd.kt") + public void testComparisonUnderAnd() throws Exception { + String fileName = JetTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/smartCasts/comparisonUnderAnd.kt"); + doTest(fileName); + } + + @TestMetadata("complexComparison.kt") + public void testComplexComparison() throws Exception { + String fileName = JetTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/smartCasts/complexComparison.kt"); + doTest(fileName); + } + @TestMetadata("dataFlowInfoForArguments.kt") public void testDataFlowInfoForArguments() throws Exception { String fileName = JetTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/smartCasts/dataFlowInfoForArguments.kt");