From 672c172c99d5e098d1d9b9330a7939d259f461e6 Mon Sep 17 00:00:00 2001 From: Simon Ogorodnik Date: Wed, 15 May 2019 16:02:47 +0300 Subject: [PATCH] [FIR] Make result type after safe-call nullable (for nullable receiver) --- .../resolve/transformers/FirBodyResolveTransformer.kt | 10 +++++++++- .../ir/irText/expressions/dotQualified.fir.txt | 7 +++---- .../testData/ir/irText/expressions/kt30020.fir.txt | 8 ++++---- .../expressions/safeCallWithIncrementDecrement.fir.txt | 6 +++--- .../testData/ir/irText/expressions/safeCalls.fir.txt | 6 +++--- 5 files changed, 22 insertions(+), 15 deletions(-) diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/FirBodyResolveTransformer.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/FirBodyResolveTransformer.kt index 8e408045831..6e636d43ce2 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/FirBodyResolveTransformer.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/FirBodyResolveTransformer.kt @@ -202,7 +202,15 @@ open class FirBodyResolveTransformer(val session: FirSession, val implicitTypeOn is FirResolvedCallableReference -> { val symbol = newCallee.coneSymbol if (symbol is ConeCallableSymbol) { - jump.tryCalculateReturnType(symbol.firUnsafe()) + val returnType = jump.tryCalculateReturnType(symbol.firUnsafe()) + if (access.safe && access.explicitReceiver!!.resultType.coneTypeUnsafe().isNullable) { + returnType.withReplacedConeType( + session, + returnType.coneTypeUnsafe().withNullability(ConeNullability.NULLABLE) + ) + } else { + returnType + } } else if (symbol is ConeClassifierSymbol) { val firUnsafe = symbol.firUnsafe() // TODO: unhack diff --git a/compiler/testData/ir/irText/expressions/dotQualified.fir.txt b/compiler/testData/ir/irText/expressions/dotQualified.fir.txt index bfafe09d080..c1fe8192aaa 100644 --- a/compiler/testData/ir/irText/expressions/dotQualified.fir.txt +++ b/compiler/testData/ir/irText/expressions/dotQualified.fir.txt @@ -4,9 +4,8 @@ FILE fqName: fileName:/dotQualified.kt BLOCK_BODY RETURN type=kotlin.Nothing from='public final fun length (s: kotlin.String): kotlin.Int declared in ' ERROR_CALL 'No getter found for R|kotlin/String.length|' type=kotlin.Int - FUN name:lengthN visibility:public modality:FINAL <> (s:kotlin.String?) returnType:kotlin.Int + FUN name:lengthN visibility:public modality:FINAL <> (s:kotlin.String?) returnType:kotlin.Int? VALUE_PARAMETER name:s index:0 type:kotlin.String? BLOCK_BODY - RETURN type=kotlin.Nothing from='public final fun lengthN (s: kotlin.String?): kotlin.Int declared in ' - ERROR_CALL 'No getter found for R|kotlin/String.length|' type=kotlin.Int - + RETURN type=kotlin.Nothing from='public final fun lengthN (s: kotlin.String?): kotlin.Int? declared in ' + ERROR_CALL 'No getter found for R|kotlin/String.length|' type=kotlin.Int? diff --git a/compiler/testData/ir/irText/expressions/kt30020.fir.txt b/compiler/testData/ir/irText/expressions/kt30020.fir.txt index 685763a3d8b..6086cb12a8f 100644 --- a/compiler/testData/ir/irText/expressions/kt30020.fir.txt +++ b/compiler/testData/ir/irText/expressions/kt30020.fir.txt @@ -41,19 +41,19 @@ FILE fqName: fileName:/kt30020.kt ERROR_CALL 'Unresolved reference: R|/|' type=IrErrorType VAR name: type:kotlin.collections.MutableList [val] BLOCK type=kotlin.collections.MutableList origin=EXCLEXCL - VAR name: type:kotlin.collections.MutableList [val] - CALL 'public abstract fun (): kotlin.collections.MutableList declared in .X' type=kotlin.collections.MutableList origin=null + VAR name: type:kotlin.collections.MutableList? [val] + CALL 'public abstract fun (): kotlin.collections.MutableList declared in .X' type=kotlin.collections.MutableList? origin=null $this: GET_VAR 'nx: .X? declared in .test' type=.X? origin=null WHEN type=kotlin.collections.MutableList origin=EXCLEXCL 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 : kotlin.collections.MutableList [val] declared in .test' type=kotlin.collections.MutableList origin=null + arg0: GET_VAR 'val : kotlin.collections.MutableList? [val] declared in .test' type=kotlin.collections.MutableList? origin=null arg1: CONST Null type=kotlin.Nothing? value=null then: THROW type=kotlin.Nothing CONSTRUCTOR_CALL 'public constructor () declared in kotlin.KotlinNullPointerException' type=kotlin.KotlinNullPointerException origin=null BRANCH if: CONST Boolean type=kotlin.Boolean value=true - then: GET_VAR 'val : kotlin.collections.MutableList [val] declared in .test' type=kotlin.collections.MutableList origin=null + then: GET_VAR 'val : kotlin.collections.MutableList? [val] declared in .test' type=kotlin.collections.MutableList? origin=null ERROR_CALL 'Unresolved reference: R|/|' type=IrErrorType VAR name: type:kotlin.collections.MutableList [val] BLOCK type=kotlin.collections.MutableList origin=EXCLEXCL diff --git a/compiler/testData/ir/irText/expressions/safeCallWithIncrementDecrement.fir.txt b/compiler/testData/ir/irText/expressions/safeCallWithIncrementDecrement.fir.txt index e2f47582a93..d3ec2beb9f8 100644 --- a/compiler/testData/ir/irText/expressions/safeCallWithIncrementDecrement.fir.txt +++ b/compiler/testData/ir/irText/expressions/safeCallWithIncrementDecrement.fir.txt @@ -45,10 +45,10 @@ FILE fqName:test fileName:/safeCallWithIncrementDecrement.kt FUN name:testProperty visibility:public modality:FINAL <> (nc:test.C?) returnType:kotlin.Unit VALUE_PARAMETER name:nc index:0 type:test.C? BLOCK_BODY - VAR name: type:kotlin.Int [val] - CALL 'public final fun (): kotlin.Int declared in test' type=kotlin.Int origin=null + VAR name: type:kotlin.Int? [val] + CALL 'public final fun (): kotlin.Int declared in test' type=kotlin.Int? origin=null ERROR_CALL 'Unresolved reference: R|test/p|' type=IrErrorType - GET_VAR 'val : kotlin.Int [val] declared in test.testProperty' type=kotlin.Int origin=null + GET_VAR 'val : kotlin.Int? [val] declared in test.testProperty' type=kotlin.Int? origin=null FUN name:testArrayAccess visibility:public modality:FINAL <> (nc:test.C?) returnType:kotlin.Unit VALUE_PARAMETER name:nc index:0 type:test.C? BLOCK_BODY diff --git a/compiler/testData/ir/irText/expressions/safeCalls.fir.txt b/compiler/testData/ir/irText/expressions/safeCalls.fir.txt index 980942329f4..d102a83160c 100644 --- a/compiler/testData/ir/irText/expressions/safeCalls.fir.txt +++ b/compiler/testData/ir/irText/expressions/safeCalls.fir.txt @@ -58,11 +58,11 @@ FILE fqName: fileName:/safeCalls.kt overridden: public open fun toString (): kotlin.String declared in kotlin.Any $this: VALUE_PARAMETER name: type:kotlin.Any - FUN name:test1 visibility:public modality:FINAL <> (x:kotlin.String?) returnType:kotlin.Int + FUN name:test1 visibility:public modality:FINAL <> (x:kotlin.String?) returnType:kotlin.Int? VALUE_PARAMETER name:x index:0 type:kotlin.String? BLOCK_BODY - RETURN type=kotlin.Nothing from='public final fun test1 (x: kotlin.String?): kotlin.Int declared in ' - ERROR_CALL 'No getter found for R|kotlin/String.length|' type=kotlin.Int + RETURN type=kotlin.Nothing from='public final fun test1 (x: kotlin.String?): kotlin.Int? declared in ' + ERROR_CALL 'No getter found for R|kotlin/String.length|' type=kotlin.Int? FUN name:test2 visibility:public modality:FINAL <> (x:kotlin.String?) returnType:IrErrorType VALUE_PARAMETER name:x index:0 type:kotlin.String? BLOCK_BODY