diff --git a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/codegen/IrInlineCodegen.kt b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/codegen/IrInlineCodegen.kt index a9d07444b12..c0db33bee5b 100644 --- a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/codegen/IrInlineCodegen.kt +++ b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/codegen/IrInlineCodegen.kt @@ -82,8 +82,7 @@ class IrInlineCodegen( 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(irValueParameter.defaultValue?.expression?.type ?: irValueParameter.type) + val isInlineParameter = irValueParameter.isInlineParameter() if (isInlineParameter && isInlineIrExpression(argumentExpression)) { val irReference: IrFunctionReference = (argumentExpression as IrBlock).statements.filterIsInstance().single() diff --git a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/codegen/defaultMethodUtilIr.kt b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/codegen/defaultMethodUtilIr.kt index cabef62545d..160e292aae9 100644 --- a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/codegen/defaultMethodUtilIr.kt +++ b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/codegen/defaultMethodUtilIr.kt @@ -20,9 +20,7 @@ fun extractDefaultLambdaOffsetAndDescriptor( val valueParameterOffset = if (irFunction.extensionReceiverParameter != null) 1 else 0 - return irFunction.valueParameters.filter { - it.defaultValue != null && it.isInlineParameter(it.defaultValue!!.expression.type) - }.associateBy { + return irFunction.valueParameters.filter { it.defaultValue != null && it.isInlineParameter() }.associateBy { parameterOffsets[valueParameterOffset + it.index] } } diff --git a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/ir/IrUtils.kt b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/ir/IrUtils.kt index 46e589ad1f6..fbae8ae6c38 100644 --- a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/ir/IrUtils.kt +++ b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/ir/IrUtils.kt @@ -168,8 +168,12 @@ fun IrFunction.hasPlatformDependent(): Boolean = propertyIfAccessor.hasAnnotatio fun IrFunction.getJvmVisibilityOfDefaultArgumentStub() = if (Visibilities.isPrivate(visibility) || isInlineOnly()) JavaVisibilities.PACKAGE_VISIBILITY else Visibilities.PUBLIC -fun IrValueParameter.isInlineParameter(type: IrType = this.type) = - index >= 0 && !isNoinline && !type.isNullable() && (type.isFunction() || type.isSuspendFunctionTypeOrSubtype()) +fun IrValueParameter.isInlineParameter() = + 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 get() = this == IrStatementOrigin.LAMBDA || this == IrStatementOrigin.ANONYMOUS_FUNCTION diff --git a/compiler/testData/codegen/boxInline/syntheticAccessors/withinInlineLambda/privateInDefaultStubArgument.kt b/compiler/testData/codegen/boxInline/syntheticAccessors/withinInlineLambda/privateInDefaultStubArgument.kt new file mode 100644 index 00000000000..3583093ea0d --- /dev/null +++ b/compiler/testData/codegen/boxInline/syntheticAccessors/withinInlineLambda/privateInDefaultStubArgument.kt @@ -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() diff --git a/compiler/tests/org/jetbrains/kotlin/codegen/BlackBoxInlineCodegenTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/codegen/BlackBoxInlineCodegenTestGenerated.java index 8bfd60cacb2..8bc373049b8 100644 --- a/compiler/tests/org/jetbrains/kotlin/codegen/BlackBoxInlineCodegenTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/codegen/BlackBoxInlineCodegenTestGenerated.java @@ -4550,6 +4550,11 @@ public class BlackBoxInlineCodegenTestGenerated extends AbstractBlackBoxInlineCo 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") public void testProtectedInCrossinline() throws Exception { runTest("compiler/testData/codegen/boxInline/syntheticAccessors/withinInlineLambda/protectedInCrossinline.kt"); diff --git a/compiler/tests/org/jetbrains/kotlin/codegen/CompileKotlinAgainstInlineKotlinTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/codegen/CompileKotlinAgainstInlineKotlinTestGenerated.java index 45b8cfdda9a..a6e3c908cfd 100644 --- a/compiler/tests/org/jetbrains/kotlin/codegen/CompileKotlinAgainstInlineKotlinTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/codegen/CompileKotlinAgainstInlineKotlinTestGenerated.java @@ -4550,6 +4550,11 @@ public class CompileKotlinAgainstInlineKotlinTestGenerated extends AbstractCompi 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") public void testProtectedInCrossinline() throws Exception { runTest("compiler/testData/codegen/boxInline/syntheticAccessors/withinInlineLambda/protectedInCrossinline.kt"); diff --git a/compiler/tests/org/jetbrains/kotlin/codegen/ir/IrBlackBoxInlineCodegenTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/codegen/ir/IrBlackBoxInlineCodegenTestGenerated.java index 0b544572b20..053bd47b714 100644 --- a/compiler/tests/org/jetbrains/kotlin/codegen/ir/IrBlackBoxInlineCodegenTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/codegen/ir/IrBlackBoxInlineCodegenTestGenerated.java @@ -4285,6 +4285,11 @@ public class IrBlackBoxInlineCodegenTestGenerated extends AbstractIrBlackBoxInli 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") public void testProtectedInCrossinline() throws Exception { runTest("compiler/testData/codegen/boxInline/syntheticAccessors/withinInlineLambda/protectedInCrossinline.kt"); diff --git a/compiler/tests/org/jetbrains/kotlin/codegen/ir/IrCompileKotlinAgainstInlineKotlinTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/codegen/ir/IrCompileKotlinAgainstInlineKotlinTestGenerated.java index 2ea226ad0cb..97b3758c830 100644 --- a/compiler/tests/org/jetbrains/kotlin/codegen/ir/IrCompileKotlinAgainstInlineKotlinTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/codegen/ir/IrCompileKotlinAgainstInlineKotlinTestGenerated.java @@ -4285,6 +4285,11 @@ public class IrCompileKotlinAgainstInlineKotlinTestGenerated extends AbstractIrC 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") public void testProtectedInCrossinline() throws Exception { runTest("compiler/testData/codegen/boxInline/syntheticAccessors/withinInlineLambda/protectedInCrossinline.kt"); diff --git a/js/js.tests/test/org/jetbrains/kotlin/js/test/ir/semantics/IrJsCodegenInlineTestGenerated.java b/js/js.tests/test/org/jetbrains/kotlin/js/test/ir/semantics/IrJsCodegenInlineTestGenerated.java index 07db99a2f93..c9d33c1debb 100644 --- a/js/js.tests/test/org/jetbrains/kotlin/js/test/ir/semantics/IrJsCodegenInlineTestGenerated.java +++ b/js/js.tests/test/org/jetbrains/kotlin/js/test/ir/semantics/IrJsCodegenInlineTestGenerated.java @@ -3845,6 +3845,11 @@ public class IrJsCodegenInlineTestGenerated extends AbstractIrJsCodegenInlineTes 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") public void testProtectedInCrossinline() throws Exception { runTest("compiler/testData/codegen/boxInline/syntheticAccessors/withinInlineLambda/protectedInCrossinline.kt"); diff --git a/js/js.tests/test/org/jetbrains/kotlin/js/test/semantics/JsCodegenInlineTestGenerated.java b/js/js.tests/test/org/jetbrains/kotlin/js/test/semantics/JsCodegenInlineTestGenerated.java index 3b1dba2cfa6..b864ea4d1c5 100644 --- a/js/js.tests/test/org/jetbrains/kotlin/js/test/semantics/JsCodegenInlineTestGenerated.java +++ b/js/js.tests/test/org/jetbrains/kotlin/js/test/semantics/JsCodegenInlineTestGenerated.java @@ -3845,6 +3845,11 @@ public class JsCodegenInlineTestGenerated extends AbstractJsCodegenInlineTest { 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") public void testProtectedInCrossinline() throws Exception { runTest("compiler/testData/codegen/boxInline/syntheticAccessors/withinInlineLambda/protectedInCrossinline.kt");