psi2ir: inferred type for 'when' is Nothing only if it's exhaustive

TODO: fix inference bug
This commit is contained in:
Dmitry Petrov
2018-05-03 16:25:05 +03:00
parent 70622ff668
commit 21dfee4565
6 changed files with 117 additions and 10 deletions
+27
View File
@@ -0,0 +1,27 @@
fun one() = 1
fun two() = 2
fun test1(): Int {
while (true) {
when (one()) {
1 -> {
when(two()) {
2 -> return 2
}
} // : Nothing
else -> return 3
}
}
}
fun test2(): Int {
while (true) {
when (one()) {
1 ->
when (two()) {
2 -> return 2
} // : Unit -> Nothing
else -> return 3
} // : Nothing
}
}
+68
View File
@@ -0,0 +1,68 @@
FILE fqName:<root> fileName:/kt24114.kt
FUN name:one visibility:public modality:FINAL <> () returnType:Int flags:
BLOCK_BODY
RETURN type=kotlin.Nothing from='one(): Int'
CONST Int type=kotlin.Int value=1
FUN name:two visibility:public modality:FINAL <> () returnType:Int flags:
BLOCK_BODY
RETURN type=kotlin.Nothing from='two(): Int'
CONST Int type=kotlin.Int value=2
FUN name:test1 visibility:public modality:FINAL <> () returnType:Int flags:
BLOCK_BODY
WHILE label=null origin=WHILE_LOOP
condition: CONST Boolean type=kotlin.Boolean value=true
body: BLOCK type=kotlin.Unit origin=null
BLOCK type=kotlin.Nothing origin=WHEN
VAR IR_TEMPORARY_VARIABLE name:tmp0_subject type:kotlin.Int flags:val
CALL 'one(): Int' type=kotlin.Int origin=null
WHEN type=kotlin.Nothing origin=WHEN
BRANCH
if: CALL 'EQEQ(Any?, Any?): Boolean' type=kotlin.Boolean origin=EQEQ
arg0: GET_VAR 'tmp0_subject: Int' type=kotlin.Int origin=null
arg1: CONST Int type=kotlin.Int value=1
then: BLOCK type=kotlin.Nothing origin=null
TYPE_OP type=kotlin.Nothing origin=IMPLICIT_CAST typeOperand=kotlin.Nothing
typeOperand: CLASS IR_EXTERNAL_DECLARATION_STUB CLASS name:Nothing modality:FINAL visibility:public flags:
BLOCK type=kotlin.Unit origin=WHEN
VAR IR_TEMPORARY_VARIABLE name:tmp1_subject type:kotlin.Int flags:val
CALL 'two(): Int' type=kotlin.Int origin=null
WHEN type=kotlin.Unit origin=WHEN
BRANCH
if: CALL 'EQEQ(Any?, Any?): Boolean' type=kotlin.Boolean origin=EQEQ
arg0: GET_VAR 'tmp1_subject: Int' type=kotlin.Int origin=null
arg1: CONST Int type=kotlin.Int value=2
then: RETURN type=kotlin.Nothing from='test1(): Int'
CONST Int type=kotlin.Int value=2
BRANCH
if: CONST Boolean type=kotlin.Boolean value=true
then: RETURN type=kotlin.Nothing from='test1(): Int'
CONST Int type=kotlin.Int value=3
FUN name:test2 visibility:public modality:FINAL <> () returnType:Int flags:
BLOCK_BODY
WHILE label=null origin=WHILE_LOOP
condition: CONST Boolean type=kotlin.Boolean value=true
body: BLOCK type=kotlin.Unit origin=null
BLOCK type=kotlin.Nothing origin=WHEN
VAR IR_TEMPORARY_VARIABLE name:tmp0_subject type:kotlin.Int flags:val
CALL 'one(): Int' type=kotlin.Int origin=null
WHEN type=kotlin.Nothing origin=WHEN
BRANCH
if: CALL 'EQEQ(Any?, Any?): Boolean' type=kotlin.Boolean origin=EQEQ
arg0: GET_VAR 'tmp0_subject: Int' type=kotlin.Int origin=null
arg1: CONST Int type=kotlin.Int value=1
then: TYPE_OP type=kotlin.Nothing origin=IMPLICIT_CAST typeOperand=kotlin.Nothing
typeOperand: CLASS IR_EXTERNAL_DECLARATION_STUB CLASS name:Nothing modality:FINAL visibility:public flags:
BLOCK type=kotlin.Unit origin=WHEN
VAR IR_TEMPORARY_VARIABLE name:tmp1_subject type:kotlin.Int flags:val
CALL 'two(): Int' type=kotlin.Int origin=null
WHEN type=kotlin.Unit origin=WHEN
BRANCH
if: CALL 'EQEQ(Any?, Any?): Boolean' type=kotlin.Boolean origin=EQEQ
arg0: GET_VAR 'tmp1_subject: Int' type=kotlin.Int origin=null
arg1: CONST Int type=kotlin.Int value=2
then: RETURN type=kotlin.Nothing from='test2(): Int'
CONST Int type=kotlin.Int value=2
BRANCH
if: CONST Boolean type=kotlin.Boolean value=true
then: RETURN type=kotlin.Nothing from='test2(): Int'
CONST Int type=kotlin.Int value=3