[FIR] Implement Int -> Long conversions for literals and operators over them

^KT-38895
^KT-50996 Fixed
^KT-51000 Fixed
^KT-51003 Fixed
^KT-51018 Fixed
This commit is contained in:
Dmitriy Novozhilov
2022-01-25 12:41:04 +03:00
committed by teamcity
parent cc86ca2a0f
commit 52b72a7dac
98 changed files with 1318 additions and 232 deletions
@@ -0,0 +1,65 @@
// SKIP_TXT
// FIR_DUMP
// ISSUE: KT-38895, KT-50996, KT-51000
interface A
interface B
fun takeByte(x: Byte) {}
fun takeInt(x: Int) {}
fun takeNullableInt(x: Int) {}
fun takeLong(x: Long) {}
fun takeNullableLong(x: Long) {}
fun takeOverloaded(x: Int): A = null!! // (1)
fun takeOverloaded(x: Long): B = null!! // (2)
fun takeA(a: A) {}
fun takeB(b: B) {}
fun test_constants() {
takeByte(<!ARGUMENT_TYPE_MISMATCH!>1 + 1<!>) // error
takeInt(1 + 1 + 1) // OK
takeNullableInt(1 + 1 + 1) // OK
takeLong(1 + 1 + 1) // will be OK with implicit widening conversion
takeNullableLong(1 + 1 + 1) // will be OK with implicit widening conversion
val x = takeOverloaded(2147483648 - 1 + 1) // now resolved to (1), will be resolved to (2)
takeA(<!ARGUMENT_TYPE_MISMATCH!>x<!>)
takeB(x)
}
val topLevelIntProperty: Int = 1 + 1 + 1
val topLevelLongProperty: Long = 1 + 1 + 1
val topLevelImplicitIntProperty = 1 + 1 + 1
val topLevelImplicitLongProperty = 3000000000 * 2 + 1
fun testTopLevelProperties() {
// OK
takeInt(topLevelIntProperty)
takeLong(topLevelLongProperty)
takeInt(topLevelImplicitIntProperty)
takeLong(topLevelImplicitLongProperty)
// no conversion for properties
takeLong(<!ARGUMENT_TYPE_MISMATCH!>topLevelIntProperty<!>)
takeLong(<!ARGUMENT_TYPE_MISMATCH!>topLevelImplicitIntProperty<!>)
}
fun testLocalProperties() {
val localIntProperty: Int = 1 + 1
val localLongProperty: Long = 1 + 1
val localImplicitIntProperty = 1 + 1
val localImplicitLongProperty = 3000000000 * 2
// OK
takeInt(localIntProperty)
takeLong(localLongProperty)
takeInt(localImplicitIntProperty)
takeLong(localImplicitLongProperty)
// no conversion for properties
takeLong(<!ARGUMENT_TYPE_MISMATCH!>localIntProperty<!>)
takeLong(<!ARGUMENT_TYPE_MISMATCH!>localImplicitIntProperty<!>)
}
@@ -0,0 +1,63 @@
FILE: intToLongConversion.fir.kt
public abstract interface A : R|kotlin/Any| {
}
public abstract interface B : R|kotlin/Any| {
}
public final fun takeByte(x: R|kotlin/Byte|): R|kotlin/Unit| {
}
public final fun takeInt(x: R|kotlin/Int|): R|kotlin/Unit| {
}
public final fun takeNullableInt(x: R|kotlin/Int|): R|kotlin/Unit| {
}
public final fun takeLong(x: R|kotlin/Long|): R|kotlin/Unit| {
}
public final fun takeNullableLong(x: R|kotlin/Long|): R|kotlin/Unit| {
}
public final fun takeOverloaded(x: R|kotlin/Int|): R|A| {
^takeOverloaded Null(null)!!
}
public final fun takeOverloaded(x: R|kotlin/Long|): R|B| {
^takeOverloaded Null(null)!!
}
public final fun takeA(a: R|A|): R|kotlin/Unit| {
}
public final fun takeB(b: R|B|): R|kotlin/Unit| {
}
public final fun test_constants(): R|kotlin/Unit| {
<Inapplicable(INAPPLICABLE): /takeByte>#(Int(1).R|kotlin/Int.plus|(Int(1)))
R|/takeInt|(Int(1).R|kotlin/Int.plus|(Int(1)).R|kotlin/Int.plus|(Int(1)))
R|/takeNullableInt|(Int(1).R|kotlin/Int.plus|(Int(1)).R|kotlin/Int.plus|(Int(1)))
R|/takeLong|(Int(1).R|kotlin/Int.plus|(Int(1)).R|kotlin/Int.plus|(Int(1)).R|kotlin/Int.toLong|())
R|/takeNullableLong|(Int(1).R|kotlin/Int.plus|(Int(1)).R|kotlin/Int.plus|(Int(1)).R|kotlin/Int.toLong|())
lval x: R|B| = R|/takeOverloaded|(Long(2147483648).R|kotlin/Long.minus|(Int(1)).R|kotlin/Long.plus|(Int(1)))
<Inapplicable(INAPPLICABLE): /takeA>#(R|<local>/x|)
R|/takeB|(R|<local>/x|)
}
public final val topLevelIntProperty: R|kotlin/Int| = Int(1).R|kotlin/Int.plus|(Int(1)).R|kotlin/Int.plus|(Int(1))
public get(): R|kotlin/Int|
public final val topLevelLongProperty: R|kotlin/Long| = Int(1).R|kotlin/Int.plus|(Int(1)).R|kotlin/Int.plus|(Int(1)).R|kotlin/Int.toLong|()
public get(): R|kotlin/Long|
public final val topLevelImplicitIntProperty: R|kotlin/Int| = Int(1).R|kotlin/Int.plus|(Int(1)).R|kotlin/Int.plus|(Int(1))
public get(): R|kotlin/Int|
public final val topLevelImplicitLongProperty: R|kotlin/Long| = Long(3000000000).R|kotlin/Long.times|(Int(2)).R|kotlin/Long.plus|(Int(1))
public get(): R|kotlin/Long|
public final fun testTopLevelProperties(): R|kotlin/Unit| {
R|/takeInt|(R|/topLevelIntProperty|)
R|/takeLong|(R|/topLevelLongProperty|)
R|/takeInt|(R|/topLevelImplicitIntProperty|)
R|/takeLong|(R|/topLevelImplicitLongProperty|)
<Inapplicable(INAPPLICABLE): /takeLong>#(R|/topLevelIntProperty|)
<Inapplicable(INAPPLICABLE): /takeLong>#(R|/topLevelImplicitIntProperty|)
}
public final fun testLocalProperties(): R|kotlin/Unit| {
lval localIntProperty: R|kotlin/Int| = Int(1).R|kotlin/Int.plus|(Int(1))
lval localLongProperty: R|kotlin/Long| = Int(1).R|kotlin/Int.plus|(Int(1)).R|kotlin/Int.toLong|()
lval localImplicitIntProperty: R|kotlin/Int| = Int(1).R|kotlin/Int.plus|(Int(1))
lval localImplicitLongProperty: R|kotlin/Long| = Long(3000000000).R|kotlin/Long.times|(Int(2))
R|/takeInt|(R|<local>/localIntProperty|)
R|/takeLong|(R|<local>/localLongProperty|)
R|/takeInt|(R|<local>/localImplicitIntProperty|)
R|/takeLong|(R|<local>/localImplicitLongProperty|)
<Inapplicable(INAPPLICABLE): /takeLong>#(R|<local>/localIntProperty|)
<Inapplicable(INAPPLICABLE): /takeLong>#(R|<local>/localImplicitIntProperty|)
}
@@ -0,0 +1,65 @@
// SKIP_TXT
// FIR_DUMP
// ISSUE: KT-38895, KT-50996, KT-51000
interface A
interface B
fun takeByte(x: Byte) {}
fun takeInt(x: Int) {}
fun takeNullableInt(x: Int) {}
fun takeLong(x: Long) {}
fun takeNullableLong(x: Long) {}
fun takeOverloaded(x: Int): A = null!! // (1)
fun takeOverloaded(x: Long): B = null!! // (2)
fun takeA(a: A) {}
fun takeB(b: B) {}
fun test_constants() {
takeByte(<!INTEGER_OPERATOR_RESOLVE_WILL_CHANGE!>1 + 1<!>) // error
takeInt(1 + 1 + 1) // OK
takeNullableInt(1 + 1 + 1) // OK
takeLong(1 + 1 + 1) // will be OK with implicit widening conversion
takeNullableLong(1 + 1 + 1) // will be OK with implicit widening conversion
val x = takeOverloaded(<!INTEGER_OVERFLOW!>2147483648 - 1 + 1<!>) // now resolved to (1), will be resolved to (2)
takeA(x)
takeB(<!TYPE_MISMATCH!>x<!>)
}
val topLevelIntProperty: Int = 1 + 1 + 1
val topLevelLongProperty: Long = 1 + 1 + 1
val topLevelImplicitIntProperty = 1 + 1 + 1
val topLevelImplicitLongProperty = 3000000000 * 2 + 1
fun testTopLevelProperties() {
// OK
takeInt(topLevelIntProperty)
takeLong(topLevelLongProperty)
takeInt(topLevelImplicitIntProperty)
takeLong(topLevelImplicitLongProperty)
// no conversion for properties
takeLong(<!TYPE_MISMATCH!>topLevelIntProperty<!>)
takeLong(<!TYPE_MISMATCH!>topLevelImplicitIntProperty<!>)
}
fun testLocalProperties() {
val localIntProperty: Int = 1 + 1
val localLongProperty: Long = 1 + 1
val localImplicitIntProperty = 1 + 1
val localImplicitLongProperty = 3000000000 * 2
// OK
takeInt(localIntProperty)
takeLong(localLongProperty)
takeInt(localImplicitIntProperty)
takeLong(localImplicitLongProperty)
// no conversion for properties
takeLong(<!TYPE_MISMATCH!>localIntProperty<!>)
takeLong(<!TYPE_MISMATCH!>localImplicitIntProperty<!>)
}
@@ -0,0 +1,24 @@
// FIR_IDENTICAL
// ISSUE: KT-51003
interface Assert<T>
fun <T> createAssert(value: T): Assert<T> = null!!
fun <A, B : Comparable<A>> Assert<B>.isGreaterThanOrEqualTo(other: A) {}
fun test_1(long: Long) {
// FE 1.0: OK
// FIR: ARGUMENT_TYPE_MISMATCH
createAssert(long).isGreaterThanOrEqualTo(10 * 10)
}
fun getNullableLong(): Long? = null
fun takeLong(x: Long) {}
fun test_2() {
val x = getNullableLong() ?: 10 * 60
takeLong(x)
// FE 1.0 infers type of `x` to `Long`
// FIR infers it to `Number` as `CST(Long, Int)`
}
@@ -0,0 +1,14 @@
package
public fun </*0*/ T> createAssert(/*0*/ value: T): Assert<T>
public fun getNullableLong(): kotlin.Long?
public fun takeLong(/*0*/ x: kotlin.Long): kotlin.Unit
public fun test_1(/*0*/ long: kotlin.Long): kotlin.Unit
public fun test_2(): kotlin.Unit
public fun </*0*/ A, /*1*/ B : kotlin.Comparable<A>> Assert<B>.isGreaterThanOrEqualTo(/*0*/ other: A): kotlin.Unit
public interface Assert</*0*/ T> {
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
}