diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/ExpressionCodegen.java b/compiler/backend/src/org/jetbrains/kotlin/codegen/ExpressionCodegen.java index c710ecaed32..9751f96870f 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/ExpressionCodegen.java +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/ExpressionCodegen.java @@ -423,6 +423,11 @@ public class ExpressionCodegen extends KtVisitor impleme return CodegenUtilKt.asmType(expression, typeMapper, bindingContext); } + @Nullable + public KotlinType kotlinType(@Nullable KtExpression expression) { + return CodegenUtilKt.kotlinType(expression, bindingContext); + } + @Override public StackValue visitParenthesizedExpression(@NotNull KtParenthesizedExpression expression, StackValue receiver) { return genQualified(receiver, expression.getExpression()); @@ -2929,10 +2934,13 @@ public class ExpressionCodegen extends KtVisitor impleme KtExpression selector = expression.getSelectorExpression(); Type receiverType = expressionType(receiver); + KotlinType receiverKotlinType = kotlinType(receiver); StackValue receiverValue = generateExpressionWithNullFallback(receiver, ifNull); //Do not optimize for primitives cause in case of safe call extension receiver should be generated before dispatch one - StackValue newReceiver = new StackValue.SafeCall(receiverType, receiverValue, isPrimitive(receiverType) ? null : ifNull); + StackValue newReceiver = new StackValue.SafeCall( + receiverType, receiverKotlinType, receiverValue, isPrimitive(receiverType) ? null : ifNull + ); return genQualified(newReceiver, selector); } diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/StackValue.java b/compiler/backend/src/org/jetbrains/kotlin/codegen/StackValue.java index df6981fb415..5c49cb01e63 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/StackValue.java +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/StackValue.java @@ -1925,8 +1925,8 @@ public abstract class StackValue { private final StackValue receiver; @Nullable private final Label ifNull; - public SafeCall(@NotNull Type type, @NotNull StackValue value, @Nullable Label ifNull) { - super(type); + public SafeCall(@NotNull Type type, @Nullable KotlinType kotlinType, @NotNull StackValue value, @Nullable Label ifNull) { + super(type, kotlinType); this.type = type; this.receiver = value; this.ifNull = ifNull; diff --git a/compiler/testData/codegen/bytecodeText/inlineClasses/unboxInlineClassAfterSafeCall.kt b/compiler/testData/codegen/bytecodeText/inlineClasses/unboxInlineClassAfterSafeCall.kt new file mode 100644 index 00000000000..cef708b126b --- /dev/null +++ b/compiler/testData/codegen/bytecodeText/inlineClasses/unboxInlineClassAfterSafeCall.kt @@ -0,0 +1,20 @@ +// !LANGUAGE: +InlineClasses + +inline class Foo(val x: Int) { + fun member() {} +} + +fun Foo.extension() {} +fun T.genericExtension() {} + +fun test(f: Foo?) { + f?.member() // unbox + f?.extension() // unbox + f?.genericExtension() +} + +// 0 INVOKESTATIC Foo\$Erased.box +// 2 INVOKEVIRTUAL Foo.unbox + +// 0 valueOf +// 0 intValue \ No newline at end of file