diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/InlineCodegen.kt b/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/InlineCodegen.kt index 67ed3d19da2..d1a551a1428 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/InlineCodegen.kt +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/InlineCodegen.kt @@ -529,7 +529,7 @@ abstract class InlineCodegen( val varDescriptor = field.descriptor //check that variable is inline function parameter return !(varDescriptor is ParameterDescriptor && - InlineUtil.isInlineLambdaParameter(varDescriptor) && + InlineUtil.isInlineParameter(varDescriptor) && InlineUtil.isInline(varDescriptor.containingDeclaration)) } @@ -631,7 +631,7 @@ class PsiInlineCodegen( //TODO deparenthisise typed val deparenthesized = KtPsiUtil.deparenthesize(expression) - return InlineUtil.isInlineLambdaParameter(valueParameterDescriptor) && isInlinableParameterExpression(deparenthesized) + return InlineUtil.isInlineParameter(valueParameterDescriptor) && isInlinableParameterExpression(deparenthesized) } override fun genValueAndPut( diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/defaultMethodUtil.kt b/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/defaultMethodUtil.kt index 2b407d521b5..8ef3da3c80a 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/defaultMethodUtil.kt +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/defaultMethodUtil.kt @@ -51,7 +51,7 @@ fun extractDefaultLambdaOffsetAndDescriptor(jvmSignature: JvmMethodSignature, fu val valueParameterOffset = valueParameters.takeWhile { it.kind != JvmMethodParameterKind.VALUE }.size return functionDescriptor.valueParameters.filter { - InlineUtil.isInlineLambdaParameter(it) && it.declaresDefaultValue() + InlineUtil.isInlineParameter(it) && it.declaresDefaultValue() }.associateBy { parameterOffsets[valueParameterOffset + it.index] } diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/checkers/InlineChecker.kt b/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/checkers/InlineChecker.kt index db7fe55f759..984a79b0ef3 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/checkers/InlineChecker.kt +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/checkers/InlineChecker.kt @@ -51,7 +51,7 @@ internal class InlineChecker(private val descriptor: FunctionDescriptor) : CallC private val isEffectivelyPrivateApiFunction = descriptor.isEffectivelyPrivateApi - private val inlinableParameters = descriptor.valueParameters.filter { isInlinableParameter(it) } + private val inlinableParameters = descriptor.valueParameters.filter { InlineUtil.isInlineParameter(it) } private val inlinableKtParameters = inlinableParameters.mapNotNull { (it.source as? KotlinSourceElement)?.psi } @@ -132,7 +132,7 @@ internal class InlineChecker(private val descriptor: FunctionDescriptor) : CallC when { !checkNotInDefaultParameter(context, argumentCallee, argumentExpression) -> { /*error*/ } - InlineUtil.isInline(targetDescriptor) && isInlinableParameter(targetParameterDescriptor) -> + InlineUtil.isInline(targetDescriptor) && InlineUtil.isInlineParameter(targetParameterDescriptor) -> if (allowsNonLocalReturns(argumentCallee) && !allowsNonLocalReturns(targetParameterDescriptor)) { context.trace.report(NON_LOCAL_RETURN_NOT_ALLOWED.on(argumentExpression, argumentExpression)) } @@ -219,10 +219,6 @@ internal class InlineChecker(private val descriptor: FunctionDescriptor) : CallC } } - private fun isInlinableParameter(descriptor: ParameterDescriptor): Boolean { - return InlineUtil.isInlineLambdaParameter(descriptor) && !descriptor.type.isMarkedNullable - } - private fun isInvokeOrInlineExtension(descriptor: CallableDescriptor): Boolean { if (descriptor !is SimpleFunctionDescriptor) { return false diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/inline/InlineAnalyzerExtension.kt b/compiler/frontend/src/org/jetbrains/kotlin/resolve/inline/InlineAnalyzerExtension.kt index bab74f8846f..b19253d92bb 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/inline/InlineAnalyzerExtension.kt +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/inline/InlineAnalyzerExtension.kt @@ -154,9 +154,12 @@ class InlineAnalyzerExtension( } private fun checkHasInlinableAndNullability(functionDescriptor: FunctionDescriptor, function: KtFunction, trace: BindingTrace) { - for ((parameter, descriptor) in function.valueParameters.zip(functionDescriptor.valueParameters)) { - if (checkInlinableParameter(descriptor, parameter, functionDescriptor, trace)) return + var hasInlineArgs = false + function.valueParameters.zip(functionDescriptor.valueParameters).forEach { + (parameter, descriptor) -> + hasInlineArgs = hasInlineArgs or checkInlinableParameter(descriptor, parameter, functionDescriptor, trace) } + if (hasInlineArgs) return if (functionDescriptor.isInlineOnlyOrReifiable() || functionDescriptor.isHeader) return @@ -171,7 +174,7 @@ class InlineAnalyzerExtension( expression: KtElement, functionDescriptor: CallableDescriptor, trace: BindingTrace?): Boolean { - if (InlineUtil.isInlineLambdaParameter(parameter)) { + if (InlineUtil.isInlineParameterExceptNullability(parameter)) { if (parameter.type.isMarkedNullable) { trace?.report(Errors.NULLABLE_INLINE_PARAMETER.on(expression, expression, functionDescriptor)) } diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/inline/InlineUtil.java b/compiler/frontend/src/org/jetbrains/kotlin/resolve/inline/InlineUtil.java index b0a79926c29..ac393211392 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/inline/InlineUtil.java +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/inline/InlineUtil.java @@ -32,12 +32,18 @@ import org.jetbrains.kotlin.resolve.calls.model.ArgumentMatch; import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall; public class InlineUtil { - public static boolean isInlineLambdaParameter(@NotNull ParameterDescriptor valueParameterOrReceiver) { + + public static boolean isInlineParameterExceptNullability(@NotNull ParameterDescriptor valueParameterOrReceiver) { return !(valueParameterOrReceiver instanceof ValueParameterDescriptor && ((ValueParameterDescriptor) valueParameterOrReceiver).isNoinline()) && FunctionTypesKt.isFunctionType(valueParameterOrReceiver.getOriginal().getType()); } + public static boolean isInlineParameter(@NotNull ParameterDescriptor valueParameterOrReceiver) { + return isInlineParameterExceptNullability(valueParameterOrReceiver) && + !valueParameterOrReceiver.getOriginal().getType().isMarkedNullable(); + } + public static boolean isInline(@Nullable DeclarationDescriptor descriptor) { return descriptor instanceof FunctionDescriptor && getInlineStrategy((FunctionDescriptor) descriptor).isInline(); } @@ -152,7 +158,7 @@ public class InlineUtil { if (!(mapping instanceof ArgumentMatch)) return null; ValueParameterDescriptor parameter = ((ArgumentMatch) mapping).getValueParameter(); - return isInlineLambdaParameter(parameter) ? parameter : null; + return isInlineParameter(parameter) ? parameter : null; } public static boolean canBeInlineArgument(@Nullable PsiElement functionalExpression) { diff --git a/compiler/testData/codegen/boxInline/defaultValues/maskElimination/kt19679.kt b/compiler/testData/codegen/boxInline/defaultValues/maskElimination/kt19679.kt new file mode 100644 index 00000000000..046b61f6bd1 --- /dev/null +++ b/compiler/testData/codegen/boxInline/defaultValues/maskElimination/kt19679.kt @@ -0,0 +1,19 @@ +// FILE: 1.kt +package test + +inline fun build(func: () -> Unit, noinline pathFunc: (() -> String)? = null) { + func() + + pathFunc?.invoke() +} + +// FILE: 2.kt + +import test.* + +fun box(): String { + var result = "fail" + build({ result = "OK" }) + + return result +} \ No newline at end of file diff --git a/compiler/testData/codegen/boxInline/defaultValues/maskElimination/kt19679_2.kt b/compiler/testData/codegen/boxInline/defaultValues/maskElimination/kt19679_2.kt new file mode 100644 index 00000000000..001a65f8d62 --- /dev/null +++ b/compiler/testData/codegen/boxInline/defaultValues/maskElimination/kt19679_2.kt @@ -0,0 +1,15 @@ +// FILE: 1.kt +package test + +inline fun build(noinline pathFunc: (() -> String)? = null) { + pathFunc?.invoke() +} + +// FILE: 2.kt + +import test.* + +fun box(): String { + build () + return "OK" +} \ No newline at end of file diff --git a/compiler/testData/codegen/boxInline/defaultValues/maskElimination/kt19679_3.kt b/compiler/testData/codegen/boxInline/defaultValues/maskElimination/kt19679_3.kt new file mode 100644 index 00000000000..8a8385a6857 --- /dev/null +++ b/compiler/testData/codegen/boxInline/defaultValues/maskElimination/kt19679_3.kt @@ -0,0 +1,20 @@ +// FILE: 1.kt +package test + +@Suppress("NULLABLE_INLINE_PARAMETER") +inline fun build(func: () -> Unit, pathFunc: (() -> String)? = null) { + func() + + pathFunc?.invoke() +} + +// FILE: 2.kt + +import test.* + +fun box(): String { + var result = "fail" + build ({ result = "OK" }) + + return result +} \ No newline at end of file diff --git a/compiler/testData/diagnostics/tests/inline/kt19679.kt b/compiler/testData/diagnostics/tests/inline/kt19679.kt new file mode 100644 index 00000000000..509269f7e1c --- /dev/null +++ b/compiler/testData/diagnostics/tests/inline/kt19679.kt @@ -0,0 +1,4 @@ +inline fun test(s: () -> Unit, p: (() -> Unit)?) { + s() + p?.invoke() +} \ No newline at end of file diff --git a/compiler/testData/diagnostics/tests/inline/kt19679.txt b/compiler/testData/diagnostics/tests/inline/kt19679.txt new file mode 100644 index 00000000000..50adc933d46 --- /dev/null +++ b/compiler/testData/diagnostics/tests/inline/kt19679.txt @@ -0,0 +1,3 @@ +package + +public inline fun test(/*0*/ s: () -> kotlin.Unit, /*1*/ p: (() -> kotlin.Unit)?): kotlin.Unit diff --git a/compiler/tests-ir-jvm/tests/org/jetbrains/kotlin/codegen/ir/IrBlackBoxInlineCodegenTestGenerated.java b/compiler/tests-ir-jvm/tests/org/jetbrains/kotlin/codegen/ir/IrBlackBoxInlineCodegenTestGenerated.java index 5d845756dad..419365c376d 100644 --- a/compiler/tests-ir-jvm/tests/org/jetbrains/kotlin/codegen/ir/IrBlackBoxInlineCodegenTestGenerated.java +++ b/compiler/tests-ir-jvm/tests/org/jetbrains/kotlin/codegen/ir/IrBlackBoxInlineCodegenTestGenerated.java @@ -1339,6 +1339,24 @@ public class IrBlackBoxInlineCodegenTestGenerated extends AbstractIrBlackBoxInli doTest(fileName); } + @TestMetadata("kt19679.kt") + public void testKt19679() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/boxInline/defaultValues/maskElimination/kt19679.kt"); + doTest(fileName); + } + + @TestMetadata("kt19679_2.kt") + public void testKt19679_2() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/boxInline/defaultValues/maskElimination/kt19679_2.kt"); + doTest(fileName); + } + + @TestMetadata("kt19679_3.kt") + public void testKt19679_3() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/boxInline/defaultValues/maskElimination/kt19679_3.kt"); + doTest(fileName); + } + @TestMetadata("simple.kt") public void testSimple() throws Exception { String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/boxInline/defaultValues/maskElimination/simple.kt"); diff --git a/compiler/tests-ir-jvm/tests/org/jetbrains/kotlin/codegen/ir/IrCompileKotlinAgainstInlineKotlinTestGenerated.java b/compiler/tests-ir-jvm/tests/org/jetbrains/kotlin/codegen/ir/IrCompileKotlinAgainstInlineKotlinTestGenerated.java index 8c7ca0e8819..719ca8d9cd9 100644 --- a/compiler/tests-ir-jvm/tests/org/jetbrains/kotlin/codegen/ir/IrCompileKotlinAgainstInlineKotlinTestGenerated.java +++ b/compiler/tests-ir-jvm/tests/org/jetbrains/kotlin/codegen/ir/IrCompileKotlinAgainstInlineKotlinTestGenerated.java @@ -1339,6 +1339,24 @@ public class IrCompileKotlinAgainstInlineKotlinTestGenerated extends AbstractIrC doTest(fileName); } + @TestMetadata("kt19679.kt") + public void testKt19679() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/boxInline/defaultValues/maskElimination/kt19679.kt"); + doTest(fileName); + } + + @TestMetadata("kt19679_2.kt") + public void testKt19679_2() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/boxInline/defaultValues/maskElimination/kt19679_2.kt"); + doTest(fileName); + } + + @TestMetadata("kt19679_3.kt") + public void testKt19679_3() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/boxInline/defaultValues/maskElimination/kt19679_3.kt"); + doTest(fileName); + } + @TestMetadata("simple.kt") public void testSimple() throws Exception { String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/boxInline/defaultValues/maskElimination/simple.kt"); diff --git a/compiler/tests/org/jetbrains/kotlin/checkers/DiagnosticsTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/checkers/DiagnosticsTestGenerated.java index b018a8bff9a..0a13c4b0f06 100644 --- a/compiler/tests/org/jetbrains/kotlin/checkers/DiagnosticsTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/checkers/DiagnosticsTestGenerated.java @@ -11263,6 +11263,12 @@ public class DiagnosticsTestGenerated extends AbstractDiagnosticsTest { doTest(fileName); } + @TestMetadata("kt19679.kt") + public void testKt19679() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/inline/kt19679.kt"); + doTest(fileName); + } + @TestMetadata("kt4869.kt") public void testKt4869() throws Exception { String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/inline/kt4869.kt"); diff --git a/compiler/tests/org/jetbrains/kotlin/codegen/BlackBoxInlineCodegenTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/codegen/BlackBoxInlineCodegenTestGenerated.java index e5114598332..03d13d07939 100644 --- a/compiler/tests/org/jetbrains/kotlin/codegen/BlackBoxInlineCodegenTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/codegen/BlackBoxInlineCodegenTestGenerated.java @@ -1339,6 +1339,24 @@ public class BlackBoxInlineCodegenTestGenerated extends AbstractBlackBoxInlineCo doTest(fileName); } + @TestMetadata("kt19679.kt") + public void testKt19679() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/boxInline/defaultValues/maskElimination/kt19679.kt"); + doTest(fileName); + } + + @TestMetadata("kt19679_2.kt") + public void testKt19679_2() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/boxInline/defaultValues/maskElimination/kt19679_2.kt"); + doTest(fileName); + } + + @TestMetadata("kt19679_3.kt") + public void testKt19679_3() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/boxInline/defaultValues/maskElimination/kt19679_3.kt"); + doTest(fileName); + } + @TestMetadata("simple.kt") public void testSimple() throws Exception { String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/boxInline/defaultValues/maskElimination/simple.kt"); diff --git a/compiler/tests/org/jetbrains/kotlin/codegen/CompileKotlinAgainstInlineKotlinTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/codegen/CompileKotlinAgainstInlineKotlinTestGenerated.java index 6146888223c..a831d603a3b 100644 --- a/compiler/tests/org/jetbrains/kotlin/codegen/CompileKotlinAgainstInlineKotlinTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/codegen/CompileKotlinAgainstInlineKotlinTestGenerated.java @@ -1339,6 +1339,24 @@ public class CompileKotlinAgainstInlineKotlinTestGenerated extends AbstractCompi doTest(fileName); } + @TestMetadata("kt19679.kt") + public void testKt19679() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/boxInline/defaultValues/maskElimination/kt19679.kt"); + doTest(fileName); + } + + @TestMetadata("kt19679_2.kt") + public void testKt19679_2() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/boxInline/defaultValues/maskElimination/kt19679_2.kt"); + doTest(fileName); + } + + @TestMetadata("kt19679_3.kt") + public void testKt19679_3() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/boxInline/defaultValues/maskElimination/kt19679_3.kt"); + doTest(fileName); + } + @TestMetadata("simple.kt") public void testSimple() throws Exception { String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/boxInline/defaultValues/maskElimination/simple.kt"); diff --git a/js/js.tests/test/org/jetbrains/kotlin/js/test/semantics/InlineDefaultValuesTestsGenerated.java b/js/js.tests/test/org/jetbrains/kotlin/js/test/semantics/InlineDefaultValuesTestsGenerated.java index a5e02ce8264..691c5a4c082 100644 --- a/js/js.tests/test/org/jetbrains/kotlin/js/test/semantics/InlineDefaultValuesTestsGenerated.java +++ b/js/js.tests/test/org/jetbrains/kotlin/js/test/semantics/InlineDefaultValuesTestsGenerated.java @@ -416,6 +416,24 @@ public class InlineDefaultValuesTestsGenerated extends AbstractInlineDefaultValu doTest(fileName); } + @TestMetadata("kt19679.kt") + public void testKt19679() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/boxInline/defaultValues/maskElimination/kt19679.kt"); + doTest(fileName); + } + + @TestMetadata("kt19679_2.kt") + public void testKt19679_2() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/boxInline/defaultValues/maskElimination/kt19679_2.kt"); + doTest(fileName); + } + + @TestMetadata("kt19679_3.kt") + public void testKt19679_3() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/boxInline/defaultValues/maskElimination/kt19679_3.kt"); + doTest(fileName); + } + @TestMetadata("simple.kt") public void testSimple() throws Exception { String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/boxInline/defaultValues/maskElimination/simple.kt"); diff --git a/js/js.translator/src/org/jetbrains/kotlin/js/translate/reference/CallExpressionTranslator.java b/js/js.translator/src/org/jetbrains/kotlin/js/translate/reference/CallExpressionTranslator.java index 8c7646dfdcb..13dbbd524cc 100644 --- a/js/js.translator/src/org/jetbrains/kotlin/js/translate/reference/CallExpressionTranslator.java +++ b/js/js.translator/src/org/jetbrains/kotlin/js/translate/reference/CallExpressionTranslator.java @@ -79,7 +79,7 @@ public final class CallExpressionTranslator extends AbstractCallExpressionTransl if (descriptor instanceof ValueParameterDescriptor) { return InlineUtil.isInline(descriptor.getContainingDeclaration()) && - InlineUtil.isInlineLambdaParameter((ParameterDescriptor) descriptor) && + InlineUtil.isInlineParameter((ParameterDescriptor) descriptor) && !((ValueParameterDescriptor) descriptor).isCrossinline(); }