diff --git a/compiler/ir/ir.interpreter/src/org/jetbrains/kotlin/ir/interpreter/Utils.kt b/compiler/ir/ir.interpreter/src/org/jetbrains/kotlin/ir/interpreter/Utils.kt index d3c27047f1a..90a5457e8ba 100644 --- a/compiler/ir/ir.interpreter/src/org/jetbrains/kotlin/ir/interpreter/Utils.kt +++ b/compiler/ir/ir.interpreter/src/org/jetbrains/kotlin/ir/interpreter/Utils.kt @@ -297,7 +297,8 @@ internal fun IrClass.getSingleAbstractMethod(): IrFunction { return declarations.filterIsInstance().single { it.modality == Modality.ABSTRACT } } -internal fun IrGetValue.isAccessToNotNullableObject(): Boolean { +internal fun IrExpression?.isAccessToNotNullableObject(): Boolean { + if (this !is IrGetValue) return false val owner = this.symbol.owner val expectedClass = this.type.classOrNull?.owner if (expectedClass == null || !expectedClass.isObject || this.type.isNullable()) return false diff --git a/compiler/ir/ir.interpreter/src/org/jetbrains/kotlin/ir/interpreter/checker/IrCompileTimeChecker.kt b/compiler/ir/ir.interpreter/src/org/jetbrains/kotlin/ir/interpreter/checker/IrCompileTimeChecker.kt index 313c902305b..f35af982c33 100644 --- a/compiler/ir/ir.interpreter/src/org/jetbrains/kotlin/ir/interpreter/checker/IrCompileTimeChecker.kt +++ b/compiler/ir/ir.interpreter/src/org/jetbrains/kotlin/ir/interpreter/checker/IrCompileTimeChecker.kt @@ -66,6 +66,10 @@ class IrCompileTimeChecker( return this.asVisited { !mode.mustCheckBodyOf(this) || (this.body?.accept(this@IrCompileTimeChecker, null) ?: true) } } + private fun IrCall.isGetterToConstVal(): Boolean { + return symbol.owner.correspondingPropertySymbol?.owner?.isConst == true + } + override fun visitCall(expression: IrCall, data: Nothing?): Boolean { val owner = expression.symbol.owner if (!mode.canEvaluateFunction(owner, expression)) return false @@ -78,6 +82,10 @@ class IrCompileTimeChecker( } return expression.saveContext { + if (expression.dispatchReceiver.isAccessToNotNullableObject()) { + return@saveContext expression.isGetterToConstVal() + } + val dispatchReceiverComputable = expression.dispatchReceiver?.accept(this, null) ?: true val extensionReceiverComputable = expression.extensionReceiver?.accept(this, null) ?: true if (!visitValueArguments(expression, null)) return@saveContext false @@ -177,7 +185,7 @@ class IrCompileTimeChecker( } override fun visitGetValue(expression: IrGetValue, data: Nothing?): Boolean { - return visitedStack.contains(expression.symbol.owner.parent) || expression.isAccessToNotNullableObject() + return visitedStack.contains(expression.symbol.owner.parent) } override fun visitSetValue(expression: IrSetValue, data: Nothing?): Boolean { @@ -199,7 +207,8 @@ class IrCompileTimeChecker( isJavaStaticWithPrimitiveOrString() -> owner.initializer?.accept(this, data) == true expression.receiver == null -> property?.isConst == true && owner.initializer?.accept(this, null) == true owner.origin == IrDeclarationOrigin.PROPERTY_BACKING_FIELD && property?.isConst == true -> { - val receiverComputable = expression.receiver?.accept(this, null) ?: true + val receiverComputable = (expression.receiver?.accept(this, null) ?: true) + || expression.isAccessToNotNullableObject() val initializerComputable = owner.initializer?.accept(this, null) ?: false receiverComputable && initializerComputable } diff --git a/compiler/testData/codegen/box/involvesIrInterpreter/kt56215.kt b/compiler/testData/codegen/box/involvesIrInterpreter/kt56215.kt index 6fbfacbec0c..3eeb479d76e 100644 --- a/compiler/testData/codegen/box/involvesIrInterpreter/kt56215.kt +++ b/compiler/testData/codegen/box/involvesIrInterpreter/kt56215.kt @@ -7,8 +7,8 @@ fun ObjectWithExtension?.nullableExtensionFun(): String = "Not null" fun ObjectWithExtension.extensionFun(): String = - if(this == null) - "Null" // unreachable branch, will be optimized by interpreter + if(this == null) + "Null" else "Not null" diff --git a/compiler/testData/codegen/box/involvesIrInterpreter/thisPlusString.kt b/compiler/testData/codegen/box/involvesIrInterpreter/thisPlusString.kt index f8c73481519..0080e5674d9 100644 --- a/compiler/testData/codegen/box/involvesIrInterpreter/thisPlusString.kt +++ b/compiler/testData/codegen/box/involvesIrInterpreter/thisPlusString.kt @@ -6,7 +6,7 @@ object Test { fun foo(): String = "foo " + this - fun bar(): String = "bar $this" + fun bar(): String = "bar $this" fun baz(): String = "baz " + this.toString() }