'val' in 'when': IEEE754 equality

This commit is contained in:
Dmitry Petrov
2018-06-08 17:32:31 +03:00
parent 67247ee490
commit 6949610dcb
7 changed files with 77 additions and 4 deletions
@@ -10,9 +10,9 @@ import org.jetbrains.kotlin.codegen.state.KotlinTypeMapper
import org.jetbrains.kotlin.config.LanguageVersionSettings
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
import org.jetbrains.kotlin.psi.KtExpression
import org.jetbrains.kotlin.psi.KtProperty
import org.jetbrains.kotlin.resolve.BindingContext
import org.jetbrains.kotlin.resolve.bindingContextUtil.getDataFlowInfoBefore
import org.jetbrains.kotlin.resolve.calls.smartcasts.DataFlowValueFactory
import org.jetbrains.kotlin.resolve.calls.smartcasts.DataFlowValueFactoryImpl
import org.jetbrains.kotlin.types.KotlinType
import org.jetbrains.kotlin.types.TypeUtils
@@ -28,20 +28,26 @@ fun calcProperTypeForIeee754ArithmeticIfNeeded(
typeMapper: KotlinTypeMapper
): TypeAndNullability? {
if (inferredPrimitiveType == null) return null
val ktType = expression.kotlinType(bindingContext) ?: return null
val ktType = expression.getKotlinTypeForComparison(bindingContext) ?: return null
val isNullable = TypeUtils.isNullableType(ktType)
val asmType = typeMapper.mapType(inferredPrimitiveType)
if (!AsmUtil.isPrimitive(asmType)) return null
return TypeAndNullability(asmType, isNullable)
}
private fun KtExpression.getKotlinTypeForComparison(bindingContext: BindingContext): KotlinType? =
when {
this is KtProperty -> bindingContext[BindingContext.VARIABLE, this]?.type
else -> kotlinType(bindingContext)
}
fun legacyCalcTypeForIeee754ArithmeticIfNeeded(
expression: KtExpression?,
bindingContext: BindingContext,
descriptor: DeclarationDescriptor,
languageVersionSettings: LanguageVersionSettings
): TypeAndNullability? {
val ktType = expression.kotlinType(bindingContext) ?: return null
val ktType = expression?.getKotlinTypeForComparison(bindingContext) ?: return null
if (KotlinBuiltIns.isDoubleOrNullableDouble(ktType)) {
return TypeAndNullability(
@@ -59,7 +65,7 @@ fun legacyCalcTypeForIeee754ArithmeticIfNeeded(
// NB. Using DataFlowValueFactoryImpl is a hack, but it is ok for 'legacy'
val dataFlow = DataFlowValueFactoryImpl().createDataFlowValue(
expression!!,
expression,
ktType,
bindingContext,
descriptor
@@ -0,0 +1,13 @@
// !LANGUAGE: +VariableDeclarationInWhenSubject
// IGNORE_BACKEND: JS
val dz = -0.0
fun box(): String {
when (val y = dz) {
0.0 -> {}
else -> throw AssertionError()
}
return "OK"
}
@@ -0,0 +1,14 @@
// !LANGUAGE: +VariableDeclarationInWhenSubject +ProperIeee754Comparisons
// IGNORE_BACKEND: JS
val az: Any = -0.0
fun box(): String {
when (val y = az) {
!is Double -> throw AssertionError()
0.0 -> {}
else -> throw AssertionError()
}
return "OK"
}
@@ -21673,6 +21673,16 @@ public class IrBlackBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTes
runTest("compiler/testData/codegen/box/when/whenSubjectVariable/equalityWithSubjectVariable.kt");
}
@TestMetadata("ieee754Equality.kt")
public void testIeee754Equality() throws Exception {
runTest("compiler/testData/codegen/box/when/whenSubjectVariable/ieee754Equality.kt");
}
@TestMetadata("ieee754EqualityWithSmartCast.kt")
public void testIeee754EqualityWithSmartCast() throws Exception {
runTest("compiler/testData/codegen/box/when/whenSubjectVariable/ieee754EqualityWithSmartCast.kt");
}
@TestMetadata("isCheckOnSubjectVariable.kt")
public void testIsCheckOnSubjectVariable() throws Exception {
runTest("compiler/testData/codegen/box/when/whenSubjectVariable/isCheckOnSubjectVariable.kt");
@@ -21673,6 +21673,16 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest {
runTest("compiler/testData/codegen/box/when/whenSubjectVariable/equalityWithSubjectVariable.kt");
}
@TestMetadata("ieee754Equality.kt")
public void testIeee754Equality() throws Exception {
runTest("compiler/testData/codegen/box/when/whenSubjectVariable/ieee754Equality.kt");
}
@TestMetadata("ieee754EqualityWithSmartCast.kt")
public void testIeee754EqualityWithSmartCast() throws Exception {
runTest("compiler/testData/codegen/box/when/whenSubjectVariable/ieee754EqualityWithSmartCast.kt");
}
@TestMetadata("isCheckOnSubjectVariable.kt")
public void testIsCheckOnSubjectVariable() throws Exception {
runTest("compiler/testData/codegen/box/when/whenSubjectVariable/isCheckOnSubjectVariable.kt");
@@ -21673,6 +21673,16 @@ public class LightAnalysisModeTestGenerated extends AbstractLightAnalysisModeTes
runTest("compiler/testData/codegen/box/when/whenSubjectVariable/equalityWithSubjectVariable.kt");
}
@TestMetadata("ieee754Equality.kt")
public void testIeee754Equality() throws Exception {
runTest("compiler/testData/codegen/box/when/whenSubjectVariable/ieee754Equality.kt");
}
@TestMetadata("ieee754EqualityWithSmartCast.kt")
public void testIeee754EqualityWithSmartCast() throws Exception {
runTest("compiler/testData/codegen/box/when/whenSubjectVariable/ieee754EqualityWithSmartCast.kt");
}
@TestMetadata("isCheckOnSubjectVariable.kt")
public void testIsCheckOnSubjectVariable() throws Exception {
runTest("compiler/testData/codegen/box/when/whenSubjectVariable/isCheckOnSubjectVariable.kt");
@@ -19566,6 +19566,16 @@ public class JsCodegenBoxTestGenerated extends AbstractJsCodegenBoxTest {
runTest("compiler/testData/codegen/box/when/whenSubjectVariable/equalityWithSubjectVariable.kt");
}
@TestMetadata("ieee754Equality.kt")
public void testIeee754Equality() throws Exception {
runTest("compiler/testData/codegen/box/when/whenSubjectVariable/ieee754Equality.kt");
}
@TestMetadata("ieee754EqualityWithSmartCast.kt")
public void testIeee754EqualityWithSmartCast() throws Exception {
runTest("compiler/testData/codegen/box/when/whenSubjectVariable/ieee754EqualityWithSmartCast.kt");
}
@TestMetadata("isCheckOnSubjectVariable.kt")
public void testIsCheckOnSubjectVariable() throws Exception {
runTest("compiler/testData/codegen/box/when/whenSubjectVariable/isCheckOnSubjectVariable.kt");