[NI] Consider intersection type with number type as Nothing

Currently, only for "in": In<in Int & A> == In<in Nothing> == In<*>

 #KT-37302 Fixed
This commit is contained in:
Mikhail Zarechenskiy
2020-03-22 23:25:12 +03:00
parent b23aff4d0d
commit 191fb02bf6
26 changed files with 242 additions and 92 deletions
@@ -0,0 +1,81 @@
// IGNORE_BACKEND: JS, JS_IR
// IGNORE_BACKEND_FIR: JVM_IR
// WITH_RUNTIME
// FILE: J.java
public class J {
public static long platformLong() {
return 42;
}
public static Comparable<Long> platformCLong() {
return new Long(42);
}
}
// FILE: test.kt
inline fun <reified T> check(value: Any?) {
if (value !is T) throw Exception("value: $value should have type ${T::class.simpleName}")
}
fun <K> selectFirst(vararg xs: K): K = xs[0]
fun takeNLong(nL: Long?) {}
fun <T> checkArray(array: T, copy: T.() -> T, toList: T.() -> List<*>, check: (T, T) -> Boolean, modify: T.() -> Unit) {}
fun testFromStdlib() {
checkArray(arrayOf("a", 1, null), { copyOf() }, { toList() }, { a1, a2 -> a1 contentEquals a2 }, { reverse() })
}
fun box(): String {
check<Long>(selectFirst(0, 0L))
check<Byte>(selectFirst(0, 0.toByte()))
check<Short>(selectFirst(0, 0.toShort()))
takeNLong(0)
val cLong: Comparable<Long> = 0L
check<Long>(selectFirst(0, cLong))
val cByte: Comparable<Byte> = 0.toByte()
check<Byte>(selectFirst(0, cByte))
val cShort: Comparable<Short> = 0.toShort()
check<Short>(selectFirst(0, cShort))
val cStar: Comparable<*> = 0L
check<Int>(selectFirst(0, cStar))
check<Long>(selectFirst(0, J.platformLong()))
check<Long>(selectFirst(0, J.platformCLong()))
check<Int>(selectFirst(0, 0L, "string"))
check<Int>(selectFirst(0, 0L, true))
check<Int>(selectFirst(0, 0L, 0.toByte()))
check<Int>(selectFirst(0, 0L, 0f))
check<Int>(selectFirst(0, 0L, 0f, 0.0))
val r = 0
check<Int>(
when (r) {
0 -> 0
1 -> 0L
2 -> "string"
else -> TODO()
}
)
check<Int>(selectFirst(0, 0L, 0.0, null))
check<ULong>(selectFirst(0u, 0uL))
check<UByte>(selectFirst(0u, 0.toUByte()))
check<UShort>(selectFirst(0u, 0.toUShort()))
check<UInt>(selectFirst(0u, 0uL, "foo"))
check<UInt>(selectFirst(0u, 0uL, "foo", null))
return "OK"
}
@@ -18,7 +18,7 @@ fun test() {
// ISSUE: KT-27999
// ISSUE: KT-30244
fun test_1() {
<!DEBUG_INFO_EXPRESSION_TYPE("() -> {Comparable<{Int & String}> & java.io.Serializable}")!>select(
<!DEBUG_INFO_EXPRESSION_TYPE("() -> {Comparable<*> & java.io.Serializable}")!>select(
{ 1 },
{ "" }
)<!>
@@ -107,7 +107,7 @@ fun case_8() {
val x3 = Test.id(A(null))
val result_1 = select(x1, x2, x3)
<!DEBUG_INFO_EXPRESSION_TYPE("A<out {Comparable<{Int & String}> & java.io.Serializable}?>?")!>result_1<!>
<!DEBUG_INFO_EXPRESSION_TYPE("A<out {Comparable<*>? & java.io.Serializable?}>?")!>result_1<!>
}
fun case_9() {
@@ -116,7 +116,7 @@ fun case_9() {
val x3 = A(Test.id(A('s')))
val result_1 = select(x1, x2, x3)
<!DEBUG_INFO_EXPRESSION_TYPE("A<out A<out {Comparable<{Char & Int & String}> & java.io.Serializable}>?>")!>result_1<!>
<!DEBUG_INFO_EXPRESSION_TYPE("A<out A<out {Comparable<*> & java.io.Serializable}>?>")!>result_1<!>
}
fun case_10() {
@@ -1,7 +1,7 @@
package
public val test1: C<kotlin.Int> /* = Cons<kotlin.Int> */
public val test2: C<kotlin.Number> /* = Cons<kotlin.Number> */
public val test2: Cons<out kotlin.Any?>
public final class Cons</*0*/ T : kotlin.Number> {
public constructor Cons</*0*/ T : kotlin.Number>(/*0*/ head: T, /*1*/ tail: Cons<T>?)
@@ -2,7 +2,7 @@ package
public val test0: P<kotlin.Int, kotlin.Int> /* = Pair<kotlin.Int, kotlin.Int> */
public val test0p2: P2<kotlin.Int> /* = Pair<kotlin.Int, kotlin.Int> */
public val test0p2a: Pair<out kotlin.Any, out kotlin.Any>
public val test0p2a: Pair<out kotlin.Any?, out kotlin.Any?>
public val test0pr: PR<kotlin.String, kotlin.Int> /* = Pair<kotlin.Int, kotlin.String> */
public val test1: P<kotlin.Int, kotlin.Int> /* = Pair<kotlin.Int, kotlin.Int> */
public val test1p2: P2<kotlin.Int> /* = Pair<kotlin.Int, kotlin.Int> */
@@ -13,7 +13,7 @@ public val test2pr: PR<kotlin.Int, kotlin.String> /* = Pair<kotlin.String, kotli
public val test2pra: PR<kotlin.String, kotlin.Int> /* = Pair<kotlin.Int, kotlin.String> */
public val test3: P<kotlin.Int, kotlin.Int> /* = Pair<kotlin.Int, kotlin.Int> */
public val test3p2: P2<kotlin.Int> /* = Pair<kotlin.Int, kotlin.Int> */
public val test3pr: Pair<out kotlin.Any, out kotlin.Any>
public val test3pr: Pair<out kotlin.Any?, out kotlin.Any?>
public val testMP0: MP<kotlin.Int> /* = MyPair<kotlin.String, kotlin.Int> */
public val testMP1: MP<kotlin.String> /* = MyPair<kotlin.String, kotlin.String> */
public val testMP2: MP<kotlin.String> /* = MyPair<kotlin.String, kotlin.String> */
@@ -0,0 +1,12 @@
// !LANGUAGE: +NewInference
import kotlin.test.assertEquals
fun test() {
val u = when (true) {
true -> 42
else -> 1.0
}
assertEquals(42, u)
}
@@ -1,4 +1,3 @@
// FIR_IDENTICAL
// !LANGUAGE: +NewInference
import kotlin.test.assertEquals
@@ -9,5 +8,5 @@ fun test() {
else -> 1.0
}
assertEquals(42, u)
<!TYPE_INFERENCE_ONLY_INPUT_TYPES_WARNING!>assertEquals<!>(42, u)
}
@@ -10,7 +10,7 @@ fun test(a: Any, ls: List<String>) {
Resolved call:
Candidate descriptor: fun <T> foo(t: T, l: List<T>): Unit defined in root package
Resulting descriptor: fun <T> foo(t: {Comparable<{Int & String}> & java.io.Serializable}, l: List<{Comparable<{Int & String}> & java.io.Serializable}>): Unit defined in root package
Resulting descriptor: fun <T> foo(t: {Comparable<*> & java.io.Serializable}, l: List<{Comparable<*> & java.io.Serializable}>): Unit defined in root package
Explicit receiver kind = NO_EXPLICIT_RECEIVER
Dispatch receiver = NO_RECEIVER
@@ -18,5 +18,5 @@ Extension receiver = NO_RECEIVER
Value arguments mapping:
SUCCESS t : {Comparable<{Int & String}> & java.io.Serializable} = 11
SUCCESS l : List<{Comparable<{Int & String}> & java.io.Serializable}> = ls
SUCCESS t : {Comparable<*> & java.io.Serializable} = 11
SUCCESS l : List<{Comparable<*> & java.io.Serializable}> = ls