[FIR] Report ASSIGNMENT_TYPE_MISMATCH on properties with numeric types

^KT-46047
^KT-56951 Fixed
This commit is contained in:
Dmitriy Novozhilov
2023-04-28 14:47:25 +03:00
committed by Space Team
parent f7733e819d
commit 71d6103122
16 changed files with 111 additions and 76 deletions
@@ -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
@@ -26,38 +26,38 @@ val l4: Short = <!INITIALIZER_TYPE_MISMATCH, TYPE_MISMATCH!>-1.toLong()<!>
// val b1: -1
val b1: Byte = <!TYPE_MISMATCH!>-1.toByte()<!>
val b1: Byte = <!INITIALIZER_TYPE_MISMATCH, TYPE_MISMATCH!>-1.toByte()<!>
// val b2: -1
val b2: Int = -1.toByte()
// val b3: -1
val b3: Long = <!TYPE_MISMATCH!>-1.toByte()<!>
val b3: Long = <!INITIALIZER_TYPE_MISMATCH, TYPE_MISMATCH!>-1.toByte()<!>
// val b4: -1
val b4: Short = <!TYPE_MISMATCH!>-1.toByte()<!>
val b4: Short = <!INITIALIZER_TYPE_MISMATCH, TYPE_MISMATCH!>-1.toByte()<!>
// val i1: -1
val i1: Byte = <!TYPE_MISMATCH!>-1.toInt()<!>
val i1: Byte = <!INITIALIZER_TYPE_MISMATCH, TYPE_MISMATCH!>-1.toInt()<!>
// val i2: -1
val i2: Int = -1.toInt()
// val i3: -1
val i3: Long = <!TYPE_MISMATCH!>-1.toInt()<!>
val i3: Long = <!INITIALIZER_TYPE_MISMATCH, TYPE_MISMATCH!>-1.toInt()<!>
// val i4: -1
val i4: Short = <!TYPE_MISMATCH!>-1.toInt()<!>
val i4: Short = <!INITIALIZER_TYPE_MISMATCH, TYPE_MISMATCH!>-1.toInt()<!>
// val s1: -1
val s1: Byte = <!TYPE_MISMATCH!>-1.toShort()<!>
val s1: Byte = <!INITIALIZER_TYPE_MISMATCH, TYPE_MISMATCH!>-1.toShort()<!>
// val s2: -1
val s2: Int = -1.toShort()
// val s3: -1
val s3: Long = <!TYPE_MISMATCH!>-1.toShort()<!>
val s3: Long = <!INITIALIZER_TYPE_MISMATCH, TYPE_MISMATCH!>-1.toShort()<!>
// val s4: -1
val s4: Short = <!TYPE_MISMATCH!>-1.toShort()<!>
val s4: Short = <!INITIALIZER_TYPE_MISMATCH, TYPE_MISMATCH!>-1.toShort()<!>
@@ -26,38 +26,38 @@ val l4: Short = <!INITIALIZER_TYPE_MISMATCH, TYPE_MISMATCH!>-1.toLong()<!>
// val b1: false
val b1: Byte = <!TYPE_MISMATCH!>-1.toByte()<!>
val b1: Byte = <!INITIALIZER_TYPE_MISMATCH, TYPE_MISMATCH!>-1.toByte()<!>
// val b2: false
val b2: Int = -1.toByte()
// val b3: false
val b3: Long = <!TYPE_MISMATCH!>-1.toByte()<!>
val b3: Long = <!INITIALIZER_TYPE_MISMATCH, TYPE_MISMATCH!>-1.toByte()<!>
// val b4: false
val b4: Short = <!TYPE_MISMATCH!>-1.toByte()<!>
val b4: Short = <!INITIALIZER_TYPE_MISMATCH, TYPE_MISMATCH!>-1.toByte()<!>
// val i1: false
val i1: Byte = <!TYPE_MISMATCH!>-1.toInt()<!>
val i1: Byte = <!INITIALIZER_TYPE_MISMATCH, TYPE_MISMATCH!>-1.toInt()<!>
// val i2: false
val i2: Int = -1.toInt()
// val i3: false
val i3: Long = <!TYPE_MISMATCH!>-1.toInt()<!>
val i3: Long = <!INITIALIZER_TYPE_MISMATCH, TYPE_MISMATCH!>-1.toInt()<!>
// val i4: false
val i4: Short = <!TYPE_MISMATCH!>-1.toInt()<!>
val i4: Short = <!INITIALIZER_TYPE_MISMATCH, TYPE_MISMATCH!>-1.toInt()<!>
// val s1: false
val s1: Byte = <!TYPE_MISMATCH!>-1.toShort()<!>
val s1: Byte = <!INITIALIZER_TYPE_MISMATCH, TYPE_MISMATCH!>-1.toShort()<!>
// val s2: false
val s2: Int = -1.toShort()
// val s3: false
val s3: Long = <!TYPE_MISMATCH!>-1.toShort()<!>
val s3: Long = <!INITIALIZER_TYPE_MISMATCH, TYPE_MISMATCH!>-1.toShort()<!>
// val s4: false
val s4: Short = <!TYPE_MISMATCH!>-1.toShort()<!>
val s4: Short = <!INITIALIZER_TYPE_MISMATCH, TYPE_MISMATCH!>-1.toShort()<!>
@@ -1,24 +1,24 @@
val p1: Int = 1 - 1
val p2: Long = 1 - 1
val p3: Byte = <!TYPE_MISMATCH!>1 - 1<!>
val p4: Short = <!TYPE_MISMATCH!>1 - 1<!>
val p3: Byte = <!INITIALIZER_TYPE_MISMATCH, TYPE_MISMATCH!>1 - 1<!>
val p4: Short = <!INITIALIZER_TYPE_MISMATCH, TYPE_MISMATCH!>1 - 1<!>
val l1: Long = 1 - 1.toLong()
val l2: Byte = <!INITIALIZER_TYPE_MISMATCH, TYPE_MISMATCH!>1 - 1.toLong()<!>
val l3: Int = <!INITIALIZER_TYPE_MISMATCH, TYPE_MISMATCH!>1 - 1.toLong()<!>
val l4: Short = <!INITIALIZER_TYPE_MISMATCH, TYPE_MISMATCH!>1 - 1.toLong()<!>
val b1: Byte = <!TYPE_MISMATCH!>1 - 1.toByte()<!>
val b1: Byte = <!INITIALIZER_TYPE_MISMATCH, TYPE_MISMATCH!>1 - 1.toByte()<!>
val b2: Int = 1 - 1.toByte()
val b3: Long = <!TYPE_MISMATCH!>1 - 1.toByte()<!>
val b4: Short = <!TYPE_MISMATCH!>1 - 1.toByte()<!>
val b3: Long = <!INITIALIZER_TYPE_MISMATCH, TYPE_MISMATCH!>1 - 1.toByte()<!>
val b4: Short = <!INITIALIZER_TYPE_MISMATCH, TYPE_MISMATCH!>1 - 1.toByte()<!>
val i1: Byte = <!TYPE_MISMATCH!>1 - 1.toInt()<!>
val i1: Byte = <!INITIALIZER_TYPE_MISMATCH, TYPE_MISMATCH!>1 - 1.toInt()<!>
val i2: Int = 1 - 1.toInt()
val i3: Long = <!TYPE_MISMATCH!>1 - 1.toInt()<!>
val i4: Short = <!TYPE_MISMATCH!>1 - 1.toInt()<!>
val i3: Long = <!INITIALIZER_TYPE_MISMATCH, TYPE_MISMATCH!>1 - 1.toInt()<!>
val i4: Short = <!INITIALIZER_TYPE_MISMATCH, TYPE_MISMATCH!>1 - 1.toInt()<!>
val s1: Byte = <!TYPE_MISMATCH!>1 - 1.toShort()<!>
val s1: Byte = <!INITIALIZER_TYPE_MISMATCH, TYPE_MISMATCH!>1 - 1.toShort()<!>
val s2: Int = 1 - 1.toShort()
val s3: Long = <!TYPE_MISMATCH!>1 - 1.toShort()<!>
val s4: Short = <!TYPE_MISMATCH!>1 - 1.toShort()<!>
val s3: Long = <!INITIALIZER_TYPE_MISMATCH, TYPE_MISMATCH!>1 - 1.toShort()<!>
val s4: Short = <!INITIALIZER_TYPE_MISMATCH, TYPE_MISMATCH!>1 - 1.toShort()<!>
@@ -15,7 +15,7 @@ val a10 = <!DIVISION_BY_ZERO!>1 / 0.0f<!>
val a11 = <!DIVISION_BY_ZERO!>1 / 0.0<!>
val a12 = <!DIVISION_BY_ZERO!>1L / 0<!>
val b1: Byte = <!DIVISION_BY_ZERO, TYPE_MISMATCH!>1 / 0<!>
val b1: Byte = <!DIVISION_BY_ZERO, INITIALIZER_TYPE_MISMATCH, TYPE_MISMATCH!>1 / 0<!>
@Ann(<!DIVISION_BY_ZERO!>1 / 0<!>) val b2 = 1
annotation class Ann(val i : Int)
@@ -1,10 +1,10 @@
val p1: Byte = <!TYPE_MISMATCH!>(1 + 2) * 2<!>
val p2: Short = <!TYPE_MISMATCH!>(1 + 2) * 2<!>
val p1: Byte = <!INITIALIZER_TYPE_MISMATCH, TYPE_MISMATCH!>(1 + 2) * 2<!>
val p2: Short = <!INITIALIZER_TYPE_MISMATCH, TYPE_MISMATCH!>(1 + 2) * 2<!>
val p3: Int = (1 + 2) * 2
val p4: Long = (1 + 2) * 2
val b1: Byte = <!TYPE_MISMATCH!>(1.toByte() + 2) * 2<!>
val b2: Short = <!TYPE_MISMATCH!>(1.toShort() + 2) * 2<!>
val b1: Byte = <!INITIALIZER_TYPE_MISMATCH, TYPE_MISMATCH!>(1.toByte() + 2) * 2<!>
val b2: Short = <!INITIALIZER_TYPE_MISMATCH, TYPE_MISMATCH!>(1.toShort() + 2) * 2<!>
val b3: Int = (1.toInt() + 2) * 2
val b4: Long = (1.toLong() + 2) * 2
@@ -13,17 +13,17 @@ val l2: Byte = <!INITIALIZER_TYPE_MISMATCH, TYPE_MISMATCH!>-1.toLong()<!>
val l3: Int = <!INITIALIZER_TYPE_MISMATCH, TYPE_MISMATCH!>-1.toLong()<!>
val l4: Short = <!INITIALIZER_TYPE_MISMATCH, TYPE_MISMATCH!>-1.toLong()<!>
val b1: Byte = <!TYPE_MISMATCH!>-1.toByte()<!>
val b1: Byte = <!INITIALIZER_TYPE_MISMATCH, TYPE_MISMATCH!>-1.toByte()<!>
val b2: Int = -1.toByte()
val b3: Long = <!TYPE_MISMATCH!>-1.toByte()<!>
val b4: Short = <!TYPE_MISMATCH!>-1.toByte()<!>
val b3: Long = <!INITIALIZER_TYPE_MISMATCH, TYPE_MISMATCH!>-1.toByte()<!>
val b4: Short = <!INITIALIZER_TYPE_MISMATCH, TYPE_MISMATCH!>-1.toByte()<!>
val i1: Byte = <!TYPE_MISMATCH!>-1.toInt()<!>
val i1: Byte = <!INITIALIZER_TYPE_MISMATCH, TYPE_MISMATCH!>-1.toInt()<!>
val i2: Int = -1.toInt()
val i3: Long = <!TYPE_MISMATCH!>-1.toInt()<!>
val i4: Short = <!TYPE_MISMATCH!>-1.toInt()<!>
val i3: Long = <!INITIALIZER_TYPE_MISMATCH, TYPE_MISMATCH!>-1.toInt()<!>
val i4: Short = <!INITIALIZER_TYPE_MISMATCH, TYPE_MISMATCH!>-1.toInt()<!>
val s1: Byte = <!TYPE_MISMATCH!>-1.toShort()<!>
val s1: Byte = <!INITIALIZER_TYPE_MISMATCH, TYPE_MISMATCH!>-1.toShort()<!>
val s2: Int = -1.toShort()
val s3: Long = <!TYPE_MISMATCH!>-1.toShort()<!>
val s4: Short = <!TYPE_MISMATCH!>-1.toShort()<!>
val s3: Long = <!INITIALIZER_TYPE_MISMATCH, TYPE_MISMATCH!>-1.toShort()<!>
val s4: Short = <!INITIALIZER_TYPE_MISMATCH, TYPE_MISMATCH!>-1.toShort()<!>
@@ -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 = <!INITIALIZER_TYPE_MISMATCH, TYPE_MISMATCH!>(2 + 2 * 3).inc()<!>
val ll4 = (3000000000 * 2 + 1).inc()
val i5 = (2 + 2 * 3).dec()
val l5: Long = <!INITIALIZER_TYPE_MISMATCH, TYPE_MISMATCH!>(2 + 2 * 3).dec()<!>
val ll5 = (3000000000 * 2 + 1).dec()
@@ -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|()
@@ -1,4 +1,3 @@
// FIR_IDENTICAL
// SKIP_TXT
// FIR_DUMP
+12 -12
View File
@@ -9,10 +9,10 @@ var c_2: Int = 1
val d_1: Long = 1
var d_2: Long = 1
val e_1: Byte = <!TYPE_MISMATCH!>1 + 2<!>
var e_2: Byte = <!TYPE_MISMATCH!>1 + 2<!>
val f_1: Short = <!TYPE_MISMATCH!>1 + 2<!>
var f_2: Short = <!TYPE_MISMATCH!>1 + 2<!>
val e_1: Byte = <!INITIALIZER_TYPE_MISMATCH, TYPE_MISMATCH!>1 + 2<!>
var e_2: Byte = <!INITIALIZER_TYPE_MISMATCH, TYPE_MISMATCH!>1 + 2<!>
val f_1: Short = <!INITIALIZER_TYPE_MISMATCH, TYPE_MISMATCH!>1 + 2<!>
var f_2: Short = <!INITIALIZER_TYPE_MISMATCH, TYPE_MISMATCH!>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 = <!TYPE_MISMATCH!>1 + 2<!>
var e_2: Byte = <!TYPE_MISMATCH!>1 + 2<!>
val f_1: Short = <!TYPE_MISMATCH!>1 + 2<!>
var f_2: Short = <!TYPE_MISMATCH!>1 + 2<!>
val e_1: Byte = <!INITIALIZER_TYPE_MISMATCH, TYPE_MISMATCH!>1 + 2<!>
var e_2: Byte = <!INITIALIZER_TYPE_MISMATCH, TYPE_MISMATCH!>1 + 2<!>
val f_1: Short = <!INITIALIZER_TYPE_MISMATCH, TYPE_MISMATCH!>1 + 2<!>
var f_2: Short = <!INITIALIZER_TYPE_MISMATCH, TYPE_MISMATCH!>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 = <!TYPE_MISMATCH!>1 + 2<!>
var e_2: Byte = <!TYPE_MISMATCH!>1 + 2<!>
val f_1: Short = <!TYPE_MISMATCH!>1 + 2<!>
var f_2: Short = <!TYPE_MISMATCH!>1 + 2<!>
val e_1: Byte = <!INITIALIZER_TYPE_MISMATCH, TYPE_MISMATCH!>1 + 2<!>
var e_2: Byte = <!INITIALIZER_TYPE_MISMATCH, TYPE_MISMATCH!>1 + 2<!>
val f_1: Short = <!INITIALIZER_TYPE_MISMATCH, TYPE_MISMATCH!>1 + 2<!>
var f_2: Short = <!INITIALIZER_TYPE_MISMATCH, TYPE_MISMATCH!>1 + 2<!>
val g_1: Int = 1 + 2
var g_2: Int = 1 + 2
val h_1: Long = 1 + 2
@@ -16,7 +16,7 @@ fun <T> otherGeneric(l: List<T>) {}
fun test() {
val a: Byte = id(1)
val b: Byte = <!TYPE_MISMATCH!>id(300)<!>
val b: Byte = <!INITIALIZER_TYPE_MISMATCH, TYPE_MISMATCH!>id(300)<!>
val c: Int = <!INITIALIZER_TYPE_MISMATCH, TYPE_MISMATCH!>id(9223372036854775807)<!>
@@ -28,7 +28,7 @@ fun test() {
val f: Byte = either(1, 2)
val g: Byte = <!TYPE_MISMATCH!>either(1, 300)<!>
val g: Byte = <!INITIALIZER_TYPE_MISMATCH, TYPE_MISMATCH!>either(1, 300)<!>
other(<!ARGUMENT_TYPE_MISMATCH!>11<!>)
@@ -17,15 +17,15 @@ fun intBinEq() {
fun shortBinEq() {
var x = 0.toShort()
x <!NONE_APPLICABLE!>+=<!> 'a'
x += 1.toByte()
x += 1.toShort()
<!ASSIGNMENT_TYPE_MISMATCH!>x += 1.toByte()<!>
<!ASSIGNMENT_TYPE_MISMATCH!>x += 1.toShort()<!>
<!ASSIGNMENT_TYPE_MISMATCH!>x += 1L<!>
<!ASSIGNMENT_TYPE_MISMATCH!>x += 1f<!>
<!ASSIGNMENT_TYPE_MISMATCH!>x += 1.0<!>
x <!NONE_APPLICABLE!>*=<!> 'a'
x *= 1.toByte()
x *= 1.toShort()
<!ASSIGNMENT_TYPE_MISMATCH!>x *= 1.toByte()<!>
<!ASSIGNMENT_TYPE_MISMATCH!>x *= 1.toShort()<!>
<!ASSIGNMENT_TYPE_MISMATCH!>x *= 1L<!>
<!ASSIGNMENT_TYPE_MISMATCH!>x *= 1f<!>
<!ASSIGNMENT_TYPE_MISMATCH!>x *= 1.0<!>
@@ -0,0 +1,20 @@
fun <T> 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 = <!INITIALIZER_TYPE_MISMATCH, TYPE_MISMATCH!>-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 = <!INITIALIZER_TYPE_MISMATCH, TYPE_MISMATCH!>-shortPos<!> // should not compile, shortNeg should be Int
assertEquals(32768, shortNeg.toInt()) // passes, should not be possible
(-128).toByte()
-128.toByte()
}
@@ -1,4 +1,3 @@
// FIR_IDENTICAL
fun <T> assertEquals(a: T, b: T) {
if (a != b) throw AssertionError("$a != $b")
}
@@ -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 = <!INITIALIZER_TYPE_MISMATCH!>'\n'.code<!>
const val e3: Byte = <!INITIALIZER_TYPE_MISMATCH!>'\n'.code<!>
const val e4: Short = <!INITIALIZER_TYPE_MISMATCH!>'\n'.code<!>