From 71d6103122205a4cecfcc9a6658f7f1489c1b807 Mon Sep 17 00:00:00 2001 From: Dmitriy Novozhilov Date: Fri, 28 Apr 2023 14:47:25 +0300 Subject: [PATCH] [FIR] Report ASSIGNMENT_TYPE_MISMATCH on properties with numeric types ^KT-46047 ^KT-56951 Fixed --- .../fir/analysis/checkers/FirHelpers.kt | 9 ------- .../unaryMinusIndependentExpType.fir.kt | 18 ++++++------- .../unaryMinusIndependentExpType.fir.kt | 18 ++++++------- .../binaryMinusIndependentExpType.fir.kt | 22 ++++++++-------- .../tests/evaluate/divisionByZero.fir.kt | 2 +- .../tests/evaluate/parentesized.fir.kt | 8 +++--- .../unaryMinusIndependentExpType.fir.kt | 18 ++++++------- .../constantUnaryOperators.fir.kt | 26 +++++++++++++++++++ .../constantUnaryOperators.fir.txt | 2 +- .../integerLiterals/constantUnaryOperators.kt | 1 - .../diagnostics/tests/numbers/kt45970.fir.kt | 24 ++++++++--------- .../numbers/numbersInSimpleConstraints.fir.kt | 4 +-- ...assignmentOperationsCheckReturnType.fir.kt | 8 +++--- .../tests/regressions/kt2768.fir.kt | 20 ++++++++++++++ .../diagnostics/tests/regressions/kt2768.kt | 1 - .../evaluate/charCodeExpType.fir.kt | 6 ++--- 16 files changed, 111 insertions(+), 76 deletions(-) create mode 100644 compiler/testData/diagnostics/tests/integerLiterals/constantUnaryOperators.fir.kt create mode 100644 compiler/testData/diagnostics/tests/regressions/kt2768.fir.kt diff --git a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/FirHelpers.kt b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/FirHelpers.kt index 7e79d69f410..288a155b8c1 100644 --- a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/FirHelpers.kt +++ b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/FirHelpers.kt @@ -449,15 +449,6 @@ fun checkTypeMismatch( val typeContext = context.session.typeContext if (!isSubtypeForTypeMismatch(typeContext, subtype = rValueType, supertype = lValueType)) { - if (rValueType is ConeClassLikeType && - rValueType.lookupTag.classId == StandardClassIds.Int && - lValueType.fullyExpandedType(context.session).isIntegerTypeOrNullableIntegerTypeOfAnySize && - rValueType.nullability == ConeNullability.NOT_NULL - ) { - // val p: Byte = 42 or similar situation - // TODO: remove after fix of KT-46047 - return - } if (lValueType.isExtensionFunctionType || rValueType.isExtensionFunctionType) { // TODO: remove after fix of KT-45989 return diff --git a/compiler/testData/diagnostics/tests/constantEvaluator/constant/unaryMinusIndependentExpType.fir.kt b/compiler/testData/diagnostics/tests/constantEvaluator/constant/unaryMinusIndependentExpType.fir.kt index bb3c530e11c..e2ff88963f1 100644 --- a/compiler/testData/diagnostics/tests/constantEvaluator/constant/unaryMinusIndependentExpType.fir.kt +++ b/compiler/testData/diagnostics/tests/constantEvaluator/constant/unaryMinusIndependentExpType.fir.kt @@ -26,38 +26,38 @@ val l4: Short = -1.toLong() // val b1: -1 -val b1: Byte = -1.toByte() +val b1: Byte = -1.toByte() // val b2: -1 val b2: Int = -1.toByte() // val b3: -1 -val b3: Long = -1.toByte() +val b3: Long = -1.toByte() // val b4: -1 -val b4: Short = -1.toByte() +val b4: Short = -1.toByte() // val i1: -1 -val i1: Byte = -1.toInt() +val i1: Byte = -1.toInt() // val i2: -1 val i2: Int = -1.toInt() // val i3: -1 -val i3: Long = -1.toInt() +val i3: Long = -1.toInt() // val i4: -1 -val i4: Short = -1.toInt() +val i4: Short = -1.toInt() // val s1: -1 -val s1: Byte = -1.toShort() +val s1: Byte = -1.toShort() // val s2: -1 val s2: Int = -1.toShort() // val s3: -1 -val s3: Long = -1.toShort() +val s3: Long = -1.toShort() // val s4: -1 -val s4: Short = -1.toShort() +val s4: Short = -1.toShort() diff --git a/compiler/testData/diagnostics/tests/constantEvaluator/isPure/unaryMinusIndependentExpType.fir.kt b/compiler/testData/diagnostics/tests/constantEvaluator/isPure/unaryMinusIndependentExpType.fir.kt index b94cb48bcea..9ef2ccd3194 100644 --- a/compiler/testData/diagnostics/tests/constantEvaluator/isPure/unaryMinusIndependentExpType.fir.kt +++ b/compiler/testData/diagnostics/tests/constantEvaluator/isPure/unaryMinusIndependentExpType.fir.kt @@ -26,38 +26,38 @@ val l4: Short = -1.toLong() // val b1: false -val b1: Byte = -1.toByte() +val b1: Byte = -1.toByte() // val b2: false val b2: Int = -1.toByte() // val b3: false -val b3: Long = -1.toByte() +val b3: Long = -1.toByte() // val b4: false -val b4: Short = -1.toByte() +val b4: Short = -1.toByte() // val i1: false -val i1: Byte = -1.toInt() +val i1: Byte = -1.toInt() // val i2: false val i2: Int = -1.toInt() // val i3: false -val i3: Long = -1.toInt() +val i3: Long = -1.toInt() // val i4: false -val i4: Short = -1.toInt() +val i4: Short = -1.toInt() // val s1: false -val s1: Byte = -1.toShort() +val s1: Byte = -1.toShort() // val s2: false val s2: Int = -1.toShort() // val s3: false -val s3: Long = -1.toShort() +val s3: Long = -1.toShort() // val s4: false -val s4: Short = -1.toShort() +val s4: Short = -1.toShort() diff --git a/compiler/testData/diagnostics/tests/evaluate/binaryMinusIndependentExpType.fir.kt b/compiler/testData/diagnostics/tests/evaluate/binaryMinusIndependentExpType.fir.kt index c2f373c4320..351b07b3383 100644 --- a/compiler/testData/diagnostics/tests/evaluate/binaryMinusIndependentExpType.fir.kt +++ b/compiler/testData/diagnostics/tests/evaluate/binaryMinusIndependentExpType.fir.kt @@ -1,24 +1,24 @@ val p1: Int = 1 - 1 val p2: Long = 1 - 1 -val p3: Byte = 1 - 1 -val p4: Short = 1 - 1 +val p3: Byte = 1 - 1 +val p4: Short = 1 - 1 val l1: Long = 1 - 1.toLong() val l2: Byte = 1 - 1.toLong() val l3: Int = 1 - 1.toLong() val l4: Short = 1 - 1.toLong() -val b1: Byte = 1 - 1.toByte() +val b1: Byte = 1 - 1.toByte() val b2: Int = 1 - 1.toByte() -val b3: Long = 1 - 1.toByte() -val b4: Short = 1 - 1.toByte() +val b3: Long = 1 - 1.toByte() +val b4: Short = 1 - 1.toByte() -val i1: Byte = 1 - 1.toInt() +val i1: Byte = 1 - 1.toInt() val i2: Int = 1 - 1.toInt() -val i3: Long = 1 - 1.toInt() -val i4: Short = 1 - 1.toInt() +val i3: Long = 1 - 1.toInt() +val i4: Short = 1 - 1.toInt() -val s1: Byte = 1 - 1.toShort() +val s1: Byte = 1 - 1.toShort() val s2: Int = 1 - 1.toShort() -val s3: Long = 1 - 1.toShort() -val s4: Short = 1 - 1.toShort() +val s3: Long = 1 - 1.toShort() +val s4: Short = 1 - 1.toShort() diff --git a/compiler/testData/diagnostics/tests/evaluate/divisionByZero.fir.kt b/compiler/testData/diagnostics/tests/evaluate/divisionByZero.fir.kt index 47b040f446f..389bd92dc42 100644 --- a/compiler/testData/diagnostics/tests/evaluate/divisionByZero.fir.kt +++ b/compiler/testData/diagnostics/tests/evaluate/divisionByZero.fir.kt @@ -15,7 +15,7 @@ val a10 = 1 / 0.0f val a11 = 1 / 0.0 val a12 = 1L / 0 -val b1: Byte = 1 / 0 +val b1: Byte = 1 / 0 @Ann(1 / 0) val b2 = 1 annotation class Ann(val i : Int) diff --git a/compiler/testData/diagnostics/tests/evaluate/parentesized.fir.kt b/compiler/testData/diagnostics/tests/evaluate/parentesized.fir.kt index 3d872367ba6..ad680ac57a6 100644 --- a/compiler/testData/diagnostics/tests/evaluate/parentesized.fir.kt +++ b/compiler/testData/diagnostics/tests/evaluate/parentesized.fir.kt @@ -1,10 +1,10 @@ -val p1: Byte = (1 + 2) * 2 -val p2: Short = (1 + 2) * 2 +val p1: Byte = (1 + 2) * 2 +val p2: Short = (1 + 2) * 2 val p3: Int = (1 + 2) * 2 val p4: Long = (1 + 2) * 2 -val b1: Byte = (1.toByte() + 2) * 2 -val b2: Short = (1.toShort() + 2) * 2 +val b1: Byte = (1.toByte() + 2) * 2 +val b2: Short = (1.toShort() + 2) * 2 val b3: Int = (1.toInt() + 2) * 2 val b4: Long = (1.toLong() + 2) * 2 diff --git a/compiler/testData/diagnostics/tests/evaluate/unaryMinusIndependentExpType.fir.kt b/compiler/testData/diagnostics/tests/evaluate/unaryMinusIndependentExpType.fir.kt index 6dac0591615..8a559fc452c 100644 --- a/compiler/testData/diagnostics/tests/evaluate/unaryMinusIndependentExpType.fir.kt +++ b/compiler/testData/diagnostics/tests/evaluate/unaryMinusIndependentExpType.fir.kt @@ -13,17 +13,17 @@ val l2: Byte = -1.toLong() val l3: Int = -1.toLong() val l4: Short = -1.toLong() -val b1: Byte = -1.toByte() +val b1: Byte = -1.toByte() val b2: Int = -1.toByte() -val b3: Long = -1.toByte() -val b4: Short = -1.toByte() +val b3: Long = -1.toByte() +val b4: Short = -1.toByte() -val i1: Byte = -1.toInt() +val i1: Byte = -1.toInt() val i2: Int = -1.toInt() -val i3: Long = -1.toInt() -val i4: Short = -1.toInt() +val i3: Long = -1.toInt() +val i4: Short = -1.toInt() -val s1: Byte = -1.toShort() +val s1: Byte = -1.toShort() val s2: Int = -1.toShort() -val s3: Long = -1.toShort() -val s4: Short = -1.toShort() +val s3: Long = -1.toShort() +val s4: Short = -1.toShort() diff --git a/compiler/testData/diagnostics/tests/integerLiterals/constantUnaryOperators.fir.kt b/compiler/testData/diagnostics/tests/integerLiterals/constantUnaryOperators.fir.kt new file mode 100644 index 00000000000..823e6e68add --- /dev/null +++ b/compiler/testData/diagnostics/tests/integerLiterals/constantUnaryOperators.fir.kt @@ -0,0 +1,26 @@ +// SKIP_TXT +// FIR_DUMP + +// ------------- const ------------- + +val i1 = (2 + 2 * 3).inv() +val l1: Long = (2 + 2 * 3).inv() +val ll1 = (3000000000 * 2 + 1).inv() + +val i2 = (2 + 2 * 3).unaryPlus() +val l2: Long = (2 + 2 * 3).unaryPlus() +val ll2 = (3000000000 * 2 + 1).unaryPlus() + +val i3 = (2 + 2 * 3).unaryMinus() +val l3: Long = (2 + 2 * 3).unaryMinus() +val ll3 = (3000000000 * 2 + 1).unaryMinus() + +// ------------- non const ------------- + +val i4 = (2 + 2 * 3).inc() +val l4: Long = (2 + 2 * 3).inc() +val ll4 = (3000000000 * 2 + 1).inc() + +val i5 = (2 + 2 * 3).dec() +val l5: Long = (2 + 2 * 3).dec() +val ll5 = (3000000000 * 2 + 1).dec() diff --git a/compiler/testData/diagnostics/tests/integerLiterals/constantUnaryOperators.fir.txt b/compiler/testData/diagnostics/tests/integerLiterals/constantUnaryOperators.fir.txt index f775f20f7ca..73cf1be59b7 100644 --- a/compiler/testData/diagnostics/tests/integerLiterals/constantUnaryOperators.fir.txt +++ b/compiler/testData/diagnostics/tests/integerLiterals/constantUnaryOperators.fir.txt @@ -1,4 +1,4 @@ -FILE: constantUnaryOperators.kt +FILE: constantUnaryOperators.fir.kt public final val i1: R|kotlin/Int| = Int(2).R|kotlin/Int.plus|(Int(2).R|kotlin/Int.times|(Int(3))).R|kotlin/Int.inv|() public get(): R|kotlin/Int| public final val l1: R|kotlin/Long| = Int(2).R|kotlin/Int.plus|(Int(2).R|kotlin/Int.times|(Int(3))).R|kotlin/Int.inv|().R|kotlin/Int.toLong|() diff --git a/compiler/testData/diagnostics/tests/integerLiterals/constantUnaryOperators.kt b/compiler/testData/diagnostics/tests/integerLiterals/constantUnaryOperators.kt index 62b6935b4c8..75ac9fcb807 100644 --- a/compiler/testData/diagnostics/tests/integerLiterals/constantUnaryOperators.kt +++ b/compiler/testData/diagnostics/tests/integerLiterals/constantUnaryOperators.kt @@ -1,4 +1,3 @@ -// FIR_IDENTICAL // SKIP_TXT // FIR_DUMP diff --git a/compiler/testData/diagnostics/tests/numbers/kt45970.fir.kt b/compiler/testData/diagnostics/tests/numbers/kt45970.fir.kt index 306f7eb37ad..54ccccff38e 100644 --- a/compiler/testData/diagnostics/tests/numbers/kt45970.fir.kt +++ b/compiler/testData/diagnostics/tests/numbers/kt45970.fir.kt @@ -9,10 +9,10 @@ var c_2: Int = 1 val d_1: Long = 1 var d_2: Long = 1 -val e_1: Byte = 1 + 2 -var e_2: Byte = 1 + 2 -val f_1: Short = 1 + 2 -var f_2: Short = 1 + 2 +val e_1: Byte = 1 + 2 +var e_2: Byte = 1 + 2 +val f_1: Short = 1 + 2 +var f_2: Short = 1 + 2 val g_1: Int = 1 + 2 var g_2: Int = 1 + 2 val h_1: Long = 1 + 2 @@ -28,10 +28,10 @@ fun local() { val d_1: Long = 1 var d_2: Long = 1 - val e_1: Byte = 1 + 2 - var e_2: Byte = 1 + 2 - val f_1: Short = 1 + 2 - var f_2: Short = 1 + 2 + val e_1: Byte = 1 + 2 + var e_2: Byte = 1 + 2 + val f_1: Short = 1 + 2 + var f_2: Short = 1 + 2 val g_1: Int = 1 + 2 var g_2: Int = 1 + 2 val h_1: Long = 1 + 2 @@ -48,10 +48,10 @@ class Member { val d_1: Long = 1 var d_2: Long = 1 - val e_1: Byte = 1 + 2 - var e_2: Byte = 1 + 2 - val f_1: Short = 1 + 2 - var f_2: Short = 1 + 2 + val e_1: Byte = 1 + 2 + var e_2: Byte = 1 + 2 + val f_1: Short = 1 + 2 + var f_2: Short = 1 + 2 val g_1: Int = 1 + 2 var g_2: Int = 1 + 2 val h_1: Long = 1 + 2 diff --git a/compiler/testData/diagnostics/tests/numbers/numbersInSimpleConstraints.fir.kt b/compiler/testData/diagnostics/tests/numbers/numbersInSimpleConstraints.fir.kt index c8284c76053..4f6ef9d1c8d 100644 --- a/compiler/testData/diagnostics/tests/numbers/numbersInSimpleConstraints.fir.kt +++ b/compiler/testData/diagnostics/tests/numbers/numbersInSimpleConstraints.fir.kt @@ -16,7 +16,7 @@ fun otherGeneric(l: List) {} fun test() { val a: Byte = id(1) - val b: Byte = id(300) + val b: Byte = id(300) val c: Int = id(9223372036854775807) @@ -28,7 +28,7 @@ fun test() { val f: Byte = either(1, 2) - val g: Byte = either(1, 300) + val g: Byte = either(1, 300) other(11) diff --git a/compiler/testData/diagnostics/tests/operatorsOverloading/assignmentOperationsCheckReturnType.fir.kt b/compiler/testData/diagnostics/tests/operatorsOverloading/assignmentOperationsCheckReturnType.fir.kt index 7466d989ab7..c6d1c9caf6f 100644 --- a/compiler/testData/diagnostics/tests/operatorsOverloading/assignmentOperationsCheckReturnType.fir.kt +++ b/compiler/testData/diagnostics/tests/operatorsOverloading/assignmentOperationsCheckReturnType.fir.kt @@ -17,15 +17,15 @@ fun intBinEq() { fun shortBinEq() { var x = 0.toShort() x += 'a' - x += 1.toByte() - x += 1.toShort() + x += 1.toByte() + x += 1.toShort() x += 1L x += 1f x += 1.0 x *= 'a' - x *= 1.toByte() - x *= 1.toShort() + x *= 1.toByte() + x *= 1.toShort() x *= 1L x *= 1f x *= 1.0 diff --git a/compiler/testData/diagnostics/tests/regressions/kt2768.fir.kt b/compiler/testData/diagnostics/tests/regressions/kt2768.fir.kt new file mode 100644 index 00000000000..f92eb6ee896 --- /dev/null +++ b/compiler/testData/diagnostics/tests/regressions/kt2768.fir.kt @@ -0,0 +1,20 @@ +fun assertEquals(a: T, b: T) { + if (a != b) throw AssertionError("$a != $b") +} + +fun main() { + val bytePos = 128.toByte() // Byte.MAX_VALUE + 1 + assertEquals(-128, bytePos.toInt()) // correct, wrapped to Byte.MIN_VALUE + + val byteNeg: Byte = -bytePos // should not compile, byteNeg should be Int + assertEquals(128, byteNeg.toInt()) // passes, should not be possible + + val shortPos = 32768.toShort() // Short.MAX_VALUE + 1 + assertEquals(-32768, shortPos.toInt()) // correct, wrapped to Short.MIN_VALUE + + val shortNeg: Short = -shortPos // should not compile, shortNeg should be Int + assertEquals(32768, shortNeg.toInt()) // passes, should not be possible + + (-128).toByte() + -128.toByte() +} diff --git a/compiler/testData/diagnostics/tests/regressions/kt2768.kt b/compiler/testData/diagnostics/tests/regressions/kt2768.kt index 7ce3503d1e4..afe608eadbe 100644 --- a/compiler/testData/diagnostics/tests/regressions/kt2768.kt +++ b/compiler/testData/diagnostics/tests/regressions/kt2768.kt @@ -1,4 +1,3 @@ -// FIR_IDENTICAL fun assertEquals(a: T, b: T) { if (a != b) throw AssertionError("$a != $b") } diff --git a/compiler/testData/diagnostics/testsWithStdLib/evaluate/charCodeExpType.fir.kt b/compiler/testData/diagnostics/testsWithStdLib/evaluate/charCodeExpType.fir.kt index 27f7572518e..5e0d9618085 100644 --- a/compiler/testData/diagnostics/testsWithStdLib/evaluate/charCodeExpType.fir.kt +++ b/compiler/testData/diagnostics/testsWithStdLib/evaluate/charCodeExpType.fir.kt @@ -3,6 +3,6 @@ const val p2: Long = '\n'.code.toLong() const val p3: Byte = '\n'.code.toByte() const val p4: Short = '\n'.code.toShort() -const val e2: Long = '\n'.code -const val e3: Byte = '\n'.code -const val e4: Short = '\n'.code +const val e2: Long = '\n'.code +const val e3: Byte = '\n'.code +const val e4: Short = '\n'.code