[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:
Brian Norman
2024-01-29 15:29:54 -06:00
committed by Space Team
parent 1fe8b50c19
commit dde2156f5f
23 changed files with 220 additions and 2 deletions
@@ -38374,6 +38374,12 @@ public class LLFirBlackBoxCodegenBasedTestGenerated extends AbstractLLFirBlackBo
runTest("compiler/testData/codegen/box/primitiveTypes/rangeTo.kt");
}
@Test
@TestMetadata("reassignDestructured.kt")
public void testReassignDestructured() throws Exception {
runTest("compiler/testData/codegen/box/primitiveTypes/reassignDestructured.kt");
}
@Test
@TestMetadata("stringEqualsHashCodeToString.kt")
public void testStringEqualsHashCodeToString() throws Exception {
@@ -38374,6 +38374,12 @@ public class LLFirReversedBlackBoxCodegenBasedTestGenerated extends AbstractLLFi
runTest("compiler/testData/codegen/box/primitiveTypes/rangeTo.kt");
}
@Test
@TestMetadata("reassignDestructured.kt")
public void testReassignDestructured() throws Exception {
runTest("compiler/testData/codegen/box/primitiveTypes/reassignDestructured.kt");
}
@Test
@TestMetadata("stringEqualsHashCodeToString.kt")
public void testStringEqualsHashCodeToString() throws Exception {
@@ -838,8 +838,9 @@ fun FirExpression.asCompileTimeIrInitializer(components: Fir2IrComponents, expec
*/
context(Fir2IrComponents)
internal fun FirVariable.irTypeForPotentiallyComponentCall(predefinedType: IrType? = null): IrType {
val typeRef = when (val initializer = initializer) {
is FirComponentCall -> initializer.resolvedType
val initializer = initializer
val typeRef = when {
isVal && initializer is FirComponentCall -> initializer.resolvedType
else -> {
if (predefinedType != null) return predefinedType
this.returnTypeRef.coneType
@@ -38007,6 +38007,12 @@ public class FirLightTreeBlackBoxCodegenTestGenerated extends AbstractFirLightTr
runTest("compiler/testData/codegen/box/primitiveTypes/rangeTo.kt");
}
@Test
@TestMetadata("reassignDestructured.kt")
public void testReassignDestructured() throws Exception {
runTest("compiler/testData/codegen/box/primitiveTypes/reassignDestructured.kt");
}
@Test
@TestMetadata("stringEqualsHashCodeToString.kt")
public void testStringEqualsHashCodeToString() throws Exception {
@@ -38007,6 +38007,12 @@ public class FirLightTreeBlackBoxCodegenWithIrFakeOverrideGeneratorTestGenerated
runTest("compiler/testData/codegen/box/primitiveTypes/rangeTo.kt");
}
@Test
@TestMetadata("reassignDestructured.kt")
public void testReassignDestructured() throws Exception {
runTest("compiler/testData/codegen/box/primitiveTypes/reassignDestructured.kt");
}
@Test
@TestMetadata("stringEqualsHashCodeToString.kt")
public void testStringEqualsHashCodeToString() throws Exception {
@@ -38007,6 +38007,12 @@ public class FirPsiBlackBoxCodegenTestGenerated extends AbstractFirPsiBlackBoxCo
runTest("compiler/testData/codegen/box/primitiveTypes/rangeTo.kt");
}
@Test
@TestMetadata("reassignDestructured.kt")
public void testReassignDestructured() throws Exception {
runTest("compiler/testData/codegen/box/primitiveTypes/reassignDestructured.kt");
}
@Test
@TestMetadata("stringEqualsHashCodeToString.kt")
public void testStringEqualsHashCodeToString() throws Exception {
@@ -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"
}
@@ -37323,6 +37323,12 @@ public class JvmAbiConsistencyTestBoxGenerated extends AbstractJvmAbiConsistency
runTest("compiler/testData/codegen/box/primitiveTypes/rangeTo.kt");
}
@Test
@TestMetadata("reassignDestructured.kt")
public void testReassignDestructured() throws Exception {
runTest("compiler/testData/codegen/box/primitiveTypes/reassignDestructured.kt");
}
@Test
@TestMetadata("stringEqualsHashCodeToString.kt")
public void testStringEqualsHashCodeToString() throws Exception {
@@ -35421,6 +35421,12 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest {
runTest("compiler/testData/codegen/box/primitiveTypes/rangeTo.kt");
}
@Test
@TestMetadata("reassignDestructured.kt")
public void testReassignDestructured() throws Exception {
runTest("compiler/testData/codegen/box/primitiveTypes/reassignDestructured.kt");
}
@Test
@TestMetadata("stringEqualsHashCodeToString.kt")
public void testStringEqualsHashCodeToString() throws Exception {
@@ -37323,6 +37323,12 @@ public class IrBlackBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTes
runTest("compiler/testData/codegen/box/primitiveTypes/rangeTo.kt");
}
@Test
@TestMetadata("reassignDestructured.kt")
public void testReassignDestructured() throws Exception {
runTest("compiler/testData/codegen/box/primitiveTypes/reassignDestructured.kt");
}
@Test
@TestMetadata("stringEqualsHashCodeToString.kt")
public void testStringEqualsHashCodeToString() throws Exception {
@@ -37323,6 +37323,12 @@ public class IrBlackBoxCodegenWithIrInlinerTestGenerated extends AbstractIrBlack
runTest("compiler/testData/codegen/box/primitiveTypes/rangeTo.kt");
}
@Test
@TestMetadata("reassignDestructured.kt")
public void testReassignDestructured() throws Exception {
runTest("compiler/testData/codegen/box/primitiveTypes/reassignDestructured.kt");
}
@Test
@TestMetadata("stringEqualsHashCodeToString.kt")
public void testStringEqualsHashCodeToString() throws Exception {
@@ -31907,6 +31907,11 @@ public class LightAnalysisModeTestGenerated extends AbstractLightAnalysisModeTes
runTest("compiler/testData/codegen/box/primitiveTypes/rangeTo.kt");
}
@TestMetadata("reassignDestructured.kt")
public void testReassignDestructured() throws Exception {
runTest("compiler/testData/codegen/box/primitiveTypes/reassignDestructured.kt");
}
@TestMetadata("stringEqualsHashCodeToString.kt")
public void testStringEqualsHashCodeToString() throws Exception {
runTest("compiler/testData/codegen/box/primitiveTypes/stringEqualsHashCodeToString.kt");
@@ -26853,6 +26853,12 @@ public class FirJsCodegenBoxTestGenerated extends AbstractFirJsCodegenBoxTest {
runTest("compiler/testData/codegen/box/primitiveTypes/rangeTo.kt");
}
@Test
@TestMetadata("reassignDestructured.kt")
public void testReassignDestructured() throws Exception {
runTest("compiler/testData/codegen/box/primitiveTypes/reassignDestructured.kt");
}
@Test
@TestMetadata("stringEqualsHashCodeToString.kt")
public void testStringEqualsHashCodeToString() throws Exception {
@@ -26853,6 +26853,12 @@ public class FirJsES6CodegenBoxTestGenerated extends AbstractFirJsES6CodegenBoxT
runTest("compiler/testData/codegen/box/primitiveTypes/rangeTo.kt");
}
@Test
@TestMetadata("reassignDestructured.kt")
public void testReassignDestructured() throws Exception {
runTest("compiler/testData/codegen/box/primitiveTypes/reassignDestructured.kt");
}
@Test
@TestMetadata("stringEqualsHashCodeToString.kt")
public void testStringEqualsHashCodeToString() throws Exception {
@@ -26289,6 +26289,12 @@ public class IrJsCodegenBoxTestGenerated extends AbstractIrJsCodegenBoxTest {
runTest("compiler/testData/codegen/box/primitiveTypes/rangeTo.kt");
}
@Test
@TestMetadata("reassignDestructured.kt")
public void testReassignDestructured() throws Exception {
runTest("compiler/testData/codegen/box/primitiveTypes/reassignDestructured.kt");
}
@Test
@TestMetadata("stringEqualsHashCodeToString.kt")
public void testStringEqualsHashCodeToString() throws Exception {
@@ -26289,6 +26289,12 @@ public class IrJsES6CodegenBoxTestGenerated extends AbstractIrJsES6CodegenBoxTes
runTest("compiler/testData/codegen/box/primitiveTypes/rangeTo.kt");
}
@Test
@TestMetadata("reassignDestructured.kt")
public void testReassignDestructured() throws Exception {
runTest("compiler/testData/codegen/box/primitiveTypes/reassignDestructured.kt");
}
@Test
@TestMetadata("stringEqualsHashCodeToString.kt")
public void testStringEqualsHashCodeToString() throws Exception {
@@ -30647,6 +30647,12 @@ public class FirNativeCodegenBoxTestGenerated extends AbstractNativeCodegenBoxTe
runTest("compiler/testData/codegen/box/primitiveTypes/rangeTo.kt");
}
@Test
@TestMetadata("reassignDestructured.kt")
public void testReassignDestructured() throws Exception {
runTest("compiler/testData/codegen/box/primitiveTypes/reassignDestructured.kt");
}
@Test
@TestMetadata("stringEqualsHashCodeToString.kt")
public void testStringEqualsHashCodeToString() throws Exception {
@@ -31345,6 +31345,12 @@ public class FirNativeCodegenBoxTestNoPLGenerated extends AbstractNativeCodegenB
runTest("compiler/testData/codegen/box/primitiveTypes/rangeTo.kt");
}
@Test
@TestMetadata("reassignDestructured.kt")
public void testReassignDestructured() throws Exception {
runTest("compiler/testData/codegen/box/primitiveTypes/reassignDestructured.kt");
}
@Test
@TestMetadata("stringEqualsHashCodeToString.kt")
public void testStringEqualsHashCodeToString() throws Exception {
@@ -29373,6 +29373,12 @@ public class NativeCodegenBoxTestGenerated extends AbstractNativeCodegenBoxTest
runTest("compiler/testData/codegen/box/primitiveTypes/rangeTo.kt");
}
@Test
@TestMetadata("reassignDestructured.kt")
public void testReassignDestructured() throws Exception {
runTest("compiler/testData/codegen/box/primitiveTypes/reassignDestructured.kt");
}
@Test
@TestMetadata("stringEqualsHashCodeToString.kt")
public void testStringEqualsHashCodeToString() throws Exception {
@@ -30060,6 +30060,12 @@ public class NativeCodegenBoxTestNoPLGenerated extends AbstractNativeCodegenBoxT
runTest("compiler/testData/codegen/box/primitiveTypes/rangeTo.kt");
}
@Test
@TestMetadata("reassignDestructured.kt")
public void testReassignDestructured() throws Exception {
runTest("compiler/testData/codegen/box/primitiveTypes/reassignDestructured.kt");
}
@Test
@TestMetadata("stringEqualsHashCodeToString.kt")
public void testStringEqualsHashCodeToString() throws Exception {
@@ -26817,6 +26817,12 @@ public class FirWasmJsCodegenBoxTestGenerated extends AbstractFirWasmJsCodegenBo
runTest("compiler/testData/codegen/box/primitiveTypes/rangeTo.kt");
}
@Test
@TestMetadata("reassignDestructured.kt")
public void testReassignDestructured() throws Exception {
runTest("compiler/testData/codegen/box/primitiveTypes/reassignDestructured.kt");
}
@Test
@TestMetadata("stringEqualsHashCodeToString.kt")
public void testStringEqualsHashCodeToString() throws Exception {
@@ -26253,6 +26253,12 @@ public class K1WasmCodegenBoxTestGenerated extends AbstractK1WasmCodegenBoxTest
runTest("compiler/testData/codegen/box/primitiveTypes/rangeTo.kt");
}
@Test
@TestMetadata("reassignDestructured.kt")
public void testReassignDestructured() throws Exception {
runTest("compiler/testData/codegen/box/primitiveTypes/reassignDestructured.kt");
}
@Test
@TestMetadata("stringEqualsHashCodeToString.kt")
public void testStringEqualsHashCodeToString() throws Exception {