JVM_IR: fix a bug when isInlineParameter is applied to default stubs
If an inline parameter has a default value, its type is nullable. There's already code to handle this in `IrInlineCodegen`, but it really should be in `isInlineParameter` instead, otherwise e.g. SyntheticAccessorLowering fails.
This commit is contained in:
+1
-2
@@ -82,8 +82,7 @@ class IrInlineCodegen(
|
|||||||
super.genValueAndPut(irValueParameter, argumentExpression, parameterType, codegen, blockInfo)
|
super.genValueAndPut(irValueParameter, argumentExpression, parameterType, codegen, blockInfo)
|
||||||
}
|
}
|
||||||
|
|
||||||
// after transformation inlinable lambda parameter with default value would have nullable type: check default value type first
|
val isInlineParameter = irValueParameter.isInlineParameter()
|
||||||
val isInlineParameter = irValueParameter.isInlineParameter(irValueParameter.defaultValue?.expression?.type ?: irValueParameter.type)
|
|
||||||
if (isInlineParameter && isInlineIrExpression(argumentExpression)) {
|
if (isInlineParameter && isInlineIrExpression(argumentExpression)) {
|
||||||
val irReference: IrFunctionReference =
|
val irReference: IrFunctionReference =
|
||||||
(argumentExpression as IrBlock).statements.filterIsInstance<IrFunctionReference>().single()
|
(argumentExpression as IrBlock).statements.filterIsInstance<IrFunctionReference>().single()
|
||||||
|
|||||||
+1
-3
@@ -20,9 +20,7 @@ fun extractDefaultLambdaOffsetAndDescriptor(
|
|||||||
|
|
||||||
val valueParameterOffset = if (irFunction.extensionReceiverParameter != null) 1 else 0
|
val valueParameterOffset = if (irFunction.extensionReceiverParameter != null) 1 else 0
|
||||||
|
|
||||||
return irFunction.valueParameters.filter {
|
return irFunction.valueParameters.filter { it.defaultValue != null && it.isInlineParameter() }.associateBy {
|
||||||
it.defaultValue != null && it.isInlineParameter(it.defaultValue!!.expression.type)
|
|
||||||
}.associateBy {
|
|
||||||
parameterOffsets[valueParameterOffset + it.index]
|
parameterOffsets[valueParameterOffset + it.index]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -168,8 +168,12 @@ fun IrFunction.hasPlatformDependent(): Boolean = propertyIfAccessor.hasAnnotatio
|
|||||||
fun IrFunction.getJvmVisibilityOfDefaultArgumentStub() =
|
fun IrFunction.getJvmVisibilityOfDefaultArgumentStub() =
|
||||||
if (Visibilities.isPrivate(visibility) || isInlineOnly()) JavaVisibilities.PACKAGE_VISIBILITY else Visibilities.PUBLIC
|
if (Visibilities.isPrivate(visibility) || isInlineOnly()) JavaVisibilities.PACKAGE_VISIBILITY else Visibilities.PUBLIC
|
||||||
|
|
||||||
fun IrValueParameter.isInlineParameter(type: IrType = this.type) =
|
fun IrValueParameter.isInlineParameter() =
|
||||||
index >= 0 && !isNoinline && !type.isNullable() && (type.isFunction() || type.isSuspendFunctionTypeOrSubtype())
|
index >= 0 && !isNoinline && (type.isFunction() || type.isSuspendFunctionTypeOrSubtype()) &&
|
||||||
|
// Parameters with default values are always nullable, so check the expression too.
|
||||||
|
// Note that the frontend has a diagnostic for nullable inline parameters, so actually
|
||||||
|
// making this return `false` requires using `@Suppress`.
|
||||||
|
(!type.isNullable() || defaultValue?.expression?.type?.isNullable() == false)
|
||||||
|
|
||||||
val IrStatementOrigin?.isLambda: Boolean
|
val IrStatementOrigin?.isLambda: Boolean
|
||||||
get() = this == IrStatementOrigin.LAMBDA || this == IrStatementOrigin.ANONYMOUS_FUNCTION
|
get() = this == IrStatementOrigin.LAMBDA || this == IrStatementOrigin.ANONYMOUS_FUNCTION
|
||||||
|
|||||||
+18
@@ -0,0 +1,18 @@
|
|||||||
|
// FILE: 1.kt
|
||||||
|
package test
|
||||||
|
|
||||||
|
// Argument `f` of `call$default` is technically nullable and inline.
|
||||||
|
inline fun call(other: Int = 1, crossinline f: () -> String = { "fail" }) = { f() }()
|
||||||
|
|
||||||
|
// FILE: 2.kt
|
||||||
|
import test.*
|
||||||
|
|
||||||
|
class A {
|
||||||
|
private fun method() = "O"
|
||||||
|
|
||||||
|
private val prop = "K"
|
||||||
|
|
||||||
|
fun test(): String = call { method() + prop }
|
||||||
|
}
|
||||||
|
|
||||||
|
fun box(): String = A().test()
|
||||||
+5
@@ -4550,6 +4550,11 @@ public class BlackBoxInlineCodegenTestGenerated extends AbstractBlackBoxInlineCo
|
|||||||
runTest("compiler/testData/codegen/boxInline/syntheticAccessors/withinInlineLambda/privateInCrossInline.kt");
|
runTest("compiler/testData/codegen/boxInline/syntheticAccessors/withinInlineLambda/privateInCrossInline.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("privateInDefaultStubArgument.kt")
|
||||||
|
public void testPrivateInDefaultStubArgument() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/boxInline/syntheticAccessors/withinInlineLambda/privateInDefaultStubArgument.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("protectedInCrossinline.kt")
|
@TestMetadata("protectedInCrossinline.kt")
|
||||||
public void testProtectedInCrossinline() throws Exception {
|
public void testProtectedInCrossinline() throws Exception {
|
||||||
runTest("compiler/testData/codegen/boxInline/syntheticAccessors/withinInlineLambda/protectedInCrossinline.kt");
|
runTest("compiler/testData/codegen/boxInline/syntheticAccessors/withinInlineLambda/protectedInCrossinline.kt");
|
||||||
|
|||||||
Generated
+5
@@ -4550,6 +4550,11 @@ public class CompileKotlinAgainstInlineKotlinTestGenerated extends AbstractCompi
|
|||||||
runTest("compiler/testData/codegen/boxInline/syntheticAccessors/withinInlineLambda/privateInCrossInline.kt");
|
runTest("compiler/testData/codegen/boxInline/syntheticAccessors/withinInlineLambda/privateInCrossInline.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("privateInDefaultStubArgument.kt")
|
||||||
|
public void testPrivateInDefaultStubArgument() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/boxInline/syntheticAccessors/withinInlineLambda/privateInDefaultStubArgument.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("protectedInCrossinline.kt")
|
@TestMetadata("protectedInCrossinline.kt")
|
||||||
public void testProtectedInCrossinline() throws Exception {
|
public void testProtectedInCrossinline() throws Exception {
|
||||||
runTest("compiler/testData/codegen/boxInline/syntheticAccessors/withinInlineLambda/protectedInCrossinline.kt");
|
runTest("compiler/testData/codegen/boxInline/syntheticAccessors/withinInlineLambda/protectedInCrossinline.kt");
|
||||||
|
|||||||
+5
@@ -4285,6 +4285,11 @@ public class IrBlackBoxInlineCodegenTestGenerated extends AbstractIrBlackBoxInli
|
|||||||
runTest("compiler/testData/codegen/boxInline/syntheticAccessors/withinInlineLambda/privateInCrossInline.kt");
|
runTest("compiler/testData/codegen/boxInline/syntheticAccessors/withinInlineLambda/privateInCrossInline.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("privateInDefaultStubArgument.kt")
|
||||||
|
public void testPrivateInDefaultStubArgument() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/boxInline/syntheticAccessors/withinInlineLambda/privateInDefaultStubArgument.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("protectedInCrossinline.kt")
|
@TestMetadata("protectedInCrossinline.kt")
|
||||||
public void testProtectedInCrossinline() throws Exception {
|
public void testProtectedInCrossinline() throws Exception {
|
||||||
runTest("compiler/testData/codegen/boxInline/syntheticAccessors/withinInlineLambda/protectedInCrossinline.kt");
|
runTest("compiler/testData/codegen/boxInline/syntheticAccessors/withinInlineLambda/protectedInCrossinline.kt");
|
||||||
|
|||||||
Generated
+5
@@ -4285,6 +4285,11 @@ public class IrCompileKotlinAgainstInlineKotlinTestGenerated extends AbstractIrC
|
|||||||
runTest("compiler/testData/codegen/boxInline/syntheticAccessors/withinInlineLambda/privateInCrossInline.kt");
|
runTest("compiler/testData/codegen/boxInline/syntheticAccessors/withinInlineLambda/privateInCrossInline.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("privateInDefaultStubArgument.kt")
|
||||||
|
public void testPrivateInDefaultStubArgument() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/boxInline/syntheticAccessors/withinInlineLambda/privateInDefaultStubArgument.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("protectedInCrossinline.kt")
|
@TestMetadata("protectedInCrossinline.kt")
|
||||||
public void testProtectedInCrossinline() throws Exception {
|
public void testProtectedInCrossinline() throws Exception {
|
||||||
runTest("compiler/testData/codegen/boxInline/syntheticAccessors/withinInlineLambda/protectedInCrossinline.kt");
|
runTest("compiler/testData/codegen/boxInline/syntheticAccessors/withinInlineLambda/protectedInCrossinline.kt");
|
||||||
|
|||||||
Generated
+5
@@ -3845,6 +3845,11 @@ public class IrJsCodegenInlineTestGenerated extends AbstractIrJsCodegenInlineTes
|
|||||||
runTest("compiler/testData/codegen/boxInline/syntheticAccessors/withinInlineLambda/privateInCrossInline.kt");
|
runTest("compiler/testData/codegen/boxInline/syntheticAccessors/withinInlineLambda/privateInCrossInline.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("privateInDefaultStubArgument.kt")
|
||||||
|
public void testPrivateInDefaultStubArgument() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/boxInline/syntheticAccessors/withinInlineLambda/privateInDefaultStubArgument.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("protectedInCrossinline.kt")
|
@TestMetadata("protectedInCrossinline.kt")
|
||||||
public void testProtectedInCrossinline() throws Exception {
|
public void testProtectedInCrossinline() throws Exception {
|
||||||
runTest("compiler/testData/codegen/boxInline/syntheticAccessors/withinInlineLambda/protectedInCrossinline.kt");
|
runTest("compiler/testData/codegen/boxInline/syntheticAccessors/withinInlineLambda/protectedInCrossinline.kt");
|
||||||
|
|||||||
+5
@@ -3845,6 +3845,11 @@ public class JsCodegenInlineTestGenerated extends AbstractJsCodegenInlineTest {
|
|||||||
runTest("compiler/testData/codegen/boxInline/syntheticAccessors/withinInlineLambda/privateInCrossInline.kt");
|
runTest("compiler/testData/codegen/boxInline/syntheticAccessors/withinInlineLambda/privateInCrossInline.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("privateInDefaultStubArgument.kt")
|
||||||
|
public void testPrivateInDefaultStubArgument() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/boxInline/syntheticAccessors/withinInlineLambda/privateInDefaultStubArgument.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("protectedInCrossinline.kt")
|
@TestMetadata("protectedInCrossinline.kt")
|
||||||
public void testProtectedInCrossinline() throws Exception {
|
public void testProtectedInCrossinline() throws Exception {
|
||||||
runTest("compiler/testData/codegen/boxInline/syntheticAccessors/withinInlineLambda/protectedInCrossinline.kt");
|
runTest("compiler/testData/codegen/boxInline/syntheticAccessors/withinInlineLambda/protectedInCrossinline.kt");
|
||||||
|
|||||||
Reference in New Issue
Block a user