FIR initializer: don't report type mismatch in SomeInt = Int case
This commit is contained in:
+11
-2
@@ -12,9 +12,10 @@ import org.jetbrains.kotlin.fir.analysis.checkers.isSubtypeForTypeMismatch
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.DiagnosticReporter
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.INITIALIZER_TYPE_MISMATCH
|
||||
import org.jetbrains.kotlin.fir.declarations.FirProperty
|
||||
import org.jetbrains.kotlin.fir.resolve.fullyExpandedType
|
||||
import org.jetbrains.kotlin.fir.typeContext
|
||||
import org.jetbrains.kotlin.fir.types.ConeKotlinType
|
||||
import org.jetbrains.kotlin.fir.types.coneTypeSafe
|
||||
import org.jetbrains.kotlin.fir.types.*
|
||||
import org.jetbrains.kotlin.name.StandardClassIds
|
||||
|
||||
object FirInitializerTypeMismatchChecker : FirPropertyChecker() {
|
||||
override fun check(declaration: FirProperty, context: CheckerContext, reporter: DiagnosticReporter) {
|
||||
@@ -26,6 +27,14 @@ object FirInitializerTypeMismatchChecker : FirPropertyChecker() {
|
||||
val typeContext = context.session.typeContext
|
||||
|
||||
if (!isSubtypeForTypeMismatch(typeContext, subtype = expressionType, supertype = propertyType)) {
|
||||
if (expressionType is ConeClassLikeType &&
|
||||
expressionType.lookupTag.classId == StandardClassIds.Int &&
|
||||
propertyType.fullyExpandedType(context.session).isIntegerTypeOrNullableIntegerTypeOfAnySize &&
|
||||
expressionType.nullability == ConeNullability.NOT_NULL
|
||||
) {
|
||||
// val p: Byte = 42 or similar situation
|
||||
return
|
||||
}
|
||||
val source = declaration.source ?: return
|
||||
reporter.report(INITIALIZER_TYPE_MISMATCH.on(source, propertyType, expressionType), context)
|
||||
}
|
||||
|
||||
@@ -76,6 +76,9 @@ val ConeKotlinType.isNonPrimitiveArray: Boolean
|
||||
private val builtinUnsignedTypes = setOf(StandardClassIds.UInt, StandardClassIds.UByte, StandardClassIds.ULong, StandardClassIds.UShort)
|
||||
val ConeKotlinType.isUnsignedTypeOrNullableUnsignedType: Boolean get() = isAnyOfBuiltinType(builtinUnsignedTypes)
|
||||
|
||||
private val builtinIntegerTypes = setOf(StandardClassIds.Int, StandardClassIds.Byte, StandardClassIds.Long, StandardClassIds.Short)
|
||||
val ConeKotlinType.isIntegerTypeOrNullableIntegerTypeOfAnySize: Boolean get() = isAnyOfBuiltinType(builtinIntegerTypes)
|
||||
|
||||
private fun ConeKotlinType.isBuiltinType(classId: ClassId, isNullable: Boolean): Boolean {
|
||||
if (this !is ConeClassLikeType) return false
|
||||
return lookupTag.classId == classId && type.isNullable == isNullable
|
||||
|
||||
+12
-12
@@ -1,24 +1,24 @@
|
||||
val p1: Int = 1 - 1
|
||||
val p2: Long = <!INITIALIZER_TYPE_MISMATCH!>1 - 1<!>
|
||||
val p3: Byte = <!INITIALIZER_TYPE_MISMATCH!>1 - 1<!>
|
||||
val p4: Short = <!INITIALIZER_TYPE_MISMATCH!>1 - 1<!>
|
||||
val p2: Long = 1 - 1
|
||||
val p3: Byte = 1 - 1
|
||||
val p4: Short = 1 - 1
|
||||
|
||||
val l1: Long = 1 - 1.toLong()
|
||||
val l2: Byte = <!INITIALIZER_TYPE_MISMATCH!>1 - 1.toLong()<!>
|
||||
val l3: Int = <!INITIALIZER_TYPE_MISMATCH!>1 - 1.toLong()<!>
|
||||
val l4: Short = <!INITIALIZER_TYPE_MISMATCH!>1 - 1.toLong()<!>
|
||||
|
||||
val b1: Byte = <!INITIALIZER_TYPE_MISMATCH!>1 - 1.toByte()<!>
|
||||
val b1: Byte = 1 - 1.toByte()
|
||||
val b2: Int = 1 - 1.toByte()
|
||||
val b3: Long = <!INITIALIZER_TYPE_MISMATCH!>1 - 1.toByte()<!>
|
||||
val b4: Short = <!INITIALIZER_TYPE_MISMATCH!>1 - 1.toByte()<!>
|
||||
val b3: Long = 1 - 1.toByte()
|
||||
val b4: Short = 1 - 1.toByte()
|
||||
|
||||
val i1: Byte = <!INITIALIZER_TYPE_MISMATCH!>1 - 1.toInt()<!>
|
||||
val i1: Byte = 1 - 1.toInt()
|
||||
val i2: Int = 1 - 1.toInt()
|
||||
val i3: Long = <!INITIALIZER_TYPE_MISMATCH!>1 - 1.toInt()<!>
|
||||
val i4: Short = <!INITIALIZER_TYPE_MISMATCH!>1 - 1.toInt()<!>
|
||||
val i3: Long = 1 - 1.toInt()
|
||||
val i4: Short = 1 - 1.toInt()
|
||||
|
||||
val s1: Byte = <!INITIALIZER_TYPE_MISMATCH!>1 - 1.toShort()<!>
|
||||
val s1: Byte = 1 - 1.toShort()
|
||||
val s2: Int = 1 - 1.toShort()
|
||||
val s3: Long = <!INITIALIZER_TYPE_MISMATCH!>1 - 1.toShort()<!>
|
||||
val s4: Short = <!INITIALIZER_TYPE_MISMATCH!>1 - 1.toShort()<!>
|
||||
val s3: Long = 1 - 1.toShort()
|
||||
val s4: Short = 1 - 1.toShort()
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
val p1: Byte = <!INITIALIZER_TYPE_MISMATCH!>(1 + 2) * 2<!>
|
||||
val p2: Short = <!INITIALIZER_TYPE_MISMATCH!>(1 + 2) * 2<!>
|
||||
val p1: Byte = (1 + 2) * 2
|
||||
val p2: Short = (1 + 2) * 2
|
||||
val p3: Int = (1 + 2) * 2
|
||||
val p4: Long = <!INITIALIZER_TYPE_MISMATCH!>(1 + 2) * 2<!>
|
||||
val p4: Long = (1 + 2) * 2
|
||||
|
||||
val b1: Byte = <!INITIALIZER_TYPE_MISMATCH!>(1.toByte() + 2) * 2<!>
|
||||
val b2: Short = <!INITIALIZER_TYPE_MISMATCH!>(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
|
||||
|
||||
|
||||
+9
-9
@@ -13,17 +13,17 @@ val l2: Byte = <!INITIALIZER_TYPE_MISMATCH!>-1.toLong()<!>
|
||||
val l3: Int = <!INITIALIZER_TYPE_MISMATCH!>-1.toLong()<!>
|
||||
val l4: Short = <!INITIALIZER_TYPE_MISMATCH!>-1.toLong()<!>
|
||||
|
||||
val b1: Byte = <!INITIALIZER_TYPE_MISMATCH!>-1.toByte()<!>
|
||||
val b1: Byte = -1.toByte()
|
||||
val b2: Int = -1.toByte()
|
||||
val b3: Long = <!INITIALIZER_TYPE_MISMATCH!>-1.toByte()<!>
|
||||
val b4: Short = <!INITIALIZER_TYPE_MISMATCH!>-1.toByte()<!>
|
||||
val b3: Long = -1.toByte()
|
||||
val b4: Short = -1.toByte()
|
||||
|
||||
val i1: Byte = <!INITIALIZER_TYPE_MISMATCH!>-1.toInt()<!>
|
||||
val i1: Byte = -1.toInt()
|
||||
val i2: Int = -1.toInt()
|
||||
val i3: Long = <!INITIALIZER_TYPE_MISMATCH!>-1.toInt()<!>
|
||||
val i4: Short = <!INITIALIZER_TYPE_MISMATCH!>-1.toInt()<!>
|
||||
val i3: Long = -1.toInt()
|
||||
val i4: Short = -1.toInt()
|
||||
|
||||
val s1: Byte = <!INITIALIZER_TYPE_MISMATCH!>-1.toShort()<!>
|
||||
val s1: Byte = -1.toShort()
|
||||
val s2: Int = -1.toShort()
|
||||
val s3: Long = <!INITIALIZER_TYPE_MISMATCH!>-1.toShort()<!>
|
||||
val s4: Short = <!INITIALIZER_TYPE_MISMATCH!>-1.toShort()<!>
|
||||
val s3: Long = -1.toShort()
|
||||
val s4: Short = -1.toShort()
|
||||
|
||||
+2
-2
@@ -17,7 +17,7 @@ fun <T> otherGeneric(l: List<T>) {}
|
||||
fun test() {
|
||||
val a: Byte = id(1)
|
||||
|
||||
val b: Byte = <!INITIALIZER_TYPE_MISMATCH!>id(300)<!>
|
||||
val b: Byte = id(300)
|
||||
|
||||
val c: Int = <!INITIALIZER_TYPE_MISMATCH!>id(9223372036854775807)<!>
|
||||
|
||||
@@ -29,7 +29,7 @@ fun test() {
|
||||
|
||||
val f: Byte = either(1, 2)
|
||||
|
||||
val g: Byte = <!INITIALIZER_TYPE_MISMATCH!>either(1, 300)<!>
|
||||
val g: Byte = either(1, 300)
|
||||
|
||||
other(<!ARGUMENT_TYPE_MISMATCH!>11<!>)
|
||||
|
||||
|
||||
@@ -6,13 +6,13 @@ 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!>-bytePos<!> // should not compile, byteNeg should be Int
|
||||
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 = <!INITIALIZER_TYPE_MISMATCH!>-shortPos<!> // should not compile, shortNeg should be Int
|
||||
val shortNeg: Short = -shortPos // should not compile, shortNeg should be Int
|
||||
assertEquals(32768, shortNeg.toInt()) // passes, should not be possible
|
||||
|
||||
(-128).toByte()
|
||||
|
||||
Reference in New Issue
Block a user