NI: Improve postponed arguments analysis

Introduce seven stages:
1) Analyze postponed arguments with fixed parameter types
2) Collect parameter types from constraints and lambda parameters' declaration
3) Fix not postponed variables for parameter types of all postponed arguments
4) Create atoms with revised expected types if needed
5) Analyze the first ready postponed argument and rerun stages if it has been analyzed
6) Force fixation remaining type variables: fix if possible or report not enough information
7) Force analysis remaining not analyzed postponed arguments and rerun stages if there are

^KT-37952 Fixed
^KT-32156 Fixed
^KT-37249 Fixed
^KT-37341 Fixed
This commit is contained in:
Victor Petukhov
2020-03-28 20:40:29 +03:00
parent 50151e0e01
commit 260683c20e
70 changed files with 2619 additions and 352 deletions
@@ -0,0 +1,8 @@
Failures detected in FirBodyResolveTransformerAdapter, file: /callableReferences.fir.kt
Cause: java.lang.RuntimeException: While resolving call R?C|/selectNumber|(R?C|/id|(::R?C|/foo6|), R?C|/id|(<L> = id@fun <implicit>.<anonymous>(x: <implicit>): <implicit> {
x#
}
), R?C|/id|(<L> = id@fun <implicit>.<anonymous>(): <implicit> {
it#
}
))
@@ -0,0 +1,57 @@
// !DIAGNOSTICS: -UNUSED_VARIABLE -UNUSED_EXPRESSION -UNUSED_PARAMETER -UNUSED_ANONYMOUS_PARAMETER
import kotlin.reflect.*
fun <T>id(x: T) = x
fun <T> select(vararg x: T) = x[0]
fun foo(x: Int) {}
fun foo2(x: Number) {}
fun foo3(x: Int) {}
fun foo3(x: Number) {}
interface A
interface B
fun foo4(x: A) {}
fun foo4(x: B) {}
interface C: A, B
fun foo5(x: A) {}
fun foo5(x: B) {}
fun foo5(x: C) {}
fun <T: (Float) -> Unit> selectNumber(vararg x: T) = x[0]
fun foo6(x: Int) {}
fun foo6(x: Float) {}
fun foo6(x: Number) {}
fun main() {
select(::foo, { <!DEBUG_INFO_EXPRESSION_TYPE("kotlin.Int")!>it<!> })
select(id(::foo), { x: Number -> }, { <!DEBUG_INFO_EXPRESSION_TYPE("kotlin.Int")!>it<!> })
val x1 = select(<!DEBUG_INFO_EXPRESSION_TYPE("kotlin.reflect.KFunction1<kotlin.Int, kotlin.Unit>")!>id(::foo)<!>, <!DEBUG_INFO_EXPRESSION_TYPE("(kotlin.Number) -> kotlin.Number")!>id { x: Number -> <!DEBUG_INFO_EXPRESSION_TYPE("kotlin.Number")!>x<!> }<!>)
<!DEBUG_INFO_EXPRESSION_TYPE("(kotlin.Int) -> kotlin.Any")!>x1<!>
val x11 = select(id(::foo), id { x: Number -> }, id { <!DEBUG_INFO_EXPRESSION_TYPE("kotlin.Int")!>it<!> })
<!DEBUG_INFO_EXPRESSION_TYPE("(kotlin.Int) -> kotlin.Any")!>x11<!>
select(id(::foo2), id { x: Int -> }, id { <!DEBUG_INFO_EXPRESSION_TYPE("kotlin.Int")!>it<!> })
select(id(<!DEBUG_INFO_EXPRESSION_TYPE("kotlin.reflect.KFunction1<kotlin.Int, kotlin.Unit>")!>::foo3<!>), id { x: Int -> }, id { <!DEBUG_INFO_EXPRESSION_TYPE("kotlin.Int")!>it<!> })
select(id(<!DEBUG_INFO_EXPRESSION_TYPE("kotlin.reflect.KFunction1<kotlin.Int, kotlin.Unit>")!>::foo3<!>), id { x: Number -> }, id { <!DEBUG_INFO_EXPRESSION_TYPE("kotlin.Int")!>it<!> })
select(id(<!DEBUG_INFO_EXPRESSION_TYPE("kotlin.reflect.KFunction1<kotlin.Int, kotlin.Unit>")!>::foo3<!>), id { x: Number -> }, id { x: Int -> }, id { <!DEBUG_INFO_EXPRESSION_TYPE("kotlin.Int")!>it<!> })
select(id(<!DEBUG_INFO_EXPRESSION_TYPE("kotlin.reflect.KFunction1<A, kotlin.Unit>")!>::foo4<!>), id { x: A -> }, id { <!DEBUG_INFO_EXPRESSION_TYPE("A")!>it<!> })
select(id(<!DEBUG_INFO_EXPRESSION_TYPE("kotlin.reflect.KFunction1<B, kotlin.Unit>")!>::foo4<!>), id { x: B -> }, id { <!DEBUG_INFO_EXPRESSION_TYPE("B")!>it<!> })
// Expected ambiguity
select(id(::<!CALLABLE_REFERENCE_RESOLUTION_AMBIGUITY!>foo4<!>), id { x: A -> }, id { x: B -> }, id { <!DEBUG_INFO_EXPRESSION_TYPE("{A & B}")!>it<!> })
select(id(::foo5), id { x: A -> }, id { x: B -> }, id { <!DEBUG_INFO_EXPRESSION_TYPE("C")!>it<!> })
val x2: (Int) -> Unit = selectNumber(id(<!DEBUG_INFO_EXPRESSION_TYPE("kotlin.reflect.KFunction1<kotlin.Number, kotlin.Unit>")!>::foo6<!>), id { x -> <!DEBUG_INFO_EXPRESSION_TYPE("{Comparable<*> & Number}")!>x<!> }, id { <!DEBUG_INFO_EXPRESSION_TYPE("{Comparable<*> & Number}")!>it<!> })
}
@@ -0,0 +1,57 @@
// !DIAGNOSTICS: -UNUSED_VARIABLE -UNUSED_EXPRESSION -UNUSED_PARAMETER -UNUSED_ANONYMOUS_PARAMETER
import kotlin.reflect.*
fun <T>id(x: T) = x
fun <T> select(vararg x: T) = x[0]
fun foo(x: Int) {}
fun foo2(x: Number) {}
fun foo3(x: Int) {}
fun foo3(x: Number) {}
interface A
interface B
fun foo4(x: A) {}
fun foo4(x: B) {}
interface C: A, B
fun foo5(x: A) {}
fun foo5(x: B) {}
fun foo5(x: C) {}
fun <T: (Float) -> Unit> selectNumber(vararg x: T) = x[0]
fun foo6(x: Int) {}
fun foo6(x: Float) {}
fun foo6(x: Number) {}
fun main() {
select(::foo, { <!DEBUG_INFO_EXPRESSION_TYPE("kotlin.Int")!>it<!> })
select(id(::foo), { x: Number -> }, { <!DEBUG_INFO_EXPRESSION_TYPE("kotlin.Int")!>it<!> })
val x1 = select(<!DEBUG_INFO_EXPRESSION_TYPE("kotlin.reflect.KFunction1<kotlin.Int, kotlin.Unit>")!>id(::foo)<!>, <!DEBUG_INFO_EXPRESSION_TYPE("(kotlin.Number) -> kotlin.Number")!>id { x: Number -> <!DEBUG_INFO_EXPRESSION_TYPE("kotlin.Number")!>x<!> }<!>)
<!DEBUG_INFO_EXPRESSION_TYPE("(kotlin.Int) -> kotlin.Any")!>x1<!>
val x11 = select(id(::foo), id { x: Number -> }, id { <!DEBUG_INFO_EXPRESSION_TYPE("kotlin.Int")!>it<!> })
<!DEBUG_INFO_EXPRESSION_TYPE("(kotlin.Int) -> kotlin.Any")!>x11<!>
select(id(::foo2), id { x: Int -> }, id { <!DEBUG_INFO_EXPRESSION_TYPE("kotlin.Int")!>it<!> })
select(id(<!DEBUG_INFO_EXPRESSION_TYPE("kotlin.reflect.KFunction1<kotlin.Int, kotlin.Unit>")!>::foo3<!>), id { x: Int -> }, id { <!DEBUG_INFO_EXPRESSION_TYPE("kotlin.Int")!>it<!> })
select(id(<!DEBUG_INFO_EXPRESSION_TYPE("kotlin.reflect.KFunction1<kotlin.Int, kotlin.Unit>")!>::foo3<!>), id { x: Number -> }, id { <!DEBUG_INFO_EXPRESSION_TYPE("kotlin.Int")!>it<!> })
select(id(<!DEBUG_INFO_EXPRESSION_TYPE("kotlin.reflect.KFunction1<kotlin.Int, kotlin.Unit>")!>::foo3<!>), id { x: Number -> }, id { x: Int -> }, id { <!DEBUG_INFO_EXPRESSION_TYPE("kotlin.Int")!>it<!> })
select(id(<!DEBUG_INFO_EXPRESSION_TYPE("kotlin.reflect.KFunction1<A, kotlin.Unit>")!>::foo4<!>), id { x: A -> }, id { <!DEBUG_INFO_EXPRESSION_TYPE("A")!>it<!> })
select(id(<!DEBUG_INFO_EXPRESSION_TYPE("kotlin.reflect.KFunction1<B, kotlin.Unit>")!>::foo4<!>), id { x: B -> }, id { <!DEBUG_INFO_EXPRESSION_TYPE("B")!>it<!> })
// Expected ambiguity
select(id(::<!CALLABLE_REFERENCE_RESOLUTION_AMBIGUITY!>foo4<!>), id { x: A -> }, id { x: B -> }, id { <!DEBUG_INFO_EXPRESSION_TYPE("{A & B}")!>it<!> })
select(id(::foo5), id { x: A -> }, id { x: B -> }, id { <!DEBUG_INFO_EXPRESSION_TYPE("C")!>it<!> })
val x2: (Int) -> Unit = selectNumber(id(<!DEBUG_INFO_EXPRESSION_TYPE("kotlin.reflect.KFunction1<kotlin.Number, kotlin.Unit>")!>::foo6<!>), id { x -> <!DEBUG_INFO_EXPRESSION_TYPE("{Comparable<*> & Number}")!>x<!> }, id { <!DEBUG_INFO_EXPRESSION_TYPE("{Comparable<*> & Number}")!>it<!> })
}
@@ -0,0 +1,36 @@
package
public fun foo(/*0*/ x: kotlin.Int): kotlin.Unit
public fun foo2(/*0*/ x: kotlin.Number): kotlin.Unit
public fun foo3(/*0*/ x: kotlin.Int): kotlin.Unit
public fun foo3(/*0*/ x: kotlin.Number): kotlin.Unit
public fun foo4(/*0*/ x: A): kotlin.Unit
public fun foo4(/*0*/ x: B): kotlin.Unit
public fun foo5(/*0*/ x: A): kotlin.Unit
public fun foo5(/*0*/ x: B): kotlin.Unit
public fun foo5(/*0*/ x: C): kotlin.Unit
public fun foo6(/*0*/ x: kotlin.Float): kotlin.Unit
public fun foo6(/*0*/ x: kotlin.Int): kotlin.Unit
public fun foo6(/*0*/ x: kotlin.Number): kotlin.Unit
public fun </*0*/ T> id(/*0*/ x: T): T
public fun main(): kotlin.Unit
public fun </*0*/ T> select(/*0*/ vararg x: T /*kotlin.Array<out T>*/): T
public fun </*0*/ T : (kotlin.Float) -> kotlin.Unit> selectNumber(/*0*/ vararg x: T /*kotlin.Array<out T>*/): T
public interface A {
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
}
public interface B {
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
}
public interface C : A, B {
public open override /*2*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public open override /*2*/ /*fake_override*/ fun hashCode(): kotlin.Int
public open override /*2*/ /*fake_override*/ fun toString(): kotlin.String
}
@@ -0,0 +1,41 @@
// !DIAGNOSTICS: -CAST_NEVER_SUCCEEDS -UNUSED_PARAMETER
interface AssertionPlant<out T : Any>
interface AssertionPlantNullable<out T : Any?>: BaseAssertionPlant<T, AssertionPlantNullable<T>>
interface BaseAssertionPlant<out T : Any?, out A : BaseAssertionPlant<T, A>>
interface BaseCollectingAssertionPlant<out T, out A : BaseAssertionPlant<T, A>, out C : BaseCollectingAssertionPlant<T, A, C>> : BaseAssertionPlant<T, A>
interface CreatorLike<TSubject, T, A : BaseAssertionPlant<T, A>, C : BaseCollectingAssertionPlant<T, A, C>>
interface ParameterObjectOption {
fun <TSubject : Any, T : Any?> withParameterObjectNullable(
parameterObject: ParameterObject<TSubject, T>
) = null as CreatorNullable<TSubject, T>
}
class ParameterObject<TSubject, T>
interface CollectingAssertionPlantNullable<out T> : AssertionPlantNullable<T>,
BaseCollectingAssertionPlant<T, AssertionPlantNullable<T>, CollectingAssertionPlantNullable<T>>
interface CreatorNullable<TSubject, T>: CreatorLike<TSubject, T, AssertionPlantNullable<T>, CollectingAssertionPlantNullable<T>>
fun <K, V, M, A : BaseAssertionPlant<V, A>, C : BaseCollectingAssertionPlant<V, A, C>> contains(
pairs: List<Pair<K, M>>,
parameterObjectOption: (ParameterObjectOption, K) -> CreatorLike<Map<out K, V>, V, A, C>,
assertionCreator: C.(M) -> Unit
) {}
private fun <K, V> createGetParameterObject(
plant: AssertionPlant<Map<out K, V>>,
key: K
) = null as ParameterObject<Map<out K, V>, V>
private fun <K, V : Any, M> containsNullable(
plant: AssertionPlant<Map<out K, V?>>,
pairs: List<Pair<K, M>>,
assertionCreator: AssertionPlantNullable<V?>.(M) -> Unit
) = contains(
pairs,
{ option, key -> option.withParameterObjectNullable(createGetParameterObject(plant, key)) },
assertionCreator
)
@@ -0,0 +1,41 @@
// !DIAGNOSTICS: -CAST_NEVER_SUCCEEDS -UNUSED_PARAMETER
interface AssertionPlant<out T : Any>
interface AssertionPlantNullable<out T : Any?>: BaseAssertionPlant<T, AssertionPlantNullable<T>>
interface BaseAssertionPlant<out T : Any?, out A : BaseAssertionPlant<T, A>>
interface BaseCollectingAssertionPlant<out T, out A : BaseAssertionPlant<T, A>, out C : BaseCollectingAssertionPlant<T, A, C>> : BaseAssertionPlant<T, A>
interface CreatorLike<TSubject, T, A : BaseAssertionPlant<T, A>, C : BaseCollectingAssertionPlant<T, A, C>>
interface ParameterObjectOption {
fun <TSubject : Any, T : Any?> withParameterObjectNullable(
parameterObject: ParameterObject<TSubject, T>
) = null as CreatorNullable<TSubject, T>
}
class ParameterObject<TSubject, T>
interface CollectingAssertionPlantNullable<out T> : AssertionPlantNullable<T>,
BaseCollectingAssertionPlant<T, AssertionPlantNullable<T>, CollectingAssertionPlantNullable<T>>
interface CreatorNullable<TSubject, T>: CreatorLike<TSubject, T, AssertionPlantNullable<T>, CollectingAssertionPlantNullable<T>>
fun <K, V, M, A : BaseAssertionPlant<V, A>, C : BaseCollectingAssertionPlant<V, A, C>> contains(
pairs: List<Pair<K, M>>,
parameterObjectOption: (ParameterObjectOption, K) -> CreatorLike<Map<out K, V>, V, A, C>,
assertionCreator: C.(M) -> Unit
) {}
private fun <K, V> createGetParameterObject(
plant: AssertionPlant<Map<out K, V>>,
key: K
) = null as ParameterObject<Map<out K, V>, V>
private fun <K, V : Any, M> containsNullable(
plant: AssertionPlant<Map<out K, V?>>,
pairs: List<Pair<K, M>>,
assertionCreator: AssertionPlantNullable<V?>.(M) -> Unit
) = contains(
pairs,
{ option, key -> <!DEBUG_INFO_EXPRESSION_TYPE("CreatorNullable<kotlin.collections.Map<out K, V?>, V?>")!>option.withParameterObjectNullable(createGetParameterObject(plant, key))<!> },
assertionCreator
)
@@ -0,0 +1,61 @@
package
public fun </*0*/ K, /*1*/ V, /*2*/ M, /*3*/ A : BaseAssertionPlant<V, A>, /*4*/ C : BaseCollectingAssertionPlant<V, A, C>> contains(/*0*/ pairs: kotlin.collections.List<kotlin.Pair<K, M>>, /*1*/ parameterObjectOption: (ParameterObjectOption, K) -> CreatorLike<kotlin.collections.Map<out K, V>, V, A, C>, /*2*/ assertionCreator: C.(M) -> kotlin.Unit): kotlin.Unit
private fun </*0*/ K, /*1*/ V : kotlin.Any, /*2*/ M> containsNullable(/*0*/ plant: AssertionPlant<kotlin.collections.Map<out K, V?>>, /*1*/ pairs: kotlin.collections.List<kotlin.Pair<K, M>>, /*2*/ assertionCreator: AssertionPlantNullable<V?>.(M) -> kotlin.Unit): kotlin.Unit
private fun </*0*/ K, /*1*/ V> createGetParameterObject(/*0*/ plant: AssertionPlant<kotlin.collections.Map<out K, V>>, /*1*/ key: K): ParameterObject<kotlin.collections.Map<out K, V>, V>
public interface AssertionPlant</*0*/ out T : kotlin.Any> {
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
}
public interface AssertionPlantNullable</*0*/ out T> : BaseAssertionPlant<T, AssertionPlantNullable<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
}
public interface BaseAssertionPlant</*0*/ out T, /*1*/ out A : BaseAssertionPlant<T, A>> {
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
}
public interface BaseCollectingAssertionPlant</*0*/ out T, /*1*/ out A : BaseAssertionPlant<T, A>, /*2*/ out C : BaseCollectingAssertionPlant<T, A, C>> : BaseAssertionPlant<T, A> {
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
}
public interface CollectingAssertionPlantNullable</*0*/ out T> : AssertionPlantNullable<T>, BaseCollectingAssertionPlant<T, AssertionPlantNullable<T>, CollectingAssertionPlantNullable<T>> {
public open override /*2*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public open override /*2*/ /*fake_override*/ fun hashCode(): kotlin.Int
public open override /*2*/ /*fake_override*/ fun toString(): kotlin.String
}
public interface CreatorLike</*0*/ TSubject, /*1*/ T, /*2*/ A : BaseAssertionPlant<T, A>, /*3*/ C : BaseCollectingAssertionPlant<T, A, C>> {
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
}
public interface CreatorNullable</*0*/ TSubject, /*1*/ T> : CreatorLike<TSubject, T, AssertionPlantNullable<T>, CollectingAssertionPlantNullable<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
}
public final class ParameterObject</*0*/ TSubject, /*1*/ T> {
public constructor ParameterObject</*0*/ TSubject, /*1*/ 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
}
public interface ParameterObjectOption {
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
public open fun </*0*/ TSubject : kotlin.Any, /*1*/ T> withParameterObjectNullable(/*0*/ parameterObject: ParameterObject<TSubject, T>): CreatorNullable<TSubject, T>
}
@@ -0,0 +1,14 @@
// FIR_IDENTICAL
// !DIAGNOSTICS: -UNUSED_PARAMETER
fun useList(list: List<Any?>) { }
fun useMap(map: Map<String, Any?>) { }
enum class Color {BLUE}
fun Color.grayValue() {}
fun test() {
useList(listOf({ x: Color -> x.grayValue() }, Color.BLUE))
useMap(mapOf("a" to { x: Color -> x.grayValue() }, "b" to Color.BLUE))
}
@@ -0,0 +1,25 @@
package
public fun test(): kotlin.Unit
public fun useList(/*0*/ list: kotlin.collections.List<kotlin.Any?>): kotlin.Unit
public fun useMap(/*0*/ map: kotlin.collections.Map<kotlin.String, kotlin.Any?>): kotlin.Unit
public fun Color.grayValue(): kotlin.Unit
public final enum class Color : kotlin.Enum<Color> {
enum entry BLUE
private constructor Color()
public final override /*1*/ /*fake_override*/ val name: kotlin.String
public final override /*1*/ /*fake_override*/ val ordinal: kotlin.Int
protected final override /*1*/ /*fake_override*/ fun clone(): kotlin.Any
public final override /*1*/ /*fake_override*/ fun compareTo(/*0*/ other: Color): kotlin.Int
public final override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
protected/*protected and package*/ final override /*1*/ /*fake_override*/ /*isHiddenForResolutionEverywhereBesideSupercalls*/ fun finalize(): kotlin.Unit
public final override /*1*/ /*fake_override*/ /*isHiddenForResolutionEverywhereBesideSupercalls*/ fun getDeclaringClass(): java.lang.Class<Color!>!
public final override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
// Static members
public final /*synthesized*/ fun valueOf(/*0*/ value: kotlin.String): Color
public final /*synthesized*/ fun values(): kotlin.Array<Color>
}
@@ -0,0 +1,11 @@
// !DIAGNOSTICS: -UNUSED_PARAMETER -UNCHECKED_CAST
fun <T : Any> foo(items: List<T>, handler: (T) -> Unit) {}
class Foo<T>(x: T)
fun <T> materialize(): T = null as T
fun main(x: List<String>?) {
foo(x?.map { Foo(it) } ?: listOf(materialize<Foo<Nothing>>())) {}
}
@@ -0,0 +1,11 @@
// !DIAGNOSTICS: -UNUSED_PARAMETER -UNCHECKED_CAST
fun <T : Any> foo(items: List<T>, handler: (T) -> Unit) {}
class Foo<T>(x: T)
fun <T> materialize(): T = null as T
fun main(x: List<String>?) {
foo(x?.map { Foo(<!DEBUG_INFO_EXPRESSION_TYPE("kotlin.String")!>it<!>) } ?: listOf(materialize<Foo<Nothing>>())) {}
}
@@ -0,0 +1,12 @@
package
public fun </*0*/ T : kotlin.Any> foo(/*0*/ items: kotlin.collections.List<T>, /*1*/ handler: (T) -> kotlin.Unit): kotlin.Unit
public fun main(/*0*/ x: kotlin.collections.List<kotlin.String>?): kotlin.Unit
public fun </*0*/ T> materialize(): T
public final class Foo</*0*/ T> {
public constructor Foo</*0*/ T>(/*0*/ x: 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
}
@@ -0,0 +1,10 @@
// FIR_IDENTICAL
// !DIAGNOSTICS: -CAST_NEVER_SUCCEEDS -UNUSED_PARAMETER -UNCHECKED_CAST
fun <T> materialize() = null as T
val x: Map<String, String> = materialize<List<Map<String, String>>>().fold(mutableMapOf()) { m, x ->
val (s, action) = x.entries.first()
m[s] = action
m
}
@@ -0,0 +1,4 @@
package
public val x: kotlin.collections.Map<kotlin.String, kotlin.String>
public fun </*0*/ T> materialize(): T
@@ -0,0 +1,9 @@
// FIR_IDENTICAL
// !DIAGNOSTICS: -UNUSED_PARAMETER -UNUSED_ANONYMOUS_PARAMETER
fun <T : Any> xSelectButton2(items: (matcher: String) -> List<T>, handler: T.() -> Unit) {}
fun main() {
val x: List<Int>? = listOf()
xSelectButton2({ matcher -> x ?: emptyList() }) { this.inv() }
}
@@ -0,0 +1,4 @@
package
public fun main(): kotlin.Unit
public fun </*0*/ T : kotlin.Any> xSelectButton2(/*0*/ items: (matcher: kotlin.String) -> kotlin.collections.List<T>, /*1*/ handler: T.() -> kotlin.Unit): kotlin.Unit
@@ -0,0 +1,6 @@
// FIR_IDENTICAL
interface ObservableSet<out T> : Set<T> {}
fun <K> test(x: List<ObservableSet<K>>) {
x.reduce { acc: Set<K>, set: Set<K> -> acc + set }
}
@@ -0,0 +1,14 @@
package
public fun </*0*/ K> test(/*0*/ x: kotlin.collections.List<ObservableSet<K>>): kotlin.Unit
public interface ObservableSet</*0*/ out T> : kotlin.collections.Set<T> {
public abstract override /*1*/ /*fake_override*/ val size: kotlin.Int
public abstract override /*1*/ /*fake_override*/ fun contains(/*0*/ element: T): kotlin.Boolean
public abstract override /*1*/ /*fake_override*/ fun containsAll(/*0*/ elements: kotlin.collections.Collection<T>): kotlin.Boolean
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 abstract override /*1*/ /*fake_override*/ fun isEmpty(): kotlin.Boolean
public abstract override /*1*/ /*fake_override*/ fun iterator(): kotlin.collections.Iterator<T>
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
}
@@ -0,0 +1,12 @@
// FIR_IDENTICAL
// !DIAGNOSTICS: -UNUSED_PARAMETER
class ArraySortedChecker<A, T>(val array: A, val comparator: Comparator<in T>) {
fun <R> checkSorted(sorted: A.() -> R, sortedDescending: A.() -> R, iterator: R.() -> Iterator<T>) {}
}
fun <A, T: Comparable<T>> arrayData(vararg values: T, toArray: Array<out T>.() -> A) = ArraySortedChecker<A, T>(values.toArray(), naturalOrder())
fun main() {
with (arrayData("ac", "aD", "aba") { toList().toTypedArray() }) {}
}
@@ -0,0 +1,14 @@
package
public fun </*0*/ A, /*1*/ T : kotlin.Comparable<T>> arrayData(/*0*/ vararg values: T /*kotlin.Array<out T>*/, /*1*/ toArray: kotlin.Array<out T>.() -> A): ArraySortedChecker<A, T>
public fun main(): kotlin.Unit
public final class ArraySortedChecker</*0*/ A, /*1*/ T> {
public constructor ArraySortedChecker</*0*/ A, /*1*/ T>(/*0*/ array: A, /*1*/ comparator: kotlin.Comparator<in T> /* = java.util.Comparator<in T> */)
public final val array: A
public final val comparator: kotlin.Comparator<in T> /* = java.util.Comparator<in T> */
public final fun </*0*/ R> checkSorted(/*0*/ sorted: A.() -> R, /*1*/ sortedDescending: A.() -> R, /*2*/ iterator: R.() -> kotlin.collections.Iterator<T>): kotlin.Unit
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
}
@@ -0,0 +1,27 @@
// FIR_IDENTICAL
// !DIAGNOSTICS: -UNUSED_PARAMETER
class Wrapper<T> (val x: T)
inline fun <T, R> Wrapper<T>.unwrap(validator: (T) -> R): R = validator(x)
fun <T> select(x: T) {}
class Foo<W>(y: Wrapper<List<W>>) {
fun <T> MutableCollection<T>.foo(x: T) {}
fun <T> MutableCollection<T>.foo(x: Iterable<T>) {}
init {
/*
* Before the fix, `foo` can't be disambiguated because the lambda is alanyzed in full mode,
* not in partial as before the inroducing new posponed arguments analysis.
*
* It happens due to the lack of rerun stages after fixation variables
* (stage 5 see `fixVariablesOrReportNotEnoughInformation` in `KotlinConstraintSystemCompleter.kt`).
* Rerun is need as fixation of variables can be make lambda available for analysis.
*
* TODO: add tests with lambdas, which can't be analyzed in partial mode, but if can, the code will be successfully resolved.
*/
ArrayList<W>().foo(y.unwrap { it })
}
}
@@ -0,0 +1,21 @@
package
public fun </*0*/ T> select(/*0*/ x: T): kotlin.Unit
public inline fun </*0*/ T, /*1*/ R> Wrapper<T>.unwrap(/*0*/ validator: (T) -> R): R
public final class Foo</*0*/ W> {
public constructor Foo</*0*/ W>(/*0*/ y: Wrapper<kotlin.collections.List<W>>)
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
public final fun </*0*/ T> kotlin.collections.MutableCollection<T>.foo(/*0*/ x: T): kotlin.Unit
public final fun </*0*/ T> kotlin.collections.MutableCollection<T>.foo(/*0*/ x: kotlin.collections.Iterable<T>): kotlin.Unit
}
public final class Wrapper</*0*/ T> {
public constructor Wrapper</*0*/ T>(/*0*/ x: T)
public final val x: 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
}
@@ -0,0 +1,8 @@
Failures detected in FirBodyResolveTransformerAdapter, file: /suspendFunctions.fir.kt
Cause: java.lang.RuntimeException: While resolving call R?C|/takeSuspend|(R?C|/id|(<L> = id@fun <implicit>.<anonymous>(): <implicit> {
it#
}
), takeSuspend@fun <anonymous>(x: R|kotlin/Int|): R|kotlin/Unit| {
^ R|<local>/x|
}
)
@@ -0,0 +1,25 @@
// !DIAGNOSTICS: -UNUSED_VARIABLE -UNUSED_EXPRESSION -UNUSED_PARAMETER -UNUSED_ANONYMOUS_PARAMETER
fun <T> select(vararg x: T) = x[0]
fun <K> id(x: K): K = x
fun <T: suspend (Int) -> Unit, K: T> takeSuspend(x: T, y: K) = x
fun <T: (Int) -> Unit, K: T> takeSimpleFunction(x: T, y: K) = x
fun main() {
select(suspend {}, <!DEBUG_INFO_EXPRESSION_TYPE("suspend () -> kotlin.Unit")!>{}<!>)
select(<!DEBUG_INFO_EXPRESSION_TYPE("suspend () -> kotlin.Unit")!>{}<!>, suspend {})
select(<!DEBUG_INFO_EXPRESSION_TYPE("suspend () -> kotlin.Unit")!>id {}<!>, suspend {})
select(<!DEBUG_INFO_EXPRESSION_TYPE("suspend () -> kotlin.Unit")!>id {}<!>, id(suspend {}))
select(<!DEBUG_INFO_EXPRESSION_TYPE("suspend () -> kotlin.Unit")!>id {}<!>, id<suspend () -> Unit> {})
takeSuspend(<!DEBUG_INFO_EXPRESSION_TYPE("suspend (kotlin.Int) -> kotlin.Unit")!>id { it }<!>, <!DEBUG_INFO_EXPRESSION_TYPE("suspend (kotlin.Int) -> kotlin.Unit")!>{ x -> x }<!>)
val x1: suspend (Int) -> Unit = takeSuspend(<!DEBUG_INFO_EXPRESSION_TYPE("suspend (kotlin.Int) -> kotlin.Unit")!>id { it }<!>, <!DEBUG_INFO_EXPRESSION_TYPE("suspend (kotlin.Int) -> kotlin.Unit")!>{ x -> x }<!>)
// Here, the error should be
val x2: (Int) -> Unit = <!TYPE_MISMATCH!>takeSuspend(<!DEBUG_INFO_EXPRESSION_TYPE("suspend (kotlin.Int) -> kotlin.Unit")!>id <!TYPE_MISMATCH, TYPE_MISMATCH, TYPE_MISMATCH, TYPE_MISMATCH!>{ it }<!><!>, <!DEBUG_INFO_EXPRESSION_TYPE("suspend (kotlin.Int) -> kotlin.Unit"), TYPE_MISMATCH, TYPE_MISMATCH, TYPE_MISMATCH, TYPE_MISMATCH, TYPE_MISMATCH!>{ x -> x }<!>)<!>
val x3: suspend (Int) -> Unit = takeSimpleFunction(<!DEBUG_INFO_EXPRESSION_TYPE("suspend (kotlin.Int) -> kotlin.Unit")!>id <!TYPE_MISMATCH, TYPE_MISMATCH, TYPE_MISMATCH, TYPE_MISMATCH!>{ it }<!><!>, <!DEBUG_INFO_EXPRESSION_TYPE("suspend (kotlin.Int) -> kotlin.Unit"), TYPE_MISMATCH, TYPE_MISMATCH, TYPE_MISMATCH, TYPE_MISMATCH, TYPE_MISMATCH!>{ x -> x }<!>)
val x4: (Int) -> Unit = <!TYPE_MISMATCH, TYPE_MISMATCH!>takeSimpleFunction(<!TYPE_MISMATCH!>id<suspend (Int) -> Unit> {}<!>, <!DEBUG_INFO_EXPRESSION_TYPE("suspend (kotlin.Int) -> kotlin.Unit"), TYPE_MISMATCH, TYPE_MISMATCH, TYPE_MISMATCH, TYPE_MISMATCH, TYPE_MISMATCH, TYPE_MISMATCH, TYPE_MISMATCH, TYPE_MISMATCH, TYPE_MISMATCH, TYPE_MISMATCH!>{}<!>)<!>
}
@@ -0,0 +1,25 @@
// !DIAGNOSTICS: -UNUSED_VARIABLE -UNUSED_EXPRESSION -UNUSED_PARAMETER -UNUSED_ANONYMOUS_PARAMETER
fun <T> select(vararg x: T) = x[0]
fun <K> id(x: K): K = x
fun <T: suspend (Int) -> Unit, K: T> takeSuspend(x: T, y: K) = x
fun <T: (Int) -> Unit, K: T> takeSimpleFunction(x: T, y: K) = x
fun main() {
select(suspend {}, <!DEBUG_INFO_EXPRESSION_TYPE("suspend () -> kotlin.Unit")!>{}<!>)
select(<!DEBUG_INFO_EXPRESSION_TYPE("suspend () -> kotlin.Unit")!>{}<!>, suspend {})
select(<!DEBUG_INFO_EXPRESSION_TYPE("suspend () -> kotlin.Unit")!>id {}<!>, suspend {})
select(<!DEBUG_INFO_EXPRESSION_TYPE("suspend () -> kotlin.Unit")!>id {}<!>, id(suspend {}))
select(<!DEBUG_INFO_EXPRESSION_TYPE("suspend () -> kotlin.Unit")!>id {}<!>, id<suspend () -> Unit> {})
takeSuspend(<!DEBUG_INFO_EXPRESSION_TYPE("suspend (kotlin.Int) -> kotlin.Unit")!>id { it }<!>, <!DEBUG_INFO_EXPRESSION_TYPE("suspend (kotlin.Int) -> kotlin.Unit")!>{ x -> x }<!>)
val x1: suspend (Int) -> Unit = takeSuspend(<!DEBUG_INFO_EXPRESSION_TYPE("suspend (kotlin.Int) -> kotlin.Unit")!>id { it }<!>, <!DEBUG_INFO_EXPRESSION_TYPE("suspend (kotlin.Int) -> kotlin.Unit")!>{ x -> x }<!>)
// Here, the error should be
val x2: (Int) -> Unit = <!TYPE_MISMATCH!>takeSuspend(<!DEBUG_INFO_EXPRESSION_TYPE("suspend (kotlin.Int) -> kotlin.Unit")!>id <!TYPE_MISMATCH, TYPE_MISMATCH, TYPE_MISMATCH, TYPE_MISMATCH!>{ it }<!><!>, <!DEBUG_INFO_EXPRESSION_TYPE("suspend (kotlin.Int) -> kotlin.Unit"), TYPE_MISMATCH, TYPE_MISMATCH, TYPE_MISMATCH, TYPE_MISMATCH, TYPE_MISMATCH!>{ x -> x }<!>)<!>
val x3: suspend (Int) -> Unit = takeSimpleFunction(<!DEBUG_INFO_EXPRESSION_TYPE("suspend (kotlin.Int) -> kotlin.Unit")!>id <!TYPE_MISMATCH, TYPE_MISMATCH, TYPE_MISMATCH, TYPE_MISMATCH!>{ it }<!><!>, <!DEBUG_INFO_EXPRESSION_TYPE("suspend (kotlin.Int) -> kotlin.Unit"), TYPE_MISMATCH, TYPE_MISMATCH, TYPE_MISMATCH, TYPE_MISMATCH, TYPE_MISMATCH!>{ x -> x }<!>)
val x4: (Int) -> Unit = <!TYPE_MISMATCH, TYPE_MISMATCH!>takeSimpleFunction(<!TYPE_MISMATCH!>id<suspend (Int) -> Unit> {}<!>, <!DEBUG_INFO_EXPRESSION_TYPE("suspend (kotlin.Int) -> kotlin.Unit"), TYPE_MISMATCH, TYPE_MISMATCH, TYPE_MISMATCH, TYPE_MISMATCH, TYPE_MISMATCH, TYPE_MISMATCH, TYPE_MISMATCH, TYPE_MISMATCH, TYPE_MISMATCH, TYPE_MISMATCH!>{}<!>)<!>
}
@@ -0,0 +1,7 @@
package
public fun </*0*/ K> id(/*0*/ x: K): K
public fun main(): kotlin.Unit
public fun </*0*/ T> select(/*0*/ vararg x: T /*kotlin.Array<out T>*/): T
public fun </*0*/ T : (kotlin.Int) -> kotlin.Unit, /*1*/ K : T> takeSimpleFunction(/*0*/ x: T, /*1*/ y: K): T
public fun </*0*/ T : suspend (kotlin.Int) -> kotlin.Unit, /*1*/ K : T> takeSuspend(/*0*/ x: T, /*1*/ y: K): T