More precise implicit cast generation

If an expression 'x' has a definitely non-null type 'T1',
and is used in position with an expected type 'T2',
cast 'x' to 'T2!!' (most common non-null type T*: T* <: T2).
This commit is contained in:
Dmitry Petrov
2018-02-02 11:11:09 +03:00
parent 9137e68d4e
commit bf18186045
4 changed files with 26 additions and 20 deletions
@@ -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
)
}
}
}