diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/extension/InlineAnalyzerExtension.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/extension/InlineAnalyzerExtension.java index 401b5587d55..93f67e61090 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/extension/InlineAnalyzerExtension.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/extension/InlineAnalyzerExtension.java @@ -22,6 +22,8 @@ import org.jetbrains.jet.lang.diagnostics.Errors; import org.jetbrains.jet.lang.psi.*; import org.jetbrains.jet.lang.resolve.BindingTrace; import org.jetbrains.jet.lang.resolve.FunctionAnalyzerExtension; +import org.jetbrains.jet.lang.types.lang.InlineUtil; +import org.jetbrains.jet.lang.types.lang.KotlinBuiltIns; import java.util.List; @@ -42,6 +44,7 @@ public class InlineAnalyzerExtension implements FunctionAnalyzerExtension.Analyz checkDefaults(descriptor, function, trace); checkModality(descriptor, function, trace); + checkHashInlinable(descriptor, function, trace); JetVisitorVoid visitor = new JetVisitorVoid() { @@ -102,4 +105,29 @@ public class InlineAnalyzerExtension implements FunctionAnalyzerExtension.Analyz trace.report(Errors.DECLARATION_CANT_BE_INLINED.on(function)); } + + private void checkHashInlinable( + @NotNull FunctionDescriptor functionDescriptor, + @NotNull JetFunction function, + @NotNull BindingTrace trace + ) { + List parameters = functionDescriptor.getValueParameters(); + for (ValueParameterDescriptor parameter : parameters) { + KotlinBuiltIns builtIns = KotlinBuiltIns.getInstance(); + if (builtIns.isExactFunctionOrExtensionFunctionType(parameter.getType())) { + if (!InlineUtil.hasNoinlineAnnotation(parameter)) { + return; + } + } + } + ReceiverParameterDescriptor receiverParameter = functionDescriptor.getReceiverParameter(); + if (receiverParameter != null) { + if (KotlinBuiltIns.getInstance().isExactFunctionOrExtensionFunctionType(receiverParameter.getType())) { + //or extension on inlinable function + return; + } + } + + trace.report(Errors.NOTHING_TO_INLINE.on(function, functionDescriptor)); + } } diff --git a/compiler/testData/diagnostics/tests/inline/capture.kt b/compiler/testData/diagnostics/tests/inline/capture.kt index 1915a8c8d85..5b821c1407c 100644 --- a/compiler/testData/diagnostics/tests/inline/capture.kt +++ b/compiler/testData/diagnostics/tests/inline/capture.kt @@ -1,4 +1,4 @@ -// !DIAGNOSTICS: -UNUSED_EXPRESSION -UNUSED_PARAMETER -UNUSED_VARIABLE +// !DIAGNOSTICS: -UNUSED_EXPRESSION -UNUSED_PARAMETER -UNUSED_VARIABLE -NOTHING_TO_INLINE fun Function1.noInlineExt(p: Int) {} @@ -48,4 +48,4 @@ inline fun inlineFunWrongExtension(s: (p: Int) -> Unit) { { s.noInlineExt(11) } () -} +} \ No newline at end of file diff --git a/compiler/testData/diagnostics/tests/inline/extensionOnFunction.kt b/compiler/testData/diagnostics/tests/inline/extensionOnFunction.kt index 429d33a3ac8..58f71163cae 100644 --- a/compiler/testData/diagnostics/tests/inline/extensionOnFunction.kt +++ b/compiler/testData/diagnostics/tests/inline/extensionOnFunction.kt @@ -1,4 +1,4 @@ -// !DIAGNOSTICS: -UNUSED_EXPRESSION -UNUSED_PARAMETER -UNUSED_VARIABLE +// !DIAGNOSTICS: -UNUSED_EXPRESSION -UNUSED_PARAMETER -UNUSED_VARIABLE -NOTHING_TO_INLINE fun Function1.noInlineExt(p: Int) {} diff --git a/compiler/testData/diagnostics/tests/inline/invoke.kt b/compiler/testData/diagnostics/tests/inline/invoke.kt index d706fd56e0f..80db51f666c 100644 --- a/compiler/testData/diagnostics/tests/inline/invoke.kt +++ b/compiler/testData/diagnostics/tests/inline/invoke.kt @@ -1,4 +1,4 @@ -// !DIAGNOSTICS: -UNUSED_EXPRESSION -UNUSED_PARAMETER -UNUSED_VARIABLE +// !DIAGNOSTICS: -UNUSED_EXPRESSION -UNUSED_PARAMETER -UNUSED_VARIABLE -NOTHING_TO_INLINE inline fun inlineFunWithInvoke(s: (p: Int) -> Unit, ext: Int.(p: Int) -> Unit) { s(11) diff --git a/compiler/testData/diagnostics/tests/inline/nonVirtualMembersWithInline.kt b/compiler/testData/diagnostics/tests/inline/nonVirtualMembersWithInline.kt index b18966960f5..4a2765e39a7 100644 --- a/compiler/testData/diagnostics/tests/inline/nonVirtualMembersWithInline.kt +++ b/compiler/testData/diagnostics/tests/inline/nonVirtualMembersWithInline.kt @@ -1,3 +1,5 @@ +// !DIAGNOSTICS: -UNUSED_EXPRESSION -UNUSED_PARAMETER -UNUSED_VARIABLE -NOTHING_TO_INLINE + inline private fun a() {} inline fun b() {} diff --git a/compiler/testData/diagnostics/tests/inline/nothingToInline.kt b/compiler/testData/diagnostics/tests/inline/nothingToInline.kt new file mode 100644 index 00000000000..a9bd8a8294d --- /dev/null +++ b/compiler/testData/diagnostics/tests/inline/nothingToInline.kt @@ -0,0 +1,29 @@ +// !DIAGNOSTICS: -UNUSED_EXPRESSION -UNUSED_PARAMETER -UNUSED_VARIABLE -NULLABLE_INLINE_PARAMETER + +inline fun test() { + +} + +inline fun test2(s : (Int) -> Int) { + +} + +inline fun test3(noinline s : (Int) -> Int) { + +} + +inline fun test4(noinline s : Int.() -> Int) { + +} + +inline fun Function1?.test5() { + +} + +inline fun Function1?.test6() { + +} + +inline fun test2(s : ((Int) -> Int)?) { + +} \ No newline at end of file diff --git a/compiler/testData/diagnostics/tests/inline/propagation.kt b/compiler/testData/diagnostics/tests/inline/propagation.kt index 239172d8043..658dede57d4 100644 --- a/compiler/testData/diagnostics/tests/inline/propagation.kt +++ b/compiler/testData/diagnostics/tests/inline/propagation.kt @@ -1,4 +1,4 @@ -// !DIAGNOSTICS: -UNUSED_EXPRESSION -UNUSED_PARAMETER -UNUSED_VARIABLE +// !DIAGNOSTICS: -UNUSED_EXPRESSION -UNUSED_PARAMETER -UNUSED_VARIABLE -NOTHING_TO_INLINE inline fun inlineFunWithInvoke(s: (p: Int) -> Unit, ext: Int.(p: Int) -> Unit) { subInline(s, ext) @@ -34,4 +34,4 @@ inline fun Function1.inlineExtWithClosure(ext: Int.(p: Int) -> Unit) inline fun subInline(s: (p: Int) -> Unit, ext: Int.(p: Int) -> Unit) {} -fun subNoInline(s: (p: Int) -> Unit, ext: Int.(p: Int) -> Unit) {} \ No newline at end of file +fun subNoInline(s: (p: Int) -> Unit, ext: Int.(p: Int) -> Unit) {} diff --git a/compiler/testData/diagnostics/tests/inline/unsupportedConstruction.kt b/compiler/testData/diagnostics/tests/inline/unsupportedConstruction.kt index a886b09c8f3..3e3b3277637 100644 --- a/compiler/testData/diagnostics/tests/inline/unsupportedConstruction.kt +++ b/compiler/testData/diagnostics/tests/inline/unsupportedConstruction.kt @@ -1,4 +1,4 @@ -// !DIAGNOSTICS: -UNUSED_EXPRESSION -UNUSED_PARAMETER -UNUSED_VARIABLE +// !DIAGNOSTICS: -UNUSED_EXPRESSION -UNUSED_PARAMETER -UNUSED_VARIABLE -NOTHING_TO_INLINE inline fun unsupported() { diff --git a/compiler/testData/diagnostics/tests/inline/vararg.kt b/compiler/testData/diagnostics/tests/inline/vararg.kt index 014b20f1635..9a9116b67fd 100644 --- a/compiler/testData/diagnostics/tests/inline/vararg.kt +++ b/compiler/testData/diagnostics/tests/inline/vararg.kt @@ -1,4 +1,4 @@ -// !DIAGNOSTICS: -UNUSED_EXPRESSION -UNUSED_PARAMETER -UNUSED_VARIABLE +// !DIAGNOSTICS: -UNUSED_EXPRESSION -UNUSED_PARAMETER -UNUSED_VARIABLE -NOTHING_TO_INLINE inline fun inlineFun(s: (p: Int) -> Unit, noinline b: (p: Int) -> Unit) { subInline(s, b) diff --git a/compiler/tests/org/jetbrains/jet/checkers/JetDiagnosticsTestGenerated.java b/compiler/tests/org/jetbrains/jet/checkers/JetDiagnosticsTestGenerated.java index 959fa1dd328..86f54331042 100644 --- a/compiler/tests/org/jetbrains/jet/checkers/JetDiagnosticsTestGenerated.java +++ b/compiler/tests/org/jetbrains/jet/checkers/JetDiagnosticsTestGenerated.java @@ -3787,6 +3787,11 @@ public class JetDiagnosticsTestGenerated extends AbstractDiagnosticsTestWithEage doTest("compiler/testData/diagnostics/tests/inline/nonVirtualMembersWithInline.kt"); } + @TestMetadata("nothingToInline.kt") + public void testNothingToInline() throws Exception { + doTest("compiler/testData/diagnostics/tests/inline/nothingToInline.kt"); + } + @TestMetadata("propagation.kt") public void testPropagation() throws Exception { doTest("compiler/testData/diagnostics/tests/inline/propagation.kt");