From 6065095e2486d23fbda804f36ccda653104de8ef Mon Sep 17 00:00:00 2001 From: Dmitry Savvinov Date: Mon, 24 Sep 2018 18:50:00 +0300 Subject: [PATCH] Fix too aggressive data-flow clearing of loop-assigned vars This is effectively a revert of 447c127036b9902de4f9f7f4841684a2a40be3b9, which was an (incorrect) fix for KT-22379. The bug was that we've cleared data-flow info for assigned variables *after* knowledge that loop condition if 'false' was applied (we can claim that if loop has no jump-outs). Therefore, we broke smartcasts in the innocent code like that: var x: Int? = null while (x == null) { x = readPotentiallyNullableInt() } // x should be non-null here Commit reverts that "fix" for 1.3.0 and postpones deprecation until 1.4 KT-22379 Open KT-27084 Fixed --- .../ControlStructureTypingVisitor.java | 16 ++-------------- .../loops/whileNullAssignToSomething.kt | 2 +- .../kotlin/config/LanguageVersionSettings.kt | 3 ++- 3 files changed, 5 insertions(+), 16 deletions(-) diff --git a/compiler/frontend/src/org/jetbrains/kotlin/types/expressions/ControlStructureTypingVisitor.java b/compiler/frontend/src/org/jetbrains/kotlin/types/expressions/ControlStructureTypingVisitor.java index 4c8e3b43c56..212ccd3f53d 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/types/expressions/ControlStructureTypingVisitor.java +++ b/compiler/frontend/src/org/jetbrains/kotlin/types/expressions/ControlStructureTypingVisitor.java @@ -286,16 +286,9 @@ public class ControlStructureTypingVisitor extends ExpressionTypingVisitor { dataFlowInfo = dataFlowInfo.and(loopVisitor.clearDataFlowInfoForAssignedLocalVariables(bodyTypeInfo.getJumpFlowInfo(), components.languageVersionSettings)); } - - DataFlowInfo conservativeInfoAfterLoop = - components.languageVersionSettings.supportsFeature(LanguageFeature.SoundSmartcastFromLoopConditionForLoopAssignedVariables) - ? loopVisitor.clearDataFlowInfoForAssignedLocalVariables(dataFlowInfo, components.languageVersionSettings) - : dataFlowInfo; - - return components.dataFlowAnalyzer .checkType(bodyTypeInfo.replaceType(components.builtIns.getUnitType()), expression, contextWithExpectedType) - .replaceDataFlowInfo(conservativeInfoAfterLoop); + .replaceDataFlowInfo(dataFlowInfo); } private boolean containsJumpOutOfLoop(@NotNull KtExpression expression, ExpressionTypingContext context) { @@ -466,14 +459,9 @@ public class ControlStructureTypingVisitor extends ExpressionTypingVisitor { bodyTypeInfo = loopRangeInfo; } - DataFlowInfo conservativeInfoAfterLoop = - components.languageVersionSettings.supportsFeature(LanguageFeature.SoundSmartcastFromLoopConditionForLoopAssignedVariables) - ? loopVisitor.clearDataFlowInfoForAssignedLocalVariables(loopRangeInfo.getDataFlowInfo(), components.languageVersionSettings) - : loopRangeInfo.getDataFlowInfo(); - return components.dataFlowAnalyzer .checkType(bodyTypeInfo.replaceType(components.builtIns.getUnitType()), expression, contextWithExpectedType) - .replaceDataFlowInfo(conservativeInfoAfterLoop); + .replaceDataFlowInfo(loopRangeInfo.getDataFlowInfo()); } private VariableDescriptor createLoopParameterDescriptor( diff --git a/compiler/testData/diagnostics/tests/smartCasts/loops/whileNullAssignToSomething.kt b/compiler/testData/diagnostics/tests/smartCasts/loops/whileNullAssignToSomething.kt index 44bb1f3ef76..ba9432e1dab 100644 --- a/compiler/testData/diagnostics/tests/smartCasts/loops/whileNullAssignToSomething.kt +++ b/compiler/testData/diagnostics/tests/smartCasts/loops/whileNullAssignToSomething.kt @@ -5,5 +5,5 @@ fun main(args: Array) { if (i == 10) result = "non null" else i++ } - result.length + result.length } \ No newline at end of file diff --git a/compiler/util/src/org/jetbrains/kotlin/config/LanguageVersionSettings.kt b/compiler/util/src/org/jetbrains/kotlin/config/LanguageVersionSettings.kt index 69eae3b4ad8..d8a7f5096e0 100644 --- a/compiler/util/src/org/jetbrains/kotlin/config/LanguageVersionSettings.kt +++ b/compiler/util/src/org/jetbrains/kotlin/config/LanguageVersionSettings.kt @@ -83,7 +83,6 @@ enum class LanguageFeature( NormalizeConstructorCalls(KOTLIN_1_3), StrictJavaNullabilityAssertions(KOTLIN_1_3, kind = BUG_FIX), SoundSmartcastForEnumEntries(KOTLIN_1_3, kind = BUG_FIX), - SoundSmartcastFromLoopConditionForLoopAssignedVariables(KOTLIN_1_3, kind = BUG_FIX), DslMarkerOnFunctionTypeReceiver(KOTLIN_1_4, kind = BUG_FIX), ProhibitErroneousExpressionsInAnnotationsWithUseSiteTargets(KOTLIN_1_3, kind = BUG_FIX), NewCapturedReceiverFieldNamingConvention(KOTLIN_1_3, kind = BUG_FIX), @@ -94,6 +93,8 @@ enum class LanguageFeature( NoConstantValueAttributeForNonConstVals(KOTLIN_1_4, kind = BUG_FIX), ProperVisibilityForCompanionObjectInstanceField(sinceVersion = null, kind = BUG_FIX), + // Temporarily disabled, see KT-27084/KT-22379 + SoundSmartcastFromLoopConditionForLoopAssignedVariables(sinceVersion = null, kind = BUG_FIX), ProperIeee754Comparisons(sinceVersion = null, defaultState = State.DISABLED, kind = BUG_FIX),