From 62edf29cbfea3d8080baa19d0fe3b685229a030d Mon Sep 17 00:00:00 2001 From: Dmitry Savvinov Date: Mon, 1 Oct 2018 14:16:36 +0300 Subject: [PATCH] Use DataFlowValue instead of Descriptor for equality of ESDataFlowValue Equality of those values is crucial for intersecting data-flow info coming from expressions like: 'this.x != null || other.x != null'. Using 'ValueDescriptor' for equality is obviously wrong, because then 'this.x' and 'other.x' will be treated as equal, leading to unsound smartcasts. This commit adds proper overload of 'equals' to 'ESDataFlowValue' that will compare them based on underlying 'DataFlowValue' (which already distinguish those values) ^KT-27260 Fixed --- .../kotlin/contracts/ESDataFlowValue.kt | 17 ++++++++++++++++- .../smartcastOnSameFieldOfDifferentInstances.kt | 2 +- 2 files changed, 17 insertions(+), 2 deletions(-) diff --git a/compiler/frontend/src/org/jetbrains/kotlin/contracts/ESDataFlowValue.kt b/compiler/frontend/src/org/jetbrains/kotlin/contracts/ESDataFlowValue.kt index 421047c1476..0fedde0791f 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/contracts/ESDataFlowValue.kt +++ b/compiler/frontend/src/org/jetbrains/kotlin/contracts/ESDataFlowValue.kt @@ -23,7 +23,22 @@ import org.jetbrains.kotlin.descriptors.ValueDescriptor import org.jetbrains.kotlin.psi.KtLambdaExpression import org.jetbrains.kotlin.resolve.calls.smartcasts.DataFlowValue -class ESDataFlowValue(descriptor: ValueDescriptor, val dataFlowValue: DataFlowValue) : ESVariable(descriptor) +class ESDataFlowValue(descriptor: ValueDescriptor, val dataFlowValue: DataFlowValue) : ESVariable(descriptor) { + override fun equals(other: Any?): Boolean { + if (this === other) return true + if (javaClass != other?.javaClass) return false + + other as ESDataFlowValue + + if (dataFlowValue != other.dataFlowValue) return false + + return true + } + + override fun hashCode(): Int { + return dataFlowValue.hashCode() + } +} class ESLambda(val lambda: KtLambdaExpression) : ESValue(null) { override fun accept(visitor: ESExpressionVisitor): T { diff --git a/compiler/testData/diagnostics/tests/smartCasts/smartcastOnSameFieldOfDifferentInstances.kt b/compiler/testData/diagnostics/tests/smartCasts/smartcastOnSameFieldOfDifferentInstances.kt index 7433c144bd5..68f01c6bdbf 100644 --- a/compiler/testData/diagnostics/tests/smartCasts/smartcastOnSameFieldOfDifferentInstances.kt +++ b/compiler/testData/diagnostics/tests/smartCasts/smartcastOnSameFieldOfDifferentInstances.kt @@ -5,7 +5,7 @@ class A(val x: String?) { fun foo(other: A) { when { x == null && other.x == null -> "1" - x.length > 0 -> "2" + x.length > 0 -> "2" } } } \ No newline at end of file