FIR: rewrite lambda return type inference

* `return` should only be added to the last statement if the return
   type is not Unit

 * If there is a `return` without an argument, then the expected return
   type is Unit and the last expression is not a return argument (unless
   it's an incomplete call, in which case it is inferred to return Unit;
   this behavior is questionable, but inherited from K1)

 * There should be a constraint on return arguments even if the expected
   type is Unit, otherwise errors will be missed

 * When the expected type is known, using the call completion results
   writer is pointless (and probably subtly wrong).

^KT-54742 Fixed
This commit is contained in:
pyos
2022-12-08 12:02:43 +01:00
committed by Dmitriy Novozhilov
parent 544cf386af
commit 803abfeba8
21 changed files with 241 additions and 538 deletions
@@ -27,7 +27,7 @@ fun testResultOfAnonFun2() =
fun testReturnFromAnonFun() =
run(fun () {
return <!RETURN_TYPE_MISMATCH!>if (true) 42 else println()<!>
return <!ARGUMENT_TYPE_MISMATCH, RETURN_TYPE_MISMATCH!>if (true) 42 else println()<!>
})
fun <!IMPLICIT_NOTHING_RETURN_TYPE!>testReturn1<!>() =
@@ -34,7 +34,7 @@ fun test4() = <!INFERRED_TYPE_VARIABLE_INTO_EMPTY_INTERSECTION!>run<!> {
fun main() {
// all ok
expectUnit(<!ARGUMENT_TYPE_MISMATCH!>test1()<!>)
expectUnit(test1())
expectUnit(test2())
expectUnit(test3())
expectUnit(test4())
@@ -139,8 +139,8 @@ fun main() {
* K <: (C) -> Unit -> TypeVariable(_RP1) >: C
* K == (B) -> Unit -> TypeVariable(_RP1) == B
*/
val x17: (C) -> Unit = <!INITIALIZER_TYPE_MISMATCH, TYPE_MISMATCH!>selectB(id <!ARGUMENT_TYPE_MISMATCH!>{ <!DEBUG_INFO_EXPRESSION_TYPE("B")!>it<!> }<!>, id <!ARGUMENT_TYPE_MISMATCH!>{ it }<!>, id<(B) -> Unit> { x -> x })<!>
val x18: (C) -> Unit = <!TYPE_MISMATCH!>select(id <!ARGUMENT_TYPE_MISMATCH!>{ <!DEBUG_INFO_EXPRESSION_TYPE("C")!>it<!> }<!>, <!ARGUMENT_TYPE_MISMATCH!>{ <!DEBUG_INFO_EXPRESSION_TYPE("C")!>it<!> }<!>, id<(B) -> Unit> { x -> x })<!>
val x17: (C) -> Unit = <!INITIALIZER_TYPE_MISMATCH, TYPE_MISMATCH!>selectB(id <!ARGUMENT_TYPE_MISMATCH, ARGUMENT_TYPE_MISMATCH!>{ <!DEBUG_INFO_EXPRESSION_TYPE("B")!>it<!> }<!>, id <!ARGUMENT_TYPE_MISMATCH, ARGUMENT_TYPE_MISMATCH!>{ it }<!>, id<(B) -> Unit> { x -> x })<!>
val x18: (C) -> Unit = <!TYPE_MISMATCH!>select(id <!ARGUMENT_TYPE_MISMATCH!>{ <!DEBUG_INFO_EXPRESSION_TYPE("C")!>it<!> }<!>, <!ARGUMENT_TYPE_MISMATCH, ARGUMENT_TYPE_MISMATCH!>{ <!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("kotlin.String")!>this<!> }<!>, <!DEBUG_INFO_EXPRESSION_TYPE("kotlin.Function1<kotlin.String, kotlin.Unit>")!>id(fun(x: String) {})<!>)
@@ -3,5 +3,5 @@
fun foo(l: () -> Unit) {}
fun bar(l: () -> String) {}
val a = foo { <!UNSUPPORTED!>[]<!> }
val b = bar { <!UNSUPPORTED!>[]<!> }
val a = foo { <!ARGUMENT_TYPE_MISMATCH, UNSUPPORTED!>[]<!> }
val b = bar { <!ARGUMENT_TYPE_MISMATCH, UNSUPPORTED!>[]<!> }