K2: allow/disallow coercion-to-unit for callable references more precisely

Before this commit, K2 always applied coercion-to-unit for
callable references if expected type was Unit, and actual non-Unit.
However, this may not work in case when actual return type is
a type parameter and it must be inferred into Unit.
In this commit we started to disallow coercion-to-unit
for references with synthetic outer call (~ top-level in K1)
AND a type parameter as a return type (both should be true to disallow).
This provides better K1 consistency,
while still keeping some broken K1 cases working in K2.

See also added comment in CallableReferenceResolution.kt.

#KT-62565 Fixed
This commit is contained in:
Mikhail Glukhikh
2023-12-05 15:12:31 +01:00
committed by Space Team
parent 25c0bd278e
commit 2680c8effd
16 changed files with 213 additions and 16 deletions
@@ -0,0 +1,30 @@
// DIAGNOSTICS: -UNCHECKED_CAST
// This test is a copy of conversionLastStatementInLambda, but with generic functions
// However works diffirently in K1
fun main(b: Boolean) {
callWithLambda {
::test1
}
callWithLambda {
if (b) ::test1 else ::test2
}
callWithLambda {
if (b) {
::test1
} else {
::test2
}
}
callWithLambda {
(::test1)
}
}
fun <T> test1(): T = "" as T
fun <T> test2(): T = "" as T
fun callWithLambda(action: () -> () -> Unit) {}
@@ -0,0 +1,30 @@
// DIAGNOSTICS: -UNCHECKED_CAST
// This test is a copy of conversionLastStatementInLambda, but with generic functions
// However works diffirently in K1
fun main(b: Boolean) {
callWithLambda {
<!NEW_INFERENCE_NO_INFORMATION_FOR_PARAMETER!>::test1<!>
}
callWithLambda {
if (b) <!NEW_INFERENCE_NO_INFORMATION_FOR_PARAMETER!>::test1<!> else <!NEW_INFERENCE_NO_INFORMATION_FOR_PARAMETER!>::test2<!>
}
callWithLambda {
if (b) {
::test1
} else {
::test2
}
}
callWithLambda {
(<!NEW_INFERENCE_NO_INFORMATION_FOR_PARAMETER!>::test1<!>)
}
}
fun <T> test1(): T = "" as T
fun <T> test2(): T = "" as T
fun callWithLambda(action: () -> () -> Unit) {}
@@ -0,0 +1,10 @@
// FIR_IDENTICAL
// WITH_STDLIB
fun <N : Number> addNumber(n: N) = n
fun foo() = 42
fun test() {
foo().apply(::addNumber)
}