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)
|
||||
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<!>{}
|
||||
@@ -79,4 +79,4 @@ fun test() {
|
||||
{}<!WRONG_NUMBER_OF_TYPE_ARGUMENTS!><Int><!>()
|
||||
1<!UNNECESSARY_SAFE_CALL!>?.<!>{Int.() -> 1}()
|
||||
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 bar() {
|
||||
<!TYPE_INFERENCE_FAILED!>foo(<!TYPE_MISMATCH!>p()<!>) {
|
||||
<!TYPE_INFERENCE_UPPER_BOUND_VIOLATED!>foo(p()) {
|
||||
|
||||
}<!>
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user