KT-37986 Force boxing of inline class returned from function reference
KT-37998 Provide KotlinType for safe call
This commit is contained in:
@@ -1033,13 +1033,19 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
|
||||
);
|
||||
|
||||
ClosureCodegen coroutineCodegen = CoroutineCodegenForLambda.create(this, descriptor, declaration, cv);
|
||||
ClosureContext closureContext = descriptor.isSuspend() ? this.context.intoCoroutineClosure(
|
||||
CoroutineCodegenUtilKt.getOrCreateJvmSuspendFunctionView(descriptor, state),
|
||||
descriptor, this, state.getTypeMapper()
|
||||
) : this.context.intoClosure(descriptor, this, typeMapper);
|
||||
ClosureCodegen closureCodegen = coroutineCodegen != null ? coroutineCodegen : new ClosureCodegen(
|
||||
state, declaration, samType, closureContext, functionReferenceCall, strategy, parentCodegen, cv
|
||||
);
|
||||
ClosureContext closureContext =
|
||||
descriptor.isSuspend()
|
||||
? this.context.intoCoroutineClosure(
|
||||
CoroutineCodegenUtilKt.getOrCreateJvmSuspendFunctionView(descriptor, state),
|
||||
descriptor, this, state.getTypeMapper()
|
||||
)
|
||||
: this.context.intoClosure(descriptor, this, typeMapper);
|
||||
ClosureCodegen closureCodegen =
|
||||
coroutineCodegen != null
|
||||
? coroutineCodegen
|
||||
: new ClosureCodegen(
|
||||
state, declaration, samType, closureContext, functionReferenceCall, strategy, parentCodegen, cv
|
||||
);
|
||||
|
||||
closureCodegen.generate();
|
||||
|
||||
@@ -3399,7 +3405,7 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
|
||||
StackValue result;
|
||||
|
||||
if (!isPrimitive(expressionType(expression.getReceiverExpression()))) {
|
||||
result = new StackValue.SafeFallback(type, ifnull, newReceiver);
|
||||
result = new StackValue.SafeFallback(type, kotlinType, ifnull, newReceiver);
|
||||
} else {
|
||||
result = newReceiver;
|
||||
}
|
||||
@@ -4363,7 +4369,6 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
|
||||
|
||||
return StackValue.none();
|
||||
}
|
||||
|
||||
@Override
|
||||
public StackValue visitDestructuringDeclaration(@NotNull KtDestructuringDeclaration multiDeclaration, StackValue receiver) {
|
||||
return initializeDestructuringDeclaration(multiDeclaration, false);
|
||||
|
||||
@@ -2308,8 +2308,8 @@ public abstract class StackValue {
|
||||
|
||||
@Nullable private final Label ifNull;
|
||||
|
||||
public SafeFallback(@NotNull Type type, @Nullable Label ifNull, StackValue receiver) {
|
||||
super(type, null, false, false, receiver, true);
|
||||
public SafeFallback(@NotNull Type type, @Nullable KotlinType kotlinType, @Nullable Label ifNull, StackValue receiver) {
|
||||
super(type, kotlinType, false, false, receiver, true);
|
||||
this.ifNull = ifNull;
|
||||
}
|
||||
|
||||
|
||||
@@ -26,6 +26,7 @@ import org.jetbrains.kotlin.config.LanguageFeature
|
||||
import org.jetbrains.kotlin.config.LanguageVersionSettings
|
||||
import org.jetbrains.kotlin.config.LanguageVersionSettingsImpl
|
||||
import org.jetbrains.kotlin.descriptors.*
|
||||
import org.jetbrains.kotlin.descriptors.impl.AnonymousFunctionDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.impl.LocalVariableAccessorDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.impl.LocalVariableDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.impl.TypeAliasConstructorDescriptor
|
||||
@@ -41,10 +42,7 @@ import org.jetbrains.kotlin.load.java.lazy.descriptors.LazyJavaPackageFragment
|
||||
import org.jetbrains.kotlin.load.kotlin.*
|
||||
import org.jetbrains.kotlin.load.kotlin.incremental.IncrementalPackageFragmentProvider.IncrementalMultifileClassPackageFragment
|
||||
import org.jetbrains.kotlin.name.*
|
||||
import org.jetbrains.kotlin.psi.KtBinaryExpressionWithTypeRHS
|
||||
import org.jetbrains.kotlin.psi.KtExpression
|
||||
import org.jetbrains.kotlin.psi.KtFunctionLiteral
|
||||
import org.jetbrains.kotlin.psi.KtLambdaExpression
|
||||
import org.jetbrains.kotlin.psi.*
|
||||
import org.jetbrains.kotlin.psi.psiUtil.getOutermostParenthesizerOrThis
|
||||
import org.jetbrains.kotlin.psi.psiUtil.getQualifiedExpressionForSelector
|
||||
import org.jetbrains.kotlin.resolve.*
|
||||
@@ -66,6 +64,7 @@ import org.jetbrains.kotlin.resolve.jvm.annotations.hasJvmDefaultAnnotation
|
||||
import org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodGenericSignature
|
||||
import org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodParameterKind
|
||||
import org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodSignature
|
||||
import org.jetbrains.kotlin.resolve.source.KotlinSourceElement
|
||||
import org.jetbrains.kotlin.serialization.deserialization.descriptors.DescriptorWithContainerSource
|
||||
import org.jetbrains.kotlin.serialization.deserialization.descriptors.DeserializedCallableMemberDescriptor
|
||||
import org.jetbrains.kotlin.types.*
|
||||
@@ -936,7 +935,20 @@ class KotlinTypeMapper @JvmOverloads constructor(
|
||||
private fun forceBoxedReturnType(descriptor: FunctionDescriptor): Boolean {
|
||||
if (isBoxMethodForInlineClass(descriptor)) return true
|
||||
|
||||
return isJvmPrimitiveOrInlineClass(descriptor.returnType!!) &&
|
||||
val returnType = descriptor.returnType!!
|
||||
|
||||
// Crude hack to determine whether it is an AnonymousFunctionDescriptor created for callable reference.
|
||||
// Ideally, we should force return type boxing for all anonymous functions returning an inline class value
|
||||
// (so that the result is boxed properly, since technically it is a covariant override of a corresponding generic 'invoke').
|
||||
// But, unfortunately, we can't do so right now, because it'd break binary compatibility for lambdas returning 'Result'.
|
||||
if (descriptor is AnonymousFunctionDescriptor) {
|
||||
val source = descriptor.source
|
||||
if (source is KotlinSourceElement && source.psi is KtCallableReferenceExpression && returnType.isInlineClassType()) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
return isJvmPrimitiveOrInlineClass(returnType) &&
|
||||
getAllOverriddenDescriptors(descriptor).any { !isJvmPrimitiveOrInlineClass(it.returnType!!) }
|
||||
}
|
||||
|
||||
|
||||
Generated
+10
@@ -12534,6 +12534,11 @@ public class FirBlackBoxCodegenTestGenerated extends AbstractFirBlackBoxCodegenT
|
||||
runTest("compiler/testData/codegen/box/inlineClasses/kt34268.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("kt37998.kt")
|
||||
public void testKt37998() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/inlineClasses/kt37998.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("mangledDefaultParameterFunction.kt")
|
||||
public void testMangledDefaultParameterFunction() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/inlineClasses/mangledDefaultParameterFunction.kt");
|
||||
@@ -12898,6 +12903,11 @@ public class FirBlackBoxCodegenTestGenerated extends AbstractFirBlackBoxCodegenT
|
||||
public void testInlineClassTypeTopLevelVar() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/inlineClasses/callableReferences/inlineClassTypeTopLevelVar.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("kt37986.kt")
|
||||
public void testKt37986() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/inlineClasses/callableReferences/kt37986.kt");
|
||||
}
|
||||
}
|
||||
|
||||
@TestMetadata("compiler/testData/codegen/box/inlineClasses/contextsAndAccessors")
|
||||
|
||||
@@ -0,0 +1,25 @@
|
||||
// IGNORE_BACKEND: JVM_IR
|
||||
// IGNORE_BACKEND_FIR: JVM_IR
|
||||
|
||||
inline class R(val x: Any)
|
||||
|
||||
fun useR(r: R) {
|
||||
if (r.x as String != "OK") throw AssertionError("$r")
|
||||
}
|
||||
|
||||
fun useR0(fn: () -> R) {
|
||||
useR(fn())
|
||||
}
|
||||
|
||||
fun useR1(r: R, fn: (R) -> R) {
|
||||
useR(fn(r))
|
||||
}
|
||||
|
||||
fun fnWithDefaultR(r: R = R("OK")) = r
|
||||
|
||||
fun box(): String {
|
||||
useR0(::fnWithDefaultR)
|
||||
useR1(R("OK"), ::fnWithDefaultR)
|
||||
|
||||
return "OK"
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
inline class Z(val x: Int)
|
||||
|
||||
class A {
|
||||
fun foo() = Z(42)
|
||||
}
|
||||
|
||||
fun test(a: A?) = a?.foo()!!
|
||||
|
||||
fun box(): String {
|
||||
val t = test(A())
|
||||
if (t.x != 42) throw AssertionError("$t")
|
||||
return "OK"
|
||||
}
|
||||
+10
@@ -13724,6 +13724,11 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest {
|
||||
runTest("compiler/testData/codegen/box/inlineClasses/kt34268.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("kt37998.kt")
|
||||
public void testKt37998() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/inlineClasses/kt37998.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("mangledDefaultParameterFunction.kt")
|
||||
public void testMangledDefaultParameterFunction() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/inlineClasses/mangledDefaultParameterFunction.kt");
|
||||
@@ -14088,6 +14093,11 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest {
|
||||
public void testInlineClassTypeTopLevelVar() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/inlineClasses/callableReferences/inlineClassTypeTopLevelVar.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("kt37986.kt")
|
||||
public void testKt37986() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/inlineClasses/callableReferences/kt37986.kt");
|
||||
}
|
||||
}
|
||||
|
||||
@TestMetadata("compiler/testData/codegen/box/inlineClasses/contextsAndAccessors")
|
||||
|
||||
+10
@@ -13729,6 +13729,11 @@ public class LightAnalysisModeTestGenerated extends AbstractLightAnalysisModeTes
|
||||
runTest("compiler/testData/codegen/box/inlineClasses/kt34268.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("kt37998.kt")
|
||||
public void testKt37998() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/inlineClasses/kt37998.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("mangledDefaultParameterFunction.kt")
|
||||
public void testMangledDefaultParameterFunction() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/inlineClasses/mangledDefaultParameterFunction.kt");
|
||||
@@ -14088,6 +14093,11 @@ public class LightAnalysisModeTestGenerated extends AbstractLightAnalysisModeTes
|
||||
public void testInlineClassTypeTopLevelVar() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/inlineClasses/callableReferences/inlineClassTypeTopLevelVar.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("kt37986.kt")
|
||||
public void testKt37986() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/inlineClasses/callableReferences/kt37986.kt");
|
||||
}
|
||||
}
|
||||
|
||||
@TestMetadata("compiler/testData/codegen/box/inlineClasses/contextsAndAccessors")
|
||||
|
||||
+10
@@ -12534,6 +12534,11 @@ public class IrBlackBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTes
|
||||
runTest("compiler/testData/codegen/box/inlineClasses/kt34268.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("kt37998.kt")
|
||||
public void testKt37998() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/inlineClasses/kt37998.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("mangledDefaultParameterFunction.kt")
|
||||
public void testMangledDefaultParameterFunction() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/inlineClasses/mangledDefaultParameterFunction.kt");
|
||||
@@ -12898,6 +12903,11 @@ public class IrBlackBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTes
|
||||
public void testInlineClassTypeTopLevelVar() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/inlineClasses/callableReferences/inlineClassTypeTopLevelVar.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("kt37986.kt")
|
||||
public void testKt37986() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/inlineClasses/callableReferences/kt37986.kt");
|
||||
}
|
||||
}
|
||||
|
||||
@TestMetadata("compiler/testData/codegen/box/inlineClasses/contextsAndAccessors")
|
||||
|
||||
Generated
+10
@@ -10764,6 +10764,11 @@ public class IrJsCodegenBoxTestGenerated extends AbstractIrJsCodegenBoxTest {
|
||||
runTest("compiler/testData/codegen/box/inlineClasses/kt34268.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("kt37998.kt")
|
||||
public void testKt37998() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/inlineClasses/kt37998.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("mangledDefaultParameterFunction.kt")
|
||||
public void testMangledDefaultParameterFunction() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/inlineClasses/mangledDefaultParameterFunction.kt");
|
||||
@@ -11113,6 +11118,11 @@ public class IrJsCodegenBoxTestGenerated extends AbstractIrJsCodegenBoxTest {
|
||||
public void testInlineClassTypeTopLevelVar() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/inlineClasses/callableReferences/inlineClassTypeTopLevelVar.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("kt37986.kt")
|
||||
public void testKt37986() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/inlineClasses/callableReferences/kt37986.kt");
|
||||
}
|
||||
}
|
||||
|
||||
@TestMetadata("compiler/testData/codegen/box/inlineClasses/contextsAndAccessors")
|
||||
|
||||
+10
@@ -10829,6 +10829,11 @@ public class JsCodegenBoxTestGenerated extends AbstractJsCodegenBoxTest {
|
||||
runTest("compiler/testData/codegen/box/inlineClasses/kt34268.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("kt37998.kt")
|
||||
public void testKt37998() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/inlineClasses/kt37998.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("mangledDefaultParameterFunction.kt")
|
||||
public void testMangledDefaultParameterFunction() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/inlineClasses/mangledDefaultParameterFunction.kt");
|
||||
@@ -11178,6 +11183,11 @@ public class JsCodegenBoxTestGenerated extends AbstractJsCodegenBoxTest {
|
||||
public void testInlineClassTypeTopLevelVar() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/inlineClasses/callableReferences/inlineClassTypeTopLevelVar.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("kt37986.kt")
|
||||
public void testKt37986() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/inlineClasses/callableReferences/kt37986.kt");
|
||||
}
|
||||
}
|
||||
|
||||
@TestMetadata("compiler/testData/codegen/box/inlineClasses/contextsAndAccessors")
|
||||
|
||||
Reference in New Issue
Block a user