[FIR] Properly pass type attributes for inference of lambda with type variable as expected type

#KT-41989 Fixed
#KT-37317 Fixed
This commit is contained in:
Dmitriy Novozhilov
2020-09-25 10:55:19 +03:00
parent d9906ae8da
commit 0c0a8f9849
14 changed files with 90 additions and 77 deletions
@@ -142,8 +142,8 @@ fun main() {
val x18: (C) -> Unit = select(id { <!DEBUG_INFO_EXPRESSION_TYPE("C")!>it<!> }, { <!DEBUG_INFO_EXPRESSION_TYPE("C")!>it<!> }, id<(B) -> Unit> { x -> x })
// Resolution of extension/non-extension functions combination
val x19: String.() -> Unit = select(<!DEBUG_INFO_EXPRESSION_TYPE("kotlin.Function1<kotlin.String, kotlin.Unit>")!>id { <!DEBUG_INFO_EXPRESSION_TYPE("ERROR CLASS: 'this' is not defined in this context"), DEBUG_INFO_EXPRESSION_TYPE("ERROR CLASS: 'this' is not defined in this context"), NO_THIS!>this<!> }<!>, <!DEBUG_INFO_EXPRESSION_TYPE("kotlin.Function1<kotlin.String, kotlin.Unit>")!>id(fun(x: String) {})<!>)
val x20: String.() -> Unit = select(<!DEBUG_INFO_EXPRESSION_TYPE("kotlin.Function1<kotlin.String, kotlin.Unit>")!>{ <!DEBUG_INFO_EXPRESSION_TYPE("ERROR CLASS: 'this' is not defined in this context"), DEBUG_INFO_EXPRESSION_TYPE("ERROR CLASS: 'this' is not defined in this context"), NO_THIS!>this<!> }<!>, (fun(x: String) {}))
val x19: String.() -> Unit = select(<!DEBUG_INFO_EXPRESSION_TYPE("kotlin.Function1<kotlin.String, kotlin.String>")!>id { <!DEBUG_INFO_EXPRESSION_TYPE("kotlin.String"), DEBUG_INFO_EXPRESSION_TYPE("kotlin.String")!>this<!> }<!>, <!DEBUG_INFO_EXPRESSION_TYPE("kotlin.Function1<kotlin.String, kotlin.Unit>")!>id(fun(x: String) {})<!>)
val x20: String.() -> Unit = select(<!DEBUG_INFO_EXPRESSION_TYPE("kotlin.Function1<kotlin.String, kotlin.Unit>")!>{ <!DEBUG_INFO_EXPRESSION_TYPE("kotlin.String"), DEBUG_INFO_EXPRESSION_TYPE("kotlin.String")!>this<!> }<!>, (fun(x: String) {}))
val x21: String.() -> Unit = select(<!DEBUG_INFO_EXPRESSION_TYPE("kotlin.Function1<kotlin.String, kotlin.Unit>")!>id(fun(x: String) {})<!>, <!DEBUG_INFO_EXPRESSION_TYPE("kotlin.Function1<kotlin.String, kotlin.Unit>")!>id(fun(x: String) {})<!>)
select(id<String.() -> Unit>(fun(x: String) {}), <!DEBUG_INFO_EXPRESSION_TYPE("kotlin.Function1<kotlin.String, kotlin.Unit>")!>id(fun(x: String) {})<!>)
select(<!DEBUG_INFO_EXPRESSION_TYPE("kotlin.Function2<kotlin.String, kotlin.String, kotlin.Unit>")!>id(fun String.(x: String) {})<!>, <!DEBUG_INFO_EXPRESSION_TYPE("kotlin.Function2<kotlin.String, kotlin.String, kotlin.Unit>")!>id(fun(x: String, y: String) {})<!>)
@@ -3,14 +3,14 @@
fun <T> select(vararg x: T) = x[0]
fun main() {
val x1: String.() -> String = if (true) {{ <!NO_THIS!>this<!> }} else {{ <!NO_THIS!>this<!> }}
val x2: String.() -> String = if (true) {{ -> <!NO_THIS!>this<!> }} else {{ -> <!NO_THIS!>this<!> }}
val x1: String.() -> String = if (true) {{ this }} else {{ this }}
val x2: String.() -> String = if (true) {{ -> this }} else {{ -> this }}
val x3: () -> String = if (true) {{ -> "this" }} else {{ -> "this" }}
val x4: String.() -> String = if (true) {{ str: String -> "this" }} else {{ str: String -> "this" }}
val x41: String.(String) -> String = if (true) {{ str: String, str2: String -> "this" }} else {{ str: String, str2: String -> "this" }}
val x42: String.(String) -> String = if (true) {{ str, str2 -> "this" }} else {{ str, str2 -> "this" }}
val x5: String.() -> String = if (true) {{ str -> "this" }} else {{ str -> "this" }}
val x6: String.() -> String = if (true) {{ str -> "this" }} else {{ "this" }}
val x7: String.() -> String = select({ -> <!NO_THIS!>this<!> }, { -> <!NO_THIS!>this<!> })
val x8: String.() -> String = select({ <!NO_THIS!>this<!> }, { <!NO_THIS!>this<!> })
val x7: String.() -> String = select({ -> this }, { -> this })
val x8: String.() -> String = select({ this }, { this })
}
@@ -1,47 +0,0 @@
// !LANGUAGE: +NewInference
// !DIAGNOSTICS: -UNUSED_PARAMETER -UNUSED_VARIABLE -UNUSED_ANONYMOUS_PARAMETER -CAST_NEVER_SUCCEEDS
// ISSUE: KT-36819
// Case 1
fun <K> select(vararg x: K) = x[0]
interface A
class B: A
class C: A
fun <T> id1(x: T): T = x
fun <R> id2(x: R): R = x
class Out<out R>(x: R)
fun main() {
val x1 = select(id1 { B() }, id2 { C() })
val x2 = select({ B() }, { C() })
val x3 = select(id1(Out(B())), id2(Out(C())))
}
// Case 2
fun <R> fold(initial: R, operation: (R) -> Unit) {}
fun foo() {
fold({ x: Int -> x }) { acc -> }
}
// Case 3
class Foo
typealias X = Foo.(Foo.() -> Unit) -> Unit
fun bar() {
val y = when {
false -> { _ ->
Unit
}
true -> null as X
else -> { x ->
<!UNRESOLVED_REFERENCE!>x<!>()
Unit
}
}
}
@@ -1,3 +1,4 @@
// FIR_IDENTICAL
// !LANGUAGE: +NewInference
// !DIAGNOSTICS: -UNUSED_PARAMETER -UNUSED_VARIABLE -UNUSED_ANONYMOUS_PARAMETER -CAST_NEVER_SUCCEEDS
// ISSUE: KT-36819
@@ -39,8 +39,8 @@ class W4(val f: L2) {
fun test1() { // to extension lambda 0
val w10 = W1 { this } // oi+ ni+
val i10: E0 = id { <!NO_THIS!>this<!> } // o1- ni+
val j10 = id<E0> { <!NO_THIS!>this<!> } // oi+ ni+
val i10: E0 = id { this } // o1- ni+
val j10 = id<E0> { this } // oi+ ni+
val f10 = W1(fun Int.(): Int = this) // oi+ ni+
val g10: E0 = id(fun Int.(): Int = this) // oi+ ni+
@@ -60,23 +60,23 @@ fun test1() { // to extension lambda 0
fun test2() { // to extension lambda 1
val w20 = W2 { this + it.length } // oi+ ni+
val i20: E1 = id { <!NO_THIS!>this<!> + <!UNRESOLVED_REFERENCE!>it<!>.<!UNRESOLVED_REFERENCE!>length<!> } // oi- ni+
val i20: E1 = id { this + it.length } // oi- ni+
val w21 = W2 { this } // oi+ ni+
val i21: E1 = id { <!NO_THIS!>this<!> } // oi- ni+
val i21: E1 = id { this } // oi- ni+
val f21 = W2(fun Int.(String): Int = this) // oi+ ni+
val g21: E1 = id(fun Int.(String): Int = this) // oi+ ni+
val w22 = W2 { s -> this + s.length } // oi+ ni+
val i22: E1 = id { s -> <!NO_THIS!>this<!> + s.<!UNRESOLVED_REFERENCE!>length<!> } // oi+ ni+
val i22: E1 = id { s -> this + s.length } // oi+ ni+
val w23 = W2 { s -> s.length } // oi+ ni+
val i23: E1 = id { s -> s.<!UNRESOLVED_REFERENCE!>length<!> } // oi+ ni+
val i23: E1 = id { s -> s.length } // oi+ ni+
val w24 = W2 { s: String -> this + s.length } // oi+ ni+
val i24: E1 = id { s: String -> <!NO_THIS!>this<!> + s.length } //oi- ni+
val i24: E1 = id { s: String -> this + s.length } //oi- ni+
val w25 = W2 { s: String -> s.length } // oi+ ni+
val i25: E1 = id { s: String -> s.length } // oi- ni+
val w26 = W2(id { s: String -> <!NO_THIS!>this<!> + s.length }) // oi- ni+
val w26a = W2(id { s -> <!NO_THIS!>this<!> + s.<!UNRESOLVED_REFERENCE!>length<!> }) // oi+ ni+
val i26: E1 = id { s: String -> <!NO_THIS!>this<!> + s.length } // oi- ni+
val i26a: E1 = id { s -> <!NO_THIS!>this<!> + s.<!UNRESOLVED_REFERENCE!>length<!> } // oi+ ni+
val w26 = W2(id { s: String -> this + s.length }) // oi- ni+
val w26a = W2(id { s -> this + s.length }) // oi+ ni+
val i26: E1 = id { s: String -> this + s.length } // oi- ni+
val i26a: E1 = id { s -> this + s.length } // oi+ ni+
val e = E.VALUE
val w27 = <!INAPPLICABLE_CANDIDATE!>W2<!>(when (e) { E.VALUE -> { s: String -> <!NO_THIS!>this<!> + s.length } }) // oi- ni+
val w27a = <!INAPPLICABLE_CANDIDATE!>W2<!>(when (e) { E.VALUE -> { s -> <!NO_THIS!>this<!> + s.<!UNRESOLVED_REFERENCE!>length<!> } }) // oi+ ni+
@@ -84,7 +84,7 @@ fun test2() { // to extension lambda 1
val i27a: E1 = when (e) { E.VALUE -> { s -> <!NO_THIS!>this<!> + s.<!UNRESOLVED_REFERENCE!>length<!> } } // oi+ ni+
val w28 = <!INAPPLICABLE_CANDIDATE!>W2<!> { i: Int, s -> i <!AMBIGUITY!>+<!> s.<!UNRESOLVED_REFERENCE!>length<!> } // oi- ni-
val i28: E1 = id { i: Int, s -> i + s.length } // oi- ni-
val i28: E1 = id { i: Int, s -> i <!AMBIGUITY!>+<!> s.<!UNRESOLVED_REFERENCE!>length<!> } // oi- ni-
val w29 = <!INAPPLICABLE_CANDIDATE!>W2<!> { i: Int, s: String -> i + s.length } // oi- ni-
val i29: E1 = id { i: Int, s: String -> i + s.length } // oi+ ni+