[FIR] Fix propagating expected type for binary operator calls

This commit is contained in:
Dmitriy Novozhilov
2019-08-14 17:48:32 +03:00
parent ba7a137e74
commit e374242adf
6 changed files with 48 additions and 25 deletions
@@ -740,6 +740,15 @@ open class FirBodyResolveTransformer(
}
}
override fun transformOperatorCall(operatorCall: FirOperatorCall, data: Any?): CompositeTransformResult<FirStatement> {
if (operatorCall.operation in FirOperation.BOOLEANS) {
return (operatorCall.transformChildren(this, noExpectedType) as FirOperatorCall).also {
it.resultType = booleanType
}.compose()
}
return super.transformOperatorCall(operatorCall, data)
}
// ----------------------- Util functions -----------------------
private inline fun <T> withLabelAndReceiverType(labelName: Name, owner: FirElement, type: ConeKotlinType, block: () -> T): T {
@@ -8,4 +8,4 @@ FILE fqName:<root> fileName:/localVarInDoWhile.kt
condition: CALL 'public final fun not (): kotlin.Boolean declared in kotlin.Boolean' type=kotlin.Boolean origin=EXCLEQ
$this: CALL 'public final fun EQEQ (arg0: kotlin.Any?, arg1: kotlin.Any?): kotlin.Boolean declared in kotlin.internal.ir' type=kotlin.Boolean origin=EXCLEQ
arg0: GET_VAR 'val x: kotlin.Int [val] declared in <root>.foo' type=kotlin.Int origin=null
arg1: CONST Int type=kotlin.Unit value=42
arg1: CONST Int type=kotlin.Int value=42
@@ -19,7 +19,7 @@ FILE fqName:<root> fileName:/floatingPointCompareTo.kt
then: CALL 'public final fun EQEQ (arg0: kotlin.Any?, arg1: kotlin.Any?): kotlin.Boolean declared in kotlin.internal.ir' type=kotlin.Boolean origin=EQEQ
arg0: ERROR_CALL 'Unresolved reference: <Inapplicable(INAPPLICABLE): [kotlin/Double.compareTo, kotlin/Double.compareTo, kotlin/Double.compareTo, kotlin/Double.compareTo, kotlin/Double.compareTo, kotlin/Double.compareTo]>#' type=IrErrorType
GET_VAR 'y: kotlin.Any declared in <root>.test2d' type=kotlin.Any origin=null
arg1: CONST Int type=kotlin.Boolean value=0
arg1: CONST Int type=kotlin.Int value=0
BRANCH
if: CONST Boolean type=kotlin.Boolean value=true
then: CONST Boolean type=kotlin.Boolean value=false
@@ -42,7 +42,7 @@ FILE fqName:<root> fileName:/floatingPointCompareTo.kt
then: CALL 'public final fun EQEQ (arg0: kotlin.Any?, arg1: kotlin.Any?): kotlin.Boolean declared in kotlin.internal.ir' type=kotlin.Boolean origin=EQEQ
arg0: ERROR_CALL 'Unresolved reference: <Unresolved name: compareTo>#' type=IrErrorType
GET_VAR 'y: kotlin.Any declared in <root>.test3d' type=kotlin.Any origin=null
arg1: CONST Int type=kotlin.Boolean value=0
arg1: CONST Int type=kotlin.Int value=0
BRANCH
if: CONST Boolean type=kotlin.Boolean value=true
then: CONST Boolean type=kotlin.Boolean value=false
@@ -66,7 +66,7 @@ FILE fqName:<root> fileName:/floatingPointCompareTo.kt
then: CALL 'public final fun EQEQ (arg0: kotlin.Any?, arg1: kotlin.Any?): kotlin.Boolean declared in kotlin.internal.ir' type=kotlin.Boolean origin=EQEQ
arg0: ERROR_CALL 'Unresolved reference: <Inapplicable(INAPPLICABLE): [kotlin/Float.compareTo, kotlin/Float.compareTo, kotlin/Float.compareTo, kotlin/Float.compareTo, kotlin/Float.compareTo, kotlin/Float.compareTo]>#' type=IrErrorType
GET_VAR 'y: kotlin.Any declared in <root>.test2f' type=kotlin.Any origin=null
arg1: CONST Int type=kotlin.Boolean value=0
arg1: CONST Int type=kotlin.Int value=0
BRANCH
if: CONST Boolean type=kotlin.Boolean value=true
then: CONST Boolean type=kotlin.Boolean value=false
@@ -89,7 +89,7 @@ FILE fqName:<root> fileName:/floatingPointCompareTo.kt
then: CALL 'public final fun EQEQ (arg0: kotlin.Any?, arg1: kotlin.Any?): kotlin.Boolean declared in kotlin.internal.ir' type=kotlin.Boolean origin=EQEQ
arg0: ERROR_CALL 'Unresolved reference: <Unresolved name: compareTo>#' type=IrErrorType
GET_VAR 'y: kotlin.Any declared in <root>.test3f' type=kotlin.Any origin=null
arg1: CONST Int type=kotlin.Boolean value=0
arg1: CONST Int type=kotlin.Int value=0
BRANCH
if: CONST Boolean type=kotlin.Boolean value=true
then: CONST Boolean type=kotlin.Boolean value=false
@@ -112,7 +112,7 @@ FILE fqName:<root> fileName:/floatingPointCompareTo.kt
then: CALL 'public final fun EQEQ (arg0: kotlin.Any?, arg1: kotlin.Any?): kotlin.Boolean declared in kotlin.internal.ir' type=kotlin.Boolean origin=EQEQ
arg0: ERROR_CALL 'Unresolved reference: <Unresolved name: compareTo>#' type=IrErrorType
GET_VAR 'y: kotlin.Any declared in <root>.testFD' type=kotlin.Any origin=null
arg1: CONST Int type=kotlin.Boolean value=0
arg1: CONST Int type=kotlin.Int value=0
BRANCH
if: CONST Boolean type=kotlin.Boolean value=true
then: CONST Boolean type=kotlin.Boolean value=false
@@ -135,7 +135,7 @@ FILE fqName:<root> fileName:/floatingPointCompareTo.kt
then: CALL 'public final fun EQEQ (arg0: kotlin.Any?, arg1: kotlin.Any?): kotlin.Boolean declared in kotlin.internal.ir' type=kotlin.Boolean origin=EQEQ
arg0: ERROR_CALL 'Unresolved reference: <Unresolved name: compareTo>#' type=IrErrorType
GET_VAR 'y: kotlin.Any declared in <root>.testDF' type=kotlin.Any origin=null
arg1: CONST Int type=kotlin.Boolean value=0
arg1: CONST Int type=kotlin.Int value=0
BRANCH
if: CONST Boolean type=kotlin.Boolean value=true
then: CONST Boolean type=kotlin.Boolean value=false
@@ -158,7 +158,7 @@ FILE fqName:<root> fileName:/floatingPointCompareTo.kt
then: CALL 'public final fun EQEQ (arg0: kotlin.Any?, arg1: kotlin.Any?): kotlin.Boolean declared in kotlin.internal.ir' type=kotlin.Boolean origin=EQEQ
arg0: ERROR_CALL 'Unresolved reference: <Inapplicable(INAPPLICABLE): [kotlin/Float.compareTo, kotlin/Float.compareTo, kotlin/Float.compareTo, kotlin/Float.compareTo, kotlin/Float.compareTo, kotlin/Float.compareTo]>#' type=IrErrorType
GET_VAR 'x: kotlin.Any declared in <root>.test2fr' type=kotlin.Any origin=null
arg1: CONST Int type=kotlin.Boolean value=0
arg1: CONST Int type=kotlin.Int value=0
BRANCH
if: CONST Boolean type=kotlin.Boolean value=true
then: CONST Boolean type=kotlin.Boolean value=false
@@ -174,7 +174,7 @@ FILE fqName:<root> fileName:/floatingPointCompareTo.kt
then: CALL 'public final fun EQEQ (arg0: kotlin.Any?, arg1: kotlin.Any?): kotlin.Boolean declared in kotlin.internal.ir' type=kotlin.Boolean origin=EQEQ
arg0: ERROR_CALL 'Unresolved reference: <Inapplicable(INAPPLICABLE): [kotlin/Float.compareTo, kotlin/Float.compareTo, kotlin/Float.compareTo, kotlin/Float.compareTo, kotlin/Float.compareTo, kotlin/Float.compareTo]>#' type=IrErrorType
GET_VAR 'x: kotlin.Any declared in <root>.test3fr' type=kotlin.Any origin=null
arg1: CONST Int type=kotlin.Boolean value=0
arg1: CONST Int type=kotlin.Int value=0
BRANCH
if: CONST Boolean type=kotlin.Boolean value=true
then: CONST Boolean type=kotlin.Boolean value=false
@@ -71,7 +71,9 @@ FILE fqName:<root> fileName:/forWithImplicitReceivers.kt
$receiver: VALUE_PARAMETER name:<this> type:<root>.IntCell
BLOCK_BODY
RETURN type=kotlin.Nothing from='public open fun hasNext (): kotlin.Boolean declared in <root>.IReceiver'
ERROR_CALL 'Comparison of arguments with different types: kotlin/Int, kotlin/Boolean' type=kotlin.Boolean
CALL 'public final fun greater (arg0: kotlin.Int, arg1: kotlin.Int): kotlin.Boolean declared in kotlin.internal.ir' type=kotlin.Boolean origin=GT
arg0: CALL 'public final fun <get-value> (): kotlin.Int declared in <root>.IntCell' type=kotlin.Int origin=null
arg1: CONST Int type=kotlin.Int value=0
FUN name:next visibility:public modality:OPEN <> ($this:<root>.IReceiver, $receiver:<root>.IntCell) returnType:kotlin.Int
$this: VALUE_PARAMETER name:<this> type:<root>.IReceiver
$receiver: VALUE_PARAMETER name:<this> type:<root>.IntCell
+9 -9
View File
@@ -98,25 +98,25 @@ FILE fqName:<root> fileName:/when.kt
BRANCH
if: CALL 'public final fun EQEQ (arg0: kotlin.Any?, arg1: kotlin.Any?): kotlin.Boolean declared in kotlin.internal.ir' type=kotlin.Boolean origin=EQEQ
arg0: GET_VAR 'val tmp1_subject: kotlin.Int [val] declared in <root>.testComma' type=kotlin.Int origin=null
arg1: CONST Int type=kotlin.Boolean value=1
arg1: CONST Int type=kotlin.Int value=1
then: CONST Boolean type=kotlin.Boolean value=true
BRANCH
if: CONST Boolean type=kotlin.Boolean value=true
then: CALL 'public final fun EQEQ (arg0: kotlin.Any?, arg1: kotlin.Any?): kotlin.Boolean declared in kotlin.internal.ir' type=kotlin.Boolean origin=EQEQ
arg0: GET_VAR 'val tmp1_subject: kotlin.Int [val] declared in <root>.testComma' type=kotlin.Int origin=null
arg1: CONST Int type=kotlin.Boolean value=2
arg1: CONST Int type=kotlin.Int value=2
then: CONST Boolean type=kotlin.Boolean value=true
BRANCH
if: CONST Boolean type=kotlin.Boolean value=true
then: CALL 'public final fun EQEQ (arg0: kotlin.Any?, arg1: kotlin.Any?): kotlin.Boolean declared in kotlin.internal.ir' type=kotlin.Boolean origin=EQEQ
arg0: GET_VAR 'val tmp1_subject: kotlin.Int [val] declared in <root>.testComma' type=kotlin.Int origin=null
arg1: CONST Int type=kotlin.Boolean value=3
arg1: CONST Int type=kotlin.Int value=3
then: CONST Boolean type=kotlin.Boolean value=true
BRANCH
if: CONST Boolean type=kotlin.Boolean value=true
then: CALL 'public final fun EQEQ (arg0: kotlin.Any?, arg1: kotlin.Any?): kotlin.Boolean declared in kotlin.internal.ir' type=kotlin.Boolean origin=EQEQ
arg0: GET_VAR 'val tmp1_subject: kotlin.Int [val] declared in <root>.testComma' type=kotlin.Int origin=null
arg1: CONST Int type=kotlin.Boolean value=4
arg1: CONST Int type=kotlin.Int value=4
then: CONST String type=kotlin.String value="1234"
BRANCH
if: WHEN type=kotlin.Boolean origin=OROR
@@ -125,32 +125,32 @@ FILE fqName:<root> fileName:/when.kt
BRANCH
if: CALL 'public final fun EQEQ (arg0: kotlin.Any?, arg1: kotlin.Any?): kotlin.Boolean declared in kotlin.internal.ir' type=kotlin.Boolean origin=EQEQ
arg0: GET_VAR 'val tmp1_subject: kotlin.Int [val] declared in <root>.testComma' type=kotlin.Int origin=null
arg1: CONST Int type=kotlin.Boolean value=5
arg1: CONST Int type=kotlin.Int value=5
then: CONST Boolean type=kotlin.Boolean value=true
BRANCH
if: CONST Boolean type=kotlin.Boolean value=true
then: CALL 'public final fun EQEQ (arg0: kotlin.Any?, arg1: kotlin.Any?): kotlin.Boolean declared in kotlin.internal.ir' type=kotlin.Boolean origin=EQEQ
arg0: GET_VAR 'val tmp1_subject: kotlin.Int [val] declared in <root>.testComma' type=kotlin.Int origin=null
arg1: CONST Int type=kotlin.Boolean value=6
arg1: CONST Int type=kotlin.Int value=6
then: CONST Boolean type=kotlin.Boolean value=true
BRANCH
if: CONST Boolean type=kotlin.Boolean value=true
then: CALL 'public final fun EQEQ (arg0: kotlin.Any?, arg1: kotlin.Any?): kotlin.Boolean declared in kotlin.internal.ir' type=kotlin.Boolean origin=EQEQ
arg0: GET_VAR 'val tmp1_subject: kotlin.Int [val] declared in <root>.testComma' type=kotlin.Int origin=null
arg1: CONST Int type=kotlin.Boolean value=7
arg1: CONST Int type=kotlin.Int value=7
then: CONST String type=kotlin.String value="567"
BRANCH
if: WHEN type=kotlin.Boolean origin=OROR
BRANCH
if: CALL 'public final fun EQEQ (arg0: kotlin.Any?, arg1: kotlin.Any?): kotlin.Boolean declared in kotlin.internal.ir' type=kotlin.Boolean origin=EQEQ
arg0: GET_VAR 'val tmp1_subject: kotlin.Int [val] declared in <root>.testComma' type=kotlin.Int origin=null
arg1: CONST Int type=kotlin.Boolean value=8
arg1: CONST Int type=kotlin.Int value=8
then: CONST Boolean type=kotlin.Boolean value=true
BRANCH
if: CONST Boolean type=kotlin.Boolean value=true
then: CALL 'public final fun EQEQ (arg0: kotlin.Any?, arg1: kotlin.Any?): kotlin.Boolean declared in kotlin.internal.ir' type=kotlin.Boolean origin=EQEQ
arg0: GET_VAR 'val tmp1_subject: kotlin.Int [val] declared in <root>.testComma' type=kotlin.Int origin=null
arg1: CONST Int type=kotlin.Boolean value=9
arg1: CONST Int type=kotlin.Int value=9
then: CONST String type=kotlin.String value="89"
BRANCH
if: CONST Boolean type=kotlin.Boolean value=true
@@ -4,10 +4,14 @@ FILE fqName:<root> fileName:/whileDoWhile.kt
VAR name:x type:kotlin.Int [var]
CONST Int type=kotlin.Int value=0
WHILE label=null origin=WHILE_LOOP
condition: ERROR_CALL 'Comparison of arguments with different types: kotlin/Int, kotlin/Unit' type=kotlin.Boolean
condition: CALL 'public final fun less (arg0: kotlin.Int, arg1: kotlin.Int): kotlin.Boolean declared in kotlin.internal.ir' type=kotlin.Boolean origin=LT
arg0: GET_VAR 'var x: kotlin.Int [var] declared in <root>.test' type=kotlin.Int origin=null
arg1: CONST Int type=kotlin.Int value=0
body: BLOCK type=kotlin.Unit origin=null
WHILE label=null origin=WHILE_LOOP
condition: ERROR_CALL 'Comparison of arguments with different types: kotlin/Int, kotlin/Unit' type=kotlin.Boolean
condition: CALL 'public final fun less (arg0: kotlin.Int, arg1: kotlin.Int): kotlin.Boolean declared in kotlin.internal.ir' type=kotlin.Boolean origin=LT
arg0: GET_VAR 'var x: kotlin.Int [var] declared in <root>.test' type=kotlin.Int origin=null
arg1: CONST Int type=kotlin.Int value=5
body: BLOCK type=kotlin.Int origin=null
VAR name:<unary> type:kotlin.Int [val]
GET_VAR 'var x: kotlin.Int [var] declared in <root>.test' type=kotlin.Int origin=null
@@ -16,7 +20,9 @@ FILE fqName:<root> fileName:/whileDoWhile.kt
$this: GET_VAR 'val <unary>: kotlin.Int [val] declared in <root>.test' type=kotlin.Int origin=null
GET_VAR 'val <unary>: kotlin.Int [val] declared in <root>.test' type=kotlin.Int origin=null
WHILE label=null origin=WHILE_LOOP
condition: ERROR_CALL 'Comparison of arguments with different types: kotlin/Int, kotlin/Unit' type=kotlin.Boolean
condition: CALL 'public final fun less (arg0: kotlin.Int, arg1: kotlin.Int): kotlin.Boolean declared in kotlin.internal.ir' type=kotlin.Boolean origin=LT
arg0: GET_VAR 'var x: kotlin.Int [var] declared in <root>.test' type=kotlin.Int origin=null
arg1: CONST Int type=kotlin.Int value=10
body: BLOCK type=kotlin.Int origin=null
VAR name:<unary> type:kotlin.Int [val]
GET_VAR 'var x: kotlin.Int [var] declared in <root>.test' type=kotlin.Int origin=null
@@ -26,7 +32,9 @@ FILE fqName:<root> fileName:/whileDoWhile.kt
GET_VAR 'val <unary>: kotlin.Int [val] declared in <root>.test' type=kotlin.Int origin=null
DO_WHILE label=null origin=DO_WHILE_LOOP
body: BLOCK type=kotlin.Unit origin=null
condition: ERROR_CALL 'Comparison of arguments with different types: kotlin/Int, kotlin/Unit' type=kotlin.Boolean
condition: CALL 'public final fun less (arg0: kotlin.Int, arg1: kotlin.Int): kotlin.Boolean declared in kotlin.internal.ir' type=kotlin.Boolean origin=LT
arg0: GET_VAR 'var x: kotlin.Int [var] declared in <root>.test' type=kotlin.Int origin=null
arg1: CONST Int type=kotlin.Int value=0
DO_WHILE label=null origin=DO_WHILE_LOOP
body: BLOCK type=kotlin.Int origin=null
VAR name:<unary> type:kotlin.Int [val]
@@ -35,7 +43,9 @@ FILE fqName:<root> fileName:/whileDoWhile.kt
CALL 'public final fun inc (): kotlin.Int declared in kotlin.Int' type=kotlin.Int origin=null
$this: GET_VAR 'val <unary>: kotlin.Int [val] declared in <root>.test' type=kotlin.Int origin=null
GET_VAR 'val <unary>: kotlin.Int [val] declared in <root>.test' type=kotlin.Int origin=null
condition: ERROR_CALL 'Comparison of arguments with different types: kotlin/Int, kotlin/Unit' type=kotlin.Boolean
condition: CALL 'public final fun less (arg0: kotlin.Int, arg1: kotlin.Int): kotlin.Boolean declared in kotlin.internal.ir' type=kotlin.Boolean origin=LT
arg0: GET_VAR 'var x: kotlin.Int [var] declared in <root>.test' type=kotlin.Int origin=null
arg1: CONST Int type=kotlin.Int value=15
DO_WHILE label=null origin=DO_WHILE_LOOP
body: BLOCK type=kotlin.Int origin=null
VAR name:<unary> type:kotlin.Int [val]
@@ -44,7 +54,9 @@ FILE fqName:<root> fileName:/whileDoWhile.kt
CALL 'public final fun inc (): kotlin.Int declared in kotlin.Int' type=kotlin.Int origin=null
$this: GET_VAR 'val <unary>: kotlin.Int [val] declared in <root>.test' type=kotlin.Int origin=null
GET_VAR 'val <unary>: kotlin.Int [val] declared in <root>.test' type=kotlin.Int origin=null
condition: ERROR_CALL 'Comparison of arguments with different types: kotlin/Int, kotlin/Unit' type=kotlin.Boolean
condition: CALL 'public final fun less (arg0: kotlin.Int, arg1: kotlin.Int): kotlin.Boolean declared in kotlin.internal.ir' type=kotlin.Boolean origin=LT
arg0: GET_VAR 'var x: kotlin.Int [var] declared in <root>.test' type=kotlin.Int origin=null
arg1: CONST Int type=kotlin.Int value=20
FUN name:testSmartcastInCondition visibility:public modality:FINAL <> () returnType:kotlin.Unit
BLOCK_BODY
VAR name:a type:kotlin.Any? [val]