Use proper descriptor for (generic) property assignment.

Insert IMPLICIT_INTEGER_COERCION only if Int is coerced to an integer type.
This commit is contained in:
Dmitry Petrov
2017-03-02 14:24:39 +03:00
parent 97fbbc74e6
commit f636ab21f8
5 changed files with 75 additions and 6 deletions
@@ -104,7 +104,7 @@ class AssignmentGenerator(statementGenerator: StatementGenerator) : StatementGen
}
val resolvedCall = getResolvedCall(ktLeft) ?: TODO("no resolved call for LHS")
val descriptor = resolvedCall.candidateDescriptor
val descriptor = resolvedCall.resultingDescriptor
return when (descriptor) {
is SyntheticFieldDescriptor -> {
@@ -188,6 +188,8 @@ class InsertImplicitCasts(val builtIns: KotlinBuiltIns): IrElementTransformerVoi
if (expectedType == null) return this
if (expectedType.isError) return this
val notNullableExpectedType = expectedType.makeNotNullable()
val valueType = this.type
return when {
@@ -196,17 +198,17 @@ class InsertImplicitCasts(val builtIns: KotlinBuiltIns): IrElementTransformerVoi
valueType.isNullabilityFlexible() && valueType.containsNull() && !expectedType.containsNull() -> {
val nonNullValueType = valueType.upperIfFlexible().makeNotNullable()
IrTypeOperatorCallImpl(
this.startOffset, this.endOffset, nonNullValueType,
startOffset, endOffset, nonNullValueType,
IrTypeOperator.IMPLICIT_NOTNULL, nonNullValueType, this
).cast(expectedType)
}
KotlinTypeChecker.DEFAULT.isSubtypeOf(valueType.makeNotNullable(), expectedType) ->
this
KotlinBuiltIns.isInt(valueType) ->
IrTypeOperatorCallImpl(this.startOffset, this.endOffset, expectedType,
IrTypeOperator.IMPLICIT_INTEGER_COERCION, expectedType.makeNotNullable(), this)
KotlinBuiltIns.isInt(valueType) && notNullableExpectedType.isBuiltInIntegerType() ->
IrTypeOperatorCallImpl(startOffset, endOffset, expectedType,
IrTypeOperator.IMPLICIT_INTEGER_COERCION, notNullableExpectedType, this)
else ->
IrTypeOperatorCallImpl(this.startOffset, this.endOffset, expectedType,
IrTypeOperatorCallImpl(startOffset, endOffset, expectedType,
IrTypeOperator.IMPLICIT_CAST, expectedType, this)
}
}
@@ -220,5 +222,11 @@ class InsertImplicitCasts(val builtIns: KotlinBuiltIns): IrElementTransformerVoi
IrTypeOperatorCallImpl(startOffset, endOffset, builtIns.unitType,
IrTypeOperator.IMPLICIT_COERCION_TO_UNIT, builtIns.unitType, this)
}
private fun KotlinType.isBuiltInIntegerType(): Boolean =
KotlinBuiltIns.isByte(this) ||
KotlinBuiltIns.isShort(this) ||
KotlinBuiltIns.isInt(this) ||
KotlinBuiltIns.isLong(this)
}
@@ -0,0 +1,16 @@
interface CPointed
inline fun <reified T : CPointed> CPointed.reinterpret(): T = TODO()
class CInt32VarX<T> : CPointed
typealias CInt32Var = CInt32VarX<Int>
var <T_INT : Int> CInt32VarX<T_INT>.value: T_INT
get() = TODO()
set(value) {}
class IdType(val value: Int) : CPointed
fun foo(value: IdType, cv: CInt32Var) {
cv.value = value.value
}
@@ -0,0 +1,39 @@
FILE /integerCoercionToT.kt
CLASS INTERFACE CPointed
FUN public inline fun <reified T : CPointed> CPointed.reinterpret(): T
BLOCK_BODY
RETURN type=kotlin.Nothing from='reinterpret() on CPointed: T'
CALL 'TODO(): Nothing' type=kotlin.Nothing origin=null
CLASS CLASS CInt32VarX
CONSTRUCTOR public constructor CInt32VarX<T>()
BLOCK_BODY
DELEGATING_CONSTRUCTOR_CALL 'constructor Any()'
INSTANCE_INITIALIZER_CALL classDescriptor='CInt32VarX'
TYPEALIAS typealias CInt32Var = CInt32VarX<Int> type=CInt32VarX<kotlin.Int>
PROPERTY public var <T_INT : kotlin.Int> CInt32VarX<T_INT>.value: T_INT
FUN public fun CInt32VarX<T_INT>.<get-value>(): T_INT
BLOCK_BODY
RETURN type=kotlin.Nothing from='<get-value>() on CInt32VarX<T_INT>: T_INT'
CALL 'TODO(): Nothing' type=kotlin.Nothing origin=null
FUN public fun CInt32VarX<T_INT>.<set-value>(value: T_INT): kotlin.Unit
BLOCK_BODY
CLASS CLASS IdType
CONSTRUCTOR public constructor IdType(value: kotlin.Int)
BLOCK_BODY
DELEGATING_CONSTRUCTOR_CALL 'constructor Any()'
INSTANCE_INITIALIZER_CALL classDescriptor='IdType'
PROPERTY public final val value: kotlin.Int
FIELD PROPERTY_BACKING_FIELD public final val value: kotlin.Int
EXPRESSION_BODY
GET_VAR 'value-parameter value: Int' type=kotlin.Int origin=INITIALIZE_PROPERTY_FROM_PARAMETER
FUN DEFAULT_PROPERTY_ACCESSOR public final fun <get-value>(): kotlin.Int
BLOCK_BODY
RETURN type=kotlin.Nothing from='<get-value>(): Int'
GET_FIELD 'value: Int' type=kotlin.Int origin=null
receiver: GET_VAR '<receiver: IdType>' type=IdType origin=null
FUN public fun foo(value: IdType, cv: CInt32Var /* = CInt32VarX<kotlin.Int> */): kotlin.Unit
BLOCK_BODY
CALL '<set-value>(Int) on CInt32VarX<Int>: Unit' type=kotlin.Unit origin=EQ
$receiver: GET_VAR 'value-parameter cv: CInt32Var /* = CInt32VarX<Int> */' type=CInt32Var /* = CInt32VarX<kotlin.Int> */ origin=null
value: CALL '<get-value>(): Int' type=kotlin.Int origin=GET_PROPERTY
$this: GET_VAR 'value-parameter value: IdType' type=IdType origin=null
@@ -847,6 +847,12 @@ public class IrTextTestCaseGenerated extends AbstractIrTextTestCase {
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/ir/irText/regressions/coercionInLoop.kt");
doTest(fileName);
}
@TestMetadata("integerCoercionToT.kt")
public void testIntegerCoercionToT() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/ir/irText/regressions/integerCoercionToT.kt");
doTest(fileName);
}
}
@TestMetadata("compiler/testData/ir/irText/singletons")