K2: Avoid using Nothing? as inference result in the majority of cases

Namely, do not choose `Nothing?` result type when fixing a variable
that has other constraints besides the ones that came from
the relevant type parameter's upper bounds.

See more details in KT-55691.

In K1, the case from specialCallWithMaterializeAndExpectedType.kt
was working (inferred to String?) just because the branches
were analyzed independently with `String?` expected type.

This change became necessary after the previous commit when we united
inference subsystems for if/when branches (see motivation there).

NB: For K1, the behavior is left the same, but the code
was refactored a bit.

^KT-55691 Fixed
^KT-56448 Fixed
This commit is contained in:
Denis.Zharkov
2022-12-02 19:28:18 +01:00
committed by Space Team
parent f12a4e08cf
commit 2bafcddf7a
18 changed files with 289 additions and 68 deletions
@@ -28,12 +28,12 @@ FILE fqName:<root> fileName:/kt47527.kt
VALUE_PARAMETER name:value index:0 type:kotlin.Any?
BLOCK_BODY
RETURN type=kotlin.Nothing from='public final fun test_2 (value: kotlin.Any?): kotlin.String? declared in <root>'
CALL 'public final fun run <R> (block: kotlin.Function0<R of kotlin.StandardKt.run>): R of kotlin.StandardKt.run [inline] declared in kotlin.StandardKt' type=kotlin.Nothing? origin=null
<R>: kotlin.Nothing?
block: FUN_EXPR type=kotlin.Function0<kotlin.Nothing?> origin=LAMBDA
FUN LOCAL_FUNCTION_FOR_LAMBDA name:<anonymous> visibility:local modality:FINAL <> () returnType:kotlin.Nothing?
CALL 'public final fun run <R> (block: kotlin.Function0<R of kotlin.StandardKt.run>): R of kotlin.StandardKt.run [inline] declared in kotlin.StandardKt' type=kotlin.String? origin=null
<R>: kotlin.String?
block: FUN_EXPR type=kotlin.Function0<kotlin.String?> origin=LAMBDA
FUN LOCAL_FUNCTION_FOR_LAMBDA name:<anonymous> visibility:local modality:FINAL <> () returnType:kotlin.String?
BLOCK_BODY
RETURN type=kotlin.Nothing from='local final fun <anonymous> (): kotlin.Nothing? declared in <root>.test_2'
RETURN type=kotlin.Nothing from='local final fun <anonymous> (): kotlin.String? declared in <root>.test_2'
BLOCK type=kotlin.Nothing? origin=SAFE_CALL
VAR IR_TEMPORARY_VARIABLE name:tmp_1 type:kotlin.Any? [val]
GET_VAR 'value: kotlin.Any? declared in <root>.test_2' type=kotlin.Any? origin=null
@@ -12,7 +12,7 @@ fun test_1(value: Any?): String? {
}
fun test_2(value: Any?): String? {
return run<Nothing?>(block = local fun <anonymous>(): Nothing? {
return run<String?>(block = local fun <anonymous>(): String? {
return { // BLOCK
val tmp1_safe_receiver: Any? = value
when {