diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/InlineDescriptorUtils.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/InlineDescriptorUtils.java index b1a3968e56b..37ea298fed8 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/InlineDescriptorUtils.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/InlineDescriptorUtils.java @@ -46,24 +46,7 @@ public class InlineDescriptorUtils { while (containingFunction instanceof JetFunctionLiteral && fromFunction != containingFunctionDescriptor) { //JetFunctionLiteralExpression containingFunction = containingFunction.getParent(); - boolean allowsNonLocalReturns = false; - JetExpression call = JetPsiUtil.getParentCallIfPresent((JetFunctionLiteralExpression) containingFunction); - if (call != null) { - ResolvedCall resolvedCall = CallUtilPackage.getResolvedCall(call, bindingContext); - CallableDescriptor resultingDescriptor = resolvedCall == null ? null : resolvedCall.getResultingDescriptor(); - if (resultingDescriptor instanceof SimpleFunctionDescriptor && - ((SimpleFunctionDescriptor) resultingDescriptor).getInlineStrategy().isInline()) { - ValueArgument argument = CallUtilPackage.getValueArgumentForExpression( - resolvedCall.getCall(), (JetFunctionLiteralExpression) containingFunction); - if (argument != null) { - ArgumentMapping mapping = resolvedCall.getArgumentMapping(argument); - if (mapping instanceof ArgumentMatch) { - allowsNonLocalReturns = allowsNonLocalReturns(((ArgumentMatch) mapping).getValueParameter()); - } - } - } - } - if (!allowsNonLocalReturns) { + if (!isInlineLambda((JetFunctionLiteralExpression) containingFunction, bindingContext, true)) { return false; } @@ -77,6 +60,32 @@ public class InlineDescriptorUtils { return fromFunction == containingFunctionDescriptor; } + public static boolean isInlineLambda( + @NotNull JetFunctionLiteralExpression lambdaExpression, + @NotNull BindingContext bindingContext, + boolean checkNonLocalReturn + ) { + JetExpression call = JetPsiUtil.getParentCallIfPresent(lambdaExpression); + if (call != null) { + ResolvedCall resolvedCall = CallUtilPackage.getResolvedCall(call, bindingContext); + CallableDescriptor resultingDescriptor = resolvedCall == null ? null : resolvedCall.getResultingDescriptor(); + if (resultingDescriptor instanceof SimpleFunctionDescriptor && + ((SimpleFunctionDescriptor) resultingDescriptor).getInlineStrategy().isInline()) { + ValueArgument argument = CallUtilPackage.getValueArgumentForExpression(resolvedCall.getCall(), lambdaExpression); + if (argument != null) { + ArgumentMapping mapping = resolvedCall.getArgumentMapping(argument); + if (mapping instanceof ArgumentMatch) { + ValueParameterDescriptor parameter = ((ArgumentMatch) mapping).getValueParameter(); + if (!InlineUtil.hasNoinlineAnnotation(parameter)) { + return !checkNonLocalReturn || allowsNonLocalReturns(parameter); + } + } + } + } + } + return false; + } + @Nullable public static DeclarationDescriptor getContainingClassOrFunctionDescriptor(@NotNull DeclarationDescriptor descriptor, boolean strict) { DeclarationDescriptor currentDescriptor = strict ? descriptor.getContainingDeclaration() : descriptor; diff --git a/compiler/testData/diagnostics/tests/inline/nonLocalReturns/noInlineAnnotation.kt b/compiler/testData/diagnostics/tests/inline/nonLocalReturns/noInlineAnnotation.kt new file mode 100644 index 00000000000..72c5bde1993 --- /dev/null +++ b/compiler/testData/diagnostics/tests/inline/nonLocalReturns/noInlineAnnotation.kt @@ -0,0 +1,10 @@ +// !DIAGNOSTICS: -NOTHING_TO_INLINE +fun main(args: Array) { + test { + return + } +} + +inline fun test(noinline lambda: () -> Unit) { + lambda() +} \ No newline at end of file diff --git a/compiler/tests/org/jetbrains/jet/checkers/JetDiagnosticsTestGenerated.java b/compiler/tests/org/jetbrains/jet/checkers/JetDiagnosticsTestGenerated.java index 0027562f4ee..1852e4fff26 100644 --- a/compiler/tests/org/jetbrains/jet/checkers/JetDiagnosticsTestGenerated.java +++ b/compiler/tests/org/jetbrains/jet/checkers/JetDiagnosticsTestGenerated.java @@ -5667,6 +5667,12 @@ public class JetDiagnosticsTestGenerated extends AbstractJetDiagnosticsTest { doTest(fileName); } + @TestMetadata("noInlineAnnotation.kt") + public void testNoInlineAnnotation() throws Exception { + String fileName = JetTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/inline/nonLocalReturns/noInlineAnnotation.kt"); + doTest(fileName); + } + @TestMetadata("noInlineLambda.kt") public void testNoInlineLambda() throws Exception { String fileName = JetTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/inline/nonLocalReturns/noInlineLambda.kt");