[FIR2IR] Always use property type if var
For destructing calls, the component type is used for the property type in all cases. However, this can result in runtime and/or compilation errors when the property is a var and changed, especially when the component is a primitive but the property type is nullable. Instead, only use the component type when the property is also a val. ^KT-64944 Fixed
This commit is contained in:
@@ -0,0 +1,66 @@
|
||||
FILE fqName:<root> fileName:/reassignDestructured.kt
|
||||
FUN name:getInt visibility:public modality:FINAL <> () returnType:kotlin.Int?
|
||||
BLOCK_BODY
|
||||
RETURN type=kotlin.Nothing from='public final fun getInt (): kotlin.Int? declared in <root>'
|
||||
CONST Int type=kotlin.Int value=1
|
||||
FUN name:test1 visibility:public modality:FINAL <> () returnType:kotlin.Unit
|
||||
BLOCK_BODY
|
||||
VAR name:i1 type:kotlin.Int? [val]
|
||||
CALL 'public final fun getInt (): kotlin.Int? declared in <root>' type=kotlin.Int? origin=null
|
||||
VAR name:i2 type:kotlin.Int? [val]
|
||||
CALL 'public final fun getInt (): kotlin.Int? declared in <root>' type=kotlin.Int? origin=null
|
||||
VAR IR_TEMPORARY_VARIABLE name:tmp_0 type:kotlin.Pair<kotlin.Int?, kotlin.Int?> [val]
|
||||
CALL 'public final fun to <A, B> (that: B of kotlin.to): kotlin.Pair<A of kotlin.to, B of kotlin.to> declared in kotlin' type=kotlin.Pair<kotlin.Int?, kotlin.Int?> origin=null
|
||||
<A>: kotlin.Int?
|
||||
<B>: kotlin.Int?
|
||||
$receiver: GET_VAR 'val i1: kotlin.Int? declared in <root>.test1' type=kotlin.Int? origin=null
|
||||
that: GET_VAR 'val i2: kotlin.Int? declared in <root>.test1' type=kotlin.Int? origin=null
|
||||
VAR name:int1 type:kotlin.Int? [var]
|
||||
CALL 'public final fun component1 (): A of kotlin.Pair declared in kotlin.Pair' type=kotlin.Int? origin=COMPONENT_N(index=1)
|
||||
$this: GET_VAR 'val tmp_0: kotlin.Pair<kotlin.Int?, kotlin.Int?> declared in <root>.test1' type=kotlin.Pair<kotlin.Int?, kotlin.Int?> origin=null
|
||||
VAR name:int2 type:kotlin.Int? [var]
|
||||
CALL 'public final fun component2 (): B of kotlin.Pair declared in kotlin.Pair' type=kotlin.Int? origin=COMPONENT_N(index=2)
|
||||
$this: GET_VAR 'val tmp_0: kotlin.Pair<kotlin.Int?, kotlin.Int?> declared in <root>.test1' type=kotlin.Pair<kotlin.Int?, kotlin.Int?> origin=null
|
||||
SET_VAR 'var int1: kotlin.Int? declared in <root>.test1' type=kotlin.Unit origin=EQ
|
||||
CONST Null type=kotlin.Nothing? value=null
|
||||
FUN name:test2 visibility:public modality:FINAL <> () returnType:kotlin.Unit
|
||||
BLOCK_BODY
|
||||
VAR name:i1 type:kotlin.Int? [val]
|
||||
CALL 'public final fun getInt (): kotlin.Int? declared in <root>' type=kotlin.Int? origin=null
|
||||
VAR name:i2 type:kotlin.Int? [val]
|
||||
CALL 'public final fun getInt (): kotlin.Int? declared in <root>' type=kotlin.Int? origin=null
|
||||
WHEN type=kotlin.Unit origin=IF
|
||||
BRANCH
|
||||
if: WHEN type=kotlin.Boolean origin=OROR
|
||||
BRANCH
|
||||
if: CALL 'public final fun EQEQ (arg0: kotlin.Any?, arg1: kotlin.Any?): kotlin.Boolean declared in kotlin.internal.ir' type=kotlin.Boolean origin=EQEQ
|
||||
arg0: GET_VAR 'val i1: kotlin.Int? declared in <root>.test2' type=kotlin.Int? origin=null
|
||||
arg1: CONST Null type=kotlin.Nothing? value=null
|
||||
then: CONST Boolean type=kotlin.Boolean value=true
|
||||
BRANCH
|
||||
if: CONST Boolean type=kotlin.Boolean value=true
|
||||
then: CALL 'public final fun EQEQ (arg0: kotlin.Any?, arg1: kotlin.Any?): kotlin.Boolean declared in kotlin.internal.ir' type=kotlin.Boolean origin=EQEQ
|
||||
arg0: GET_VAR 'val i2: kotlin.Int? declared in <root>.test2' type=kotlin.Int? origin=null
|
||||
arg1: CONST Null type=kotlin.Nothing? value=null
|
||||
then: RETURN type=kotlin.Nothing from='public final fun test2 (): kotlin.Unit declared in <root>'
|
||||
GET_OBJECT 'CLASS IR_EXTERNAL_DECLARATION_STUB OBJECT name:Unit modality:FINAL visibility:public superTypes:[kotlin.Any]' type=kotlin.Unit
|
||||
VAR IR_TEMPORARY_VARIABLE name:tmp_1 type:kotlin.Pair<kotlin.Int, kotlin.Int> [val]
|
||||
CALL 'public final fun to <A, B> (that: B of kotlin.to): kotlin.Pair<A of kotlin.to, B of kotlin.to> declared in kotlin' type=kotlin.Pair<kotlin.Int, kotlin.Int> origin=null
|
||||
<A>: kotlin.Int
|
||||
<B>: kotlin.Int
|
||||
$receiver: GET_VAR 'val i1: kotlin.Int? declared in <root>.test2' type=kotlin.Int? origin=null
|
||||
that: GET_VAR 'val i2: kotlin.Int? declared in <root>.test2' type=kotlin.Int? origin=null
|
||||
VAR name:int1 type:kotlin.Int? [var]
|
||||
CALL 'public final fun component1 (): A of kotlin.Pair declared in kotlin.Pair' type=kotlin.Int origin=COMPONENT_N(index=1)
|
||||
$this: GET_VAR 'val tmp_1: kotlin.Pair<kotlin.Int, kotlin.Int> declared in <root>.test2' type=kotlin.Pair<kotlin.Int, kotlin.Int> origin=null
|
||||
VAR name:int2 type:kotlin.Int? [var]
|
||||
CALL 'public final fun component2 (): B of kotlin.Pair declared in kotlin.Pair' type=kotlin.Int origin=COMPONENT_N(index=2)
|
||||
$this: GET_VAR 'val tmp_1: kotlin.Pair<kotlin.Int, kotlin.Int> declared in <root>.test2' type=kotlin.Pair<kotlin.Int, kotlin.Int> origin=null
|
||||
SET_VAR 'var int1: kotlin.Int? declared in <root>.test2' type=kotlin.Unit origin=EQ
|
||||
CONST Null type=kotlin.Nothing? value=null
|
||||
FUN name:box visibility:public modality:FINAL <> () returnType:kotlin.String
|
||||
BLOCK_BODY
|
||||
CALL 'public final fun test1 (): kotlin.Unit declared in <root>' type=kotlin.Unit origin=null
|
||||
CALL 'public final fun test2 (): kotlin.Unit declared in <root>' type=kotlin.Unit origin=null
|
||||
RETURN type=kotlin.Nothing from='public final fun box (): kotlin.String declared in <root>'
|
||||
CONST String type=kotlin.String value="OK"
|
||||
@@ -0,0 +1,32 @@
|
||||
// IGNORE_BACKEND_K1: ANY
|
||||
// WITH_STDLIB
|
||||
// DUMP_IR
|
||||
// ISSUE: KT-64944
|
||||
|
||||
fun getInt(): Int? {
|
||||
return 1
|
||||
}
|
||||
|
||||
fun test1() {
|
||||
val i1 = getInt()
|
||||
val i2 = getInt()
|
||||
|
||||
var (int1: Int?, int2: Int?) = i1 to i2
|
||||
int1 = null
|
||||
}
|
||||
|
||||
fun test2() {
|
||||
val i1 = getInt()
|
||||
val i2 = getInt()
|
||||
|
||||
if (i1 == null || i2 == null) return
|
||||
|
||||
var (int1: Int?, int2: Int?) = i1 to i2
|
||||
int1 = null
|
||||
}
|
||||
|
||||
fun box(): String {
|
||||
test1()
|
||||
test2()
|
||||
return "OK"
|
||||
}
|
||||
Reference in New Issue
Block a user