tests for type inference
#KT-1800 fixed #KT-1029 fixed #KT-1031 fixed #KT-1558 fixed #KT-1944 fixed #KT-2179 fixed #KT-2294 fixed #KT-2320 fixed #KT-2324 fixed
This commit is contained in:
@@ -0,0 +1,32 @@
|
|||||||
|
//KT-1800 error/NonExistentClass generated on runtime
|
||||||
|
package i
|
||||||
|
|
||||||
|
import java.util.Collection
|
||||||
|
import java.util.ArrayList
|
||||||
|
|
||||||
|
public class User(val firstName: String,
|
||||||
|
val lastName: String,
|
||||||
|
val age: Int) {
|
||||||
|
fun toString() = "$firstName $lastName, age $age"
|
||||||
|
}
|
||||||
|
|
||||||
|
public fun <T: Comparable<T>> Collection<T>.min(): T? {
|
||||||
|
var minValue: T? = null
|
||||||
|
for(value in this) {
|
||||||
|
if (minValue == null || value.compareTo(minValue!!) < 0) {
|
||||||
|
minValue = value
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return minValue
|
||||||
|
}
|
||||||
|
|
||||||
|
fun box() : String {
|
||||||
|
val users = arrayList(
|
||||||
|
User("John", "Doe", 30),
|
||||||
|
User("Jane", "Doe", 27))
|
||||||
|
|
||||||
|
val ages = users.map { it.age }
|
||||||
|
|
||||||
|
val minAge = ages.min()
|
||||||
|
return if (minAge == 27) "OK" else "fail"
|
||||||
|
}
|
||||||
@@ -42,7 +42,7 @@ fun main(args : Array<String>) {
|
|||||||
|
|
||||||
val b = fooT2<Int>()(1)
|
val b = fooT2<Int>()(1)
|
||||||
b : Int
|
b : Int
|
||||||
<!TYPE_INFERENCE_FAILED!>fooT2()<!>(<!ERROR_COMPILE_TIME_VALUE!>1<!>) // : Any?
|
<!TYPE_INFERENCE_FAILED!>fooT2()<!>(1) // : Any?
|
||||||
|
|
||||||
<!CALLEE_NOT_A_FUNCTION!>1<!>()
|
<!CALLEE_NOT_A_FUNCTION!>1<!>()
|
||||||
<!CALLEE_NOT_A_FUNCTION!>1<!>{}
|
<!CALLEE_NOT_A_FUNCTION!>1<!>{}
|
||||||
@@ -79,4 +79,4 @@ fun test() {
|
|||||||
{}<!WRONG_NUMBER_OF_TYPE_ARGUMENTS!><Int><!>()
|
{}<!WRONG_NUMBER_OF_TYPE_ARGUMENTS!><Int><!>()
|
||||||
1<!UNNECESSARY_SAFE_CALL!>?.<!>{Int.() -> 1}()
|
1<!UNNECESSARY_SAFE_CALL!>?.<!>{Int.() -> 1}()
|
||||||
1.<!NO_RECEIVER_ADMITTED!>{}<!>()
|
1.<!NO_RECEIVER_ADMITTED!>{}<!>()
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,12 @@
|
|||||||
|
package b
|
||||||
|
|
||||||
|
fun bar() {
|
||||||
|
val a1 = Array(1, {(i: Int) -> i})
|
||||||
|
val a2 = Array(1, {(i: Int) -> "$i"})
|
||||||
|
val a3 = Array(1, {it})
|
||||||
|
|
||||||
|
a1 : Array<Int>
|
||||||
|
a2 : Array<String>
|
||||||
|
a3 : Array<Int>
|
||||||
|
}
|
||||||
|
|
||||||
@@ -0,0 +1,51 @@
|
|||||||
|
package h
|
||||||
|
//+JDK
|
||||||
|
import java.util.*
|
||||||
|
|
||||||
|
fun <T> id(t: T) : T = t
|
||||||
|
|
||||||
|
fun <T> id1(t: T) = t
|
||||||
|
|
||||||
|
fun <R> elem(t: List<R>): R = t.get(0)
|
||||||
|
|
||||||
|
fun <R> elemAndList(<!UNUSED_PARAMETER!>r<!>: R, t: List<R>): R = t.get(0)
|
||||||
|
|
||||||
|
fun both<T>(t1: T, <!UNUSED_PARAMETER!>t2<!>: T) : T = t1
|
||||||
|
|
||||||
|
fun test1() {
|
||||||
|
val a = elem(list(2))
|
||||||
|
val b = id(elem(list(2)))
|
||||||
|
val c = id(id1(id(id1(list(33)))))
|
||||||
|
a : Int
|
||||||
|
b : Int
|
||||||
|
c : List<Int>
|
||||||
|
|
||||||
|
val d : ArrayList<Int> = newList()
|
||||||
|
val e : ArrayList<Int> = id(newList())
|
||||||
|
val f : ArrayList<Int> = id(id1(id(id1(newList()))))
|
||||||
|
|
||||||
|
d : List<Int>
|
||||||
|
e : List<Int>
|
||||||
|
f : List<Int>
|
||||||
|
|
||||||
|
val g = elemAndList("", newList())
|
||||||
|
val h = elemAndList<Long>(1, newList<Long>())
|
||||||
|
|
||||||
|
g : String
|
||||||
|
h : Long
|
||||||
|
|
||||||
|
val i = both(1, "")
|
||||||
|
val j = both(id(1), id(""))
|
||||||
|
i : Comparable<out Any?>
|
||||||
|
j : Comparable<out Any?>
|
||||||
|
}
|
||||||
|
|
||||||
|
fun list<T>(value: T) : ArrayList<T> {
|
||||||
|
val list = ArrayList<T>()
|
||||||
|
list.add(value)
|
||||||
|
return list
|
||||||
|
}
|
||||||
|
|
||||||
|
fun newList<S>() : ArrayList<S> {
|
||||||
|
return ArrayList<S>()
|
||||||
|
}
|
||||||
@@ -0,0 +1,28 @@
|
|||||||
|
package a
|
||||||
|
//+JDK
|
||||||
|
import java.util.*
|
||||||
|
|
||||||
|
fun <A> cons(<!UNUSED_PARAMETER!>x<!>: A, xs: List<A>): List<A> = xs
|
||||||
|
|
||||||
|
fun <B> nil(): List<B> = arrayList()
|
||||||
|
|
||||||
|
fun test() {
|
||||||
|
val xs = cons(1, nil())
|
||||||
|
val xs1 = cons("", nil())
|
||||||
|
val xs2 = cons(1, nil<Any>())
|
||||||
|
|
||||||
|
xs : List<Int>
|
||||||
|
xs1 : List<String>
|
||||||
|
xs2 : List<Any>
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// ---------------------
|
||||||
|
// copy from kotlin util
|
||||||
|
|
||||||
|
fun arrayList<T>(vararg values: T) : ArrayList<T> = values.toCollection(ArrayList<T>(values.size))
|
||||||
|
|
||||||
|
fun <in T, C: Collection<in T>> Array<T>.toCollection(result: C) : C {
|
||||||
|
for (element in this) result.add(element)
|
||||||
|
return result
|
||||||
|
}
|
||||||
@@ -0,0 +1,28 @@
|
|||||||
|
package a
|
||||||
|
|
||||||
|
//+JDK
|
||||||
|
import java.util.*
|
||||||
|
|
||||||
|
fun foo() {
|
||||||
|
val v = array(1, 2, 3)
|
||||||
|
|
||||||
|
val u = v map { it * 2 }
|
||||||
|
|
||||||
|
u : List<Int>
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// ---------------------
|
||||||
|
// copy from kotlin util
|
||||||
|
|
||||||
|
fun <T> array(vararg t : T) : Array<T> = t
|
||||||
|
|
||||||
|
fun <T, R> Array<T>.map(transform : (T) -> R) : java.util.List<R> {
|
||||||
|
return mapTo(java.util.ArrayList<R>(this.size), transform)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun <T, R, C: Collection<in R>> Array<T>.mapTo(result: C, transform : (T) -> R) : C {
|
||||||
|
for (item in this)
|
||||||
|
result.add(transform(item))
|
||||||
|
return result
|
||||||
|
}
|
||||||
@@ -0,0 +1,15 @@
|
|||||||
|
//KT-1029 Wrong type inference
|
||||||
|
package i
|
||||||
|
|
||||||
|
public fun<T> from(<!UNUSED_PARAMETER!>yielder<!>: ()->Iterable<T>) : Iterable<T> {
|
||||||
|
<!NO_RETURN_IN_FUNCTION_WITH_BLOCK_BODY!>}<!>
|
||||||
|
|
||||||
|
public fun<T> Iterable<T>.where(<!UNUSED_PARAMETER!>predicate<!> : (T)->Boolean) : ()->Iterable<T> {
|
||||||
|
<!NO_RETURN_IN_FUNCTION_WITH_BLOCK_BODY!>}<!>
|
||||||
|
|
||||||
|
fun a() {
|
||||||
|
val x = 0..200
|
||||||
|
val odd = from (x where {it%2==0}) // I believe it should infer here
|
||||||
|
|
||||||
|
odd : Iterable<Int>
|
||||||
|
}
|
||||||
@@ -0,0 +1,19 @@
|
|||||||
|
//KT-1031 Can't infer type of `it` with two lambdas
|
||||||
|
package i
|
||||||
|
|
||||||
|
import java.util.ArrayList
|
||||||
|
|
||||||
|
public fun<TItem> Iterable<TItem>.where(<!UNUSED_PARAMETER!>predicate<!> : (TItem)->Boolean) : ()->Iterable<TItem> {
|
||||||
|
<!NO_RETURN_IN_FUNCTION_WITH_BLOCK_BODY!>}<!>
|
||||||
|
|
||||||
|
public fun<TItem, TResult> select(<!UNUSED_PARAMETER!>yielder<!>: ()->Iterable<TItem>, <!UNUSED_PARAMETER!>selector<!> : (TItem)->TResult) : ()->Iterable<TResult> {
|
||||||
|
<!NO_RETURN_IN_FUNCTION_WITH_BLOCK_BODY!>}<!>
|
||||||
|
|
||||||
|
fun a() {
|
||||||
|
val x = 0..200
|
||||||
|
val z = x where { (i: Int) -> i % 2 == 0 }
|
||||||
|
val yielder = select(x where { it%2==0 }, { it.toString() })
|
||||||
|
|
||||||
|
z : () -> Iterable<Int>
|
||||||
|
yielder : () -> Iterable<String>
|
||||||
|
}
|
||||||
@@ -0,0 +1,24 @@
|
|||||||
|
//KT-1558 Exception while analyzing
|
||||||
|
package j
|
||||||
|
|
||||||
|
//+JDK
|
||||||
|
import java.util.List
|
||||||
|
|
||||||
|
|
||||||
|
fun testArrays(val ci: List<Int?>, val cii: List<Int?>) {
|
||||||
|
val c1: Array<Int?> = cii.sure().toArray(<!FUNCTION_CALL_EXPECTED!><!NO_VALUE_FOR_PARAMETER, NO_VALUE_FOR_PARAMETER!>Array<!><Int?><!>)
|
||||||
|
|
||||||
|
val c2: Array<Int?> = ci.toArray(Array<Int?><!NO_VALUE_FOR_PARAMETER, NO_VALUE_FOR_PARAMETER!>()<!>)
|
||||||
|
|
||||||
|
val c3 = Array<Int?><!NO_VALUE_FOR_PARAMETER, NO_VALUE_FOR_PARAMETER!>()<!>
|
||||||
|
|
||||||
|
val c4 = ci.toArray<Int?>(Array<Int?><!NO_VALUE_FOR_PARAMETER, NO_VALUE_FOR_PARAMETER!>()<!>)
|
||||||
|
|
||||||
|
val c5 = ci.toArray(Array<Int?><!NO_VALUE_FOR_PARAMETER, NO_VALUE_FOR_PARAMETER!>()<!>)
|
||||||
|
|
||||||
|
c1 : Array<Int?>
|
||||||
|
c2 : Array<Int?>
|
||||||
|
c3 : Array<Int?>
|
||||||
|
c4 : Array<Int?>
|
||||||
|
c5 : Array<Int?>
|
||||||
|
}
|
||||||
@@ -0,0 +1,14 @@
|
|||||||
|
//KT-1944 Inference fails on run()
|
||||||
|
package j
|
||||||
|
|
||||||
|
class P {
|
||||||
|
var x : Int = 0
|
||||||
|
private set
|
||||||
|
|
||||||
|
fun foo() {
|
||||||
|
val r = run {x = 5} // ERROR
|
||||||
|
r : Unit
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun <T> run(f: () -> T) : T = f()
|
||||||
@@ -0,0 +1,44 @@
|
|||||||
|
//KT-2179 Nested function literal breaks compiler
|
||||||
|
package i
|
||||||
|
|
||||||
|
//+JDK
|
||||||
|
import java.util.*
|
||||||
|
|
||||||
|
fun test() {
|
||||||
|
val sample1: List<List<Int?>> = arrayList(arrayList<Int?>(1, 7, null, 8))
|
||||||
|
|
||||||
|
//breaks compiler
|
||||||
|
val sample2 = sample1.map({it.map({it})})
|
||||||
|
sample2 : List<List<Int?>>
|
||||||
|
|
||||||
|
//breaks compiler
|
||||||
|
val sample3 = sample1.map({row -> row.map({column -> column})})
|
||||||
|
sample3 : List<List<Int?>>
|
||||||
|
|
||||||
|
//doesn't break compiler
|
||||||
|
val identity: (Int?) -> Int? = {column -> column}
|
||||||
|
val sample4 = sample1.map({row -> row.map(identity)})
|
||||||
|
sample4 : List<List<Int?>>
|
||||||
|
}
|
||||||
|
|
||||||
|
//------------
|
||||||
|
|
||||||
|
fun arrayList<T>(vararg values: T) : ArrayList<T> = values.toCollection(ArrayList<T>(values.size))
|
||||||
|
|
||||||
|
fun <T, R> java.util.Collection<T>.map(transform : (T) -> R) : java.util.List<R> {
|
||||||
|
return mapTo(java.util.ArrayList<R>(this.size), transform)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun <T, R, C: Collection<in R>> java.util.Collection<T>.mapTo(result: C, transform : (T) -> R) : C {
|
||||||
|
for (item in this)
|
||||||
|
result.add(transform(item))
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
|
||||||
|
fun <in T, C: Collection<in T>> Array<T>.toCollection(result: C) : C {
|
||||||
|
for (element in this) result.add(element)
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
|
||||||
|
val Collection<*>.size : Int
|
||||||
|
get() = size()
|
||||||
@@ -0,0 +1,16 @@
|
|||||||
|
//KT-2294 Type inference infers DONT_CARE instead of correct type
|
||||||
|
package a
|
||||||
|
|
||||||
|
public fun foo<E>(array: Array<E>): Array<E> = array
|
||||||
|
|
||||||
|
public fun test()
|
||||||
|
{
|
||||||
|
val x = foo(array(1, 2, 3, 4, 5)) // Should infer type 'Int'
|
||||||
|
// ^--- public final fun <T : jet.Any? > array(vararg t : DONT_CARE) : jet.Array<DONT_CARE> defined in Kotlin
|
||||||
|
// ^--- public final fun <E : jet.Any? > foo(items t : jet.Array<DONT_CARE>) : jet.Array<DONT_CARE> defined in root package
|
||||||
|
x : Array<Int>
|
||||||
|
}
|
||||||
|
|
||||||
|
//--------------------
|
||||||
|
|
||||||
|
fun <T> array(vararg t : T) : Array<T> = t
|
||||||
@@ -0,0 +1,13 @@
|
|||||||
|
//KT-2320 failure of complex case of type inference
|
||||||
|
package i
|
||||||
|
|
||||||
|
trait NotMap<B>
|
||||||
|
|
||||||
|
trait Entry<B> {
|
||||||
|
fun getValue(): B
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
fun <V, R> NotMap<V>.mapValuesOriginal(<!UNUSED_PARAMETER!>ff<!>: (Entry<V>) -> R): NotMap<R> = throw Exception()
|
||||||
|
|
||||||
|
fun <B, C> NotMap<B>.mapValuesOnly(f: (B) -> C) = mapValuesOriginal { e -> f(e.getValue()) }
|
||||||
@@ -0,0 +1,33 @@
|
|||||||
|
//KT-2324 Can't resolve generic by type of function result
|
||||||
|
package i
|
||||||
|
|
||||||
|
//+JDK
|
||||||
|
import java.util.*
|
||||||
|
|
||||||
|
fun <T, K> someFunction(list: List<T>, transform: (T) -> K): List<K> {
|
||||||
|
val result = arrayList<K>()
|
||||||
|
for (i in list) {
|
||||||
|
result.add(transform(i))
|
||||||
|
}
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
|
||||||
|
fun testSomeFunction() {
|
||||||
|
val result1 = someFunction(arrayList<Int>(1, 2), {it : Int}) //type of result1 is List<Int>
|
||||||
|
assertEquals(1, result1.get(0)); //OK
|
||||||
|
|
||||||
|
val result2 = someFunction(arrayList<Int>(1, 2), {it}) // type of result2 is List<DONT_CARE>
|
||||||
|
result2 : List<Int>
|
||||||
|
assertEquals(1, result2.get(0)); //resolved to error element
|
||||||
|
}
|
||||||
|
|
||||||
|
//---------------------------------
|
||||||
|
fun assertEquals(<!UNUSED_PARAMETER!>expected<!>: Any?, <!UNUSED_PARAMETER!>actual<!>: Any?, <!UNUSED_PARAMETER!>message<!>: String = "") {
|
||||||
|
}
|
||||||
|
|
||||||
|
fun arrayList<T>(vararg values: T) : ArrayList<T> = values.toCollection(ArrayList<T>(values.size))
|
||||||
|
|
||||||
|
fun <in T, C: Collection<in T>> Array<T>.toCollection(result: C) : C {
|
||||||
|
for (element in this) result.add(element)
|
||||||
|
return result
|
||||||
|
}
|
||||||
@@ -18,7 +18,7 @@ class C {
|
|||||||
fun p() : Resource? = null
|
fun p() : Resource? = null
|
||||||
|
|
||||||
fun bar() {
|
fun bar() {
|
||||||
<!TYPE_INFERENCE_FAILED!>foo(<!TYPE_MISMATCH!>p()<!>) {
|
<!TYPE_INFERENCE_UPPER_BOUND_VIOLATED!>foo(p()) {
|
||||||
|
|
||||||
}<!>
|
}<!>
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user