diff --git a/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/transformations/InsertImplicitCasts.kt b/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/transformations/InsertImplicitCasts.kt index deb726986ce..f71d4ee8965 100644 --- a/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/transformations/InsertImplicitCasts.kt +++ b/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/transformations/InsertImplicitCasts.kt @@ -172,6 +172,7 @@ class InsertImplicitCasts(val builtIns: KotlinBuiltIns) : IrElementTransformerVo return when { KotlinBuiltIns.isUnit(expectedType) -> coerceToUnit() + valueType.isNullabilityFlexible() && valueType.containsNull() && !expectedType.containsNull() -> { val nonNullValueType = valueType.upperIfFlexible().makeNotNullable() IrTypeOperatorCallImpl( @@ -179,18 +180,23 @@ class InsertImplicitCasts(val builtIns: KotlinBuiltIns) : IrElementTransformerVo IrTypeOperator.IMPLICIT_NOTNULL, nonNullValueType, this ).cast(expectedType) } + KotlinTypeChecker.DEFAULT.isSubtypeOf(valueType.makeNotNullable(), expectedType) -> this + KotlinBuiltIns.isInt(valueType) && notNullableExpectedType.isBuiltInIntegerType() -> IrTypeOperatorCallImpl( startOffset, endOffset, notNullableExpectedType, IrTypeOperator.IMPLICIT_INTEGER_COERCION, notNullableExpectedType, this ) - else -> + + else -> { + val targetType = if (!valueType.containsNull()) notNullableExpectedType else expectedType IrTypeOperatorCallImpl( - startOffset, endOffset, expectedType, - IrTypeOperator.IMPLICIT_CAST, expectedType, this + startOffset, endOffset, targetType, + IrTypeOperator.IMPLICIT_CAST, targetType, this ) + } } } diff --git a/compiler/testData/ir/irText/expressions/floatingPointComparisons/floatingPointEqeq.txt b/compiler/testData/ir/irText/expressions/floatingPointComparisons/floatingPointEqeq.txt index 30bc23179d6..495f0c11b35 100644 --- a/compiler/testData/ir/irText/expressions/floatingPointComparisons/floatingPointEqeq.txt +++ b/compiler/testData/ir/irText/expressions/floatingPointComparisons/floatingPointEqeq.txt @@ -42,7 +42,7 @@ FILE fqName: fileName:/floatingPointEqeq.kt GET_VAR 'value-parameter y: Any' type=kotlin.Any origin=null then: CALL 'ieee754equals(Double?, Double?): Boolean' type=kotlin.Boolean origin=EQEQ arg0: GET_VAR 'value-parameter x: Double' type=kotlin.Double origin=null - arg1: TYPE_OP type=kotlin.Double? origin=IMPLICIT_CAST typeOperand=kotlin.Double? + arg1: TYPE_OP type=kotlin.Double origin=IMPLICIT_CAST typeOperand=kotlin.Double GET_VAR 'value-parameter y: Any' type=kotlin.Any origin=null BRANCH if: CONST Boolean type=kotlin.Boolean value=true @@ -64,9 +64,9 @@ FILE fqName: fileName:/floatingPointEqeq.kt if: CONST Boolean type=kotlin.Boolean value=true then: CONST Boolean type=kotlin.Boolean value=false then: CALL 'ieee754equals(Double?, Double?): Boolean' type=kotlin.Boolean origin=EQEQ - arg0: TYPE_OP type=kotlin.Double? origin=IMPLICIT_CAST typeOperand=kotlin.Double? + arg0: TYPE_OP type=kotlin.Double origin=IMPLICIT_CAST typeOperand=kotlin.Double GET_VAR 'value-parameter x: Any' type=kotlin.Any origin=null - arg1: TYPE_OP type=kotlin.Double? origin=IMPLICIT_CAST typeOperand=kotlin.Double? + arg1: TYPE_OP type=kotlin.Double origin=IMPLICIT_CAST typeOperand=kotlin.Double GET_VAR 'value-parameter y: Any' type=kotlin.Any origin=null BRANCH if: CONST Boolean type=kotlin.Boolean value=true @@ -114,7 +114,7 @@ FILE fqName: fileName:/floatingPointEqeq.kt GET_VAR 'value-parameter y: Any' type=kotlin.Any origin=null then: CALL 'ieee754equals(Float?, Float?): Boolean' type=kotlin.Boolean origin=EQEQ arg0: GET_VAR 'value-parameter x: Float' type=kotlin.Float origin=null - arg1: TYPE_OP type=kotlin.Float? origin=IMPLICIT_CAST typeOperand=kotlin.Float? + arg1: TYPE_OP type=kotlin.Float origin=IMPLICIT_CAST typeOperand=kotlin.Float GET_VAR 'value-parameter y: Any' type=kotlin.Any origin=null BRANCH if: CONST Boolean type=kotlin.Boolean value=true @@ -136,9 +136,9 @@ FILE fqName: fileName:/floatingPointEqeq.kt if: CONST Boolean type=kotlin.Boolean value=true then: CONST Boolean type=kotlin.Boolean value=false then: CALL 'ieee754equals(Float?, Float?): Boolean' type=kotlin.Boolean origin=EQEQ - arg0: TYPE_OP type=kotlin.Float? origin=IMPLICIT_CAST typeOperand=kotlin.Float? + arg0: TYPE_OP type=kotlin.Float origin=IMPLICIT_CAST typeOperand=kotlin.Float GET_VAR 'value-parameter x: Any' type=kotlin.Any origin=null - arg1: TYPE_OP type=kotlin.Float? origin=IMPLICIT_CAST typeOperand=kotlin.Float? + arg1: TYPE_OP type=kotlin.Float origin=IMPLICIT_CAST typeOperand=kotlin.Float GET_VAR 'value-parameter y: Any' type=kotlin.Any origin=null BRANCH if: CONST Boolean type=kotlin.Boolean value=true @@ -163,7 +163,7 @@ FILE fqName: fileName:/floatingPointEqeq.kt arg0: CALL 'toDouble(): Double' type=kotlin.Double origin=null $this: TYPE_OP type=kotlin.Float origin=IMPLICIT_CAST typeOperand=kotlin.Float GET_VAR 'value-parameter x: Any' type=kotlin.Any origin=null - arg1: TYPE_OP type=kotlin.Double? origin=IMPLICIT_CAST typeOperand=kotlin.Double? + arg1: TYPE_OP type=kotlin.Double origin=IMPLICIT_CAST typeOperand=kotlin.Double GET_VAR 'value-parameter y: Any' type=kotlin.Any origin=null BRANCH if: CONST Boolean type=kotlin.Boolean value=true @@ -185,7 +185,7 @@ FILE fqName: fileName:/floatingPointEqeq.kt if: CONST Boolean type=kotlin.Boolean value=true then: CONST Boolean type=kotlin.Boolean value=false then: CALL 'ieee754equals(Double?, Double?): Boolean' type=kotlin.Boolean origin=EQEQ - arg0: TYPE_OP type=kotlin.Double? origin=IMPLICIT_CAST typeOperand=kotlin.Double? + arg0: TYPE_OP type=kotlin.Double origin=IMPLICIT_CAST typeOperand=kotlin.Double GET_VAR 'value-parameter x: Any' type=kotlin.Any origin=null arg1: CALL 'toDouble(): Double' type=kotlin.Double origin=null $this: TYPE_OP type=kotlin.Float origin=IMPLICIT_CAST typeOperand=kotlin.Float diff --git a/compiler/testData/ir/irText/expressions/floatingPointComparisons/floatingPointExcleq.txt b/compiler/testData/ir/irText/expressions/floatingPointComparisons/floatingPointExcleq.txt index 631a7a2d660..6e0a15bbdb8 100644 --- a/compiler/testData/ir/irText/expressions/floatingPointComparisons/floatingPointExcleq.txt +++ b/compiler/testData/ir/irText/expressions/floatingPointComparisons/floatingPointExcleq.txt @@ -47,7 +47,7 @@ FILE fqName: fileName:/floatingPointExcleq.kt then: CALL 'NOT(Boolean): Boolean' type=kotlin.Boolean origin=EXCLEQ arg0: CALL 'ieee754equals(Double?, Double?): Boolean' type=kotlin.Boolean origin=EXCLEQ arg0: GET_VAR 'value-parameter x: Double' type=kotlin.Double origin=null - arg1: TYPE_OP type=kotlin.Double? origin=IMPLICIT_CAST typeOperand=kotlin.Double? + arg1: TYPE_OP type=kotlin.Double origin=IMPLICIT_CAST typeOperand=kotlin.Double GET_VAR 'value-parameter y: Any' type=kotlin.Any origin=null BRANCH if: CONST Boolean type=kotlin.Boolean value=true @@ -70,9 +70,9 @@ FILE fqName: fileName:/floatingPointExcleq.kt then: CONST Boolean type=kotlin.Boolean value=false then: CALL 'NOT(Boolean): Boolean' type=kotlin.Boolean origin=EXCLEQ arg0: CALL 'ieee754equals(Double?, Double?): Boolean' type=kotlin.Boolean origin=EXCLEQ - arg0: TYPE_OP type=kotlin.Double? origin=IMPLICIT_CAST typeOperand=kotlin.Double? + arg0: TYPE_OP type=kotlin.Double origin=IMPLICIT_CAST typeOperand=kotlin.Double GET_VAR 'value-parameter x: Any' type=kotlin.Any origin=null - arg1: TYPE_OP type=kotlin.Double? origin=IMPLICIT_CAST typeOperand=kotlin.Double? + arg1: TYPE_OP type=kotlin.Double origin=IMPLICIT_CAST typeOperand=kotlin.Double GET_VAR 'value-parameter y: Any' type=kotlin.Any origin=null BRANCH if: CONST Boolean type=kotlin.Boolean value=true @@ -125,7 +125,7 @@ FILE fqName: fileName:/floatingPointExcleq.kt then: CALL 'NOT(Boolean): Boolean' type=kotlin.Boolean origin=EXCLEQ arg0: CALL 'ieee754equals(Float?, Float?): Boolean' type=kotlin.Boolean origin=EXCLEQ arg0: GET_VAR 'value-parameter x: Float' type=kotlin.Float origin=null - arg1: TYPE_OP type=kotlin.Float? origin=IMPLICIT_CAST typeOperand=kotlin.Float? + arg1: TYPE_OP type=kotlin.Float origin=IMPLICIT_CAST typeOperand=kotlin.Float GET_VAR 'value-parameter y: Any' type=kotlin.Any origin=null BRANCH if: CONST Boolean type=kotlin.Boolean value=true @@ -148,9 +148,9 @@ FILE fqName: fileName:/floatingPointExcleq.kt then: CONST Boolean type=kotlin.Boolean value=false then: CALL 'NOT(Boolean): Boolean' type=kotlin.Boolean origin=EXCLEQ arg0: CALL 'ieee754equals(Float?, Float?): Boolean' type=kotlin.Boolean origin=EXCLEQ - arg0: TYPE_OP type=kotlin.Float? origin=IMPLICIT_CAST typeOperand=kotlin.Float? + arg0: TYPE_OP type=kotlin.Float origin=IMPLICIT_CAST typeOperand=kotlin.Float GET_VAR 'value-parameter x: Any' type=kotlin.Any origin=null - arg1: TYPE_OP type=kotlin.Float? origin=IMPLICIT_CAST typeOperand=kotlin.Float? + arg1: TYPE_OP type=kotlin.Float origin=IMPLICIT_CAST typeOperand=kotlin.Float GET_VAR 'value-parameter y: Any' type=kotlin.Any origin=null BRANCH if: CONST Boolean type=kotlin.Boolean value=true @@ -176,7 +176,7 @@ FILE fqName: fileName:/floatingPointExcleq.kt arg0: CALL 'toDouble(): Double' type=kotlin.Double origin=null $this: TYPE_OP type=kotlin.Float origin=IMPLICIT_CAST typeOperand=kotlin.Float GET_VAR 'value-parameter x: Any' type=kotlin.Any origin=null - arg1: TYPE_OP type=kotlin.Double? origin=IMPLICIT_CAST typeOperand=kotlin.Double? + arg1: TYPE_OP type=kotlin.Double origin=IMPLICIT_CAST typeOperand=kotlin.Double GET_VAR 'value-parameter y: Any' type=kotlin.Any origin=null BRANCH if: CONST Boolean type=kotlin.Boolean value=true @@ -199,7 +199,7 @@ FILE fqName: fileName:/floatingPointExcleq.kt then: CONST Boolean type=kotlin.Boolean value=false then: CALL 'NOT(Boolean): Boolean' type=kotlin.Boolean origin=EXCLEQ arg0: CALL 'ieee754equals(Double?, Double?): Boolean' type=kotlin.Boolean origin=EXCLEQ - arg0: TYPE_OP type=kotlin.Double? origin=IMPLICIT_CAST typeOperand=kotlin.Double? + arg0: TYPE_OP type=kotlin.Double origin=IMPLICIT_CAST typeOperand=kotlin.Double GET_VAR 'value-parameter x: Any' type=kotlin.Any origin=null arg1: CALL 'toDouble(): Double' type=kotlin.Double origin=null $this: TYPE_OP type=kotlin.Float origin=IMPLICIT_CAST typeOperand=kotlin.Float diff --git a/compiler/testData/ir/irText/expressions/setFieldWithImplicitCast.txt b/compiler/testData/ir/irText/expressions/setFieldWithImplicitCast.txt index 9961c3accf4..c88a5398a3b 100644 --- a/compiler/testData/ir/irText/expressions/setFieldWithImplicitCast.txt +++ b/compiler/testData/ir/irText/expressions/setFieldWithImplicitCast.txt @@ -16,7 +16,7 @@ FILE fqName: fileName:/Derived.kt then: BLOCK type=kotlin.Unit origin=null SET_FIELD 'value: String!' type=kotlin.Unit origin=EQ receiver: GET_VAR 'this@Derived: Derived' type=Derived origin=null - value: TYPE_OP type=kotlin.String! origin=IMPLICIT_CAST typeOperand=kotlin.String! + value: TYPE_OP type=kotlin.String origin=IMPLICIT_CAST typeOperand=kotlin.String GET_VAR 'value-parameter v: Any' type=kotlin.Any origin=null PROPERTY FAKE_OVERRIDE name:value type:kotlin.String! visibility:public modality:FINAL flags:var FIELD FAKE_OVERRIDE name:value type:kotlin.String! visibility:public