diff --git a/idea/src/org/jetbrains/kotlin/idea/inspections/UnusedSymbolInspection.kt b/idea/src/org/jetbrains/kotlin/idea/inspections/UnusedSymbolInspection.kt
index c6263179634..f92ac9fb866 100644
--- a/idea/src/org/jetbrains/kotlin/idea/inspections/UnusedSymbolInspection.kt
+++ b/idea/src/org/jetbrains/kotlin/idea/inspections/UnusedSymbolInspection.kt
@@ -67,6 +67,7 @@ import org.jetbrains.kotlin.psi.psiUtil.*
import org.jetbrains.kotlin.resolve.BindingContext
import org.jetbrains.kotlin.resolve.DescriptorUtils
import org.jetbrains.kotlin.resolve.descriptorUtil.fqNameSafe
+import org.jetbrains.kotlin.resolve.isInlineClassType
import org.jetbrains.kotlin.util.findCallableMemberBySignature
import java.awt.GridBagConstraints
import java.awt.GridBagLayout
@@ -309,7 +310,7 @@ class UnusedSymbolInspection : AbstractKotlinInspection() {
if (referenceUsed) return true
}
- if (declaration is KtCallableDeclaration && !declaration.hasModifier(KtTokens.INTERNAL_KEYWORD)) {
+ if (declaration is KtCallableDeclaration && declaration.canBeHandledByLightMethods(descriptor)) {
val lightMethods = declaration.toLightMethods()
if (lightMethods.isNotEmpty()) {
val lightMethodsUsed = lightMethods.any { method ->
@@ -323,6 +324,24 @@ class UnusedSymbolInspection : AbstractKotlinInspection() {
return referenceUsed
}
+ private fun KtCallableDeclaration.canBeHandledByLightMethods(descriptor: DeclarationDescriptor?): Boolean {
+ return when {
+ hasModifier(KtTokens.INTERNAL_KEYWORD) -> false
+ this !is KtNamedFunction -> true
+ descriptor !is FunctionDescriptor -> true
+ else -> !descriptor.hasInlineClassParameters()
+ }
+
+ }
+
+ private fun FunctionDescriptor.hasInlineClassParameters(): Boolean {
+ return when {
+ dispatchReceiverParameter?.type?.isInlineClassType() == true -> true
+ extensionReceiverParameter?.type?.isInlineClassType() == true -> true
+ else -> valueParameters.any { it.type.isInlineClassType() }
+ }
+ }
+
private fun hasOverrides(declaration: KtNamedDeclaration, useScope: SearchScope): Boolean =
DefinitionsScopedSearch.search(declaration, useScope).findFirst() != null
diff --git a/idea/testData/inspections/unusedSymbol/function/functionWithInlineClassParam.kt b/idea/testData/inspections/unusedSymbol/function/functionWithInlineClassParam.kt
new file mode 100644
index 00000000000..61e229254ca
--- /dev/null
+++ b/idea/testData/inspections/unusedSymbol/function/functionWithInlineClassParam.kt
@@ -0,0 +1,6 @@
+inline class InlineClass(val x: Int)
+
+// Unused
+fun foo(arg: InlineClass) {
+ arg.x.hashCode()
+}
\ No newline at end of file
diff --git a/idea/testData/inspections/unusedSymbol/function/inspectionData/expected.xml b/idea/testData/inspections/unusedSymbol/function/inspectionData/expected.xml
index 5051e4dc54a..c8de5ceba0b 100644
--- a/idea/testData/inspections/unusedSymbol/function/inspectionData/expected.xml
+++ b/idea/testData/inspections/unusedSymbol/function/inspectionData/expected.xml
@@ -78,4 +78,13 @@
Unused symbol
Constructor is never used
+
+
+ functionWithInlineClassParam.kt
+ 4
+ light_idea_test_case
+
+ Unused symbol
+ Function "foo" is never used
+
diff --git a/idea/testData/inspectionsLocal/unusedSymbol/functionWithInlineClass.kt b/idea/testData/inspectionsLocal/unusedSymbol/functionWithInlineClass.kt
new file mode 100644
index 00000000000..7ff5e2f344b
--- /dev/null
+++ b/idea/testData/inspectionsLocal/unusedSymbol/functionWithInlineClass.kt
@@ -0,0 +1,7 @@
+// PROBLEM: none
+
+inline class InlineClass(val x: Int)
+
+fun takeInline(inlineClass: InlineClass) = 1
+
+val call = takeInline(InlineClass(1))
\ No newline at end of file
diff --git a/idea/testData/inspectionsLocal/unusedSymbol/functionWithInlineClassReceiver.kt b/idea/testData/inspectionsLocal/unusedSymbol/functionWithInlineClassReceiver.kt
new file mode 100644
index 00000000000..dbdc1920805
--- /dev/null
+++ b/idea/testData/inspectionsLocal/unusedSymbol/functionWithInlineClassReceiver.kt
@@ -0,0 +1,7 @@
+// PROBLEM: none
+
+inline class InlineClass(val x: Int)
+
+fun InlineClass.takeInline() = 1
+
+val call = InlineClass(1).takeInline()
\ No newline at end of file
diff --git a/idea/testData/inspectionsLocal/unusedSymbol/inlineClassMemberFunction.kt b/idea/testData/inspectionsLocal/unusedSymbol/inlineClassMemberFunction.kt
new file mode 100644
index 00000000000..3946f1be277
--- /dev/null
+++ b/idea/testData/inspectionsLocal/unusedSymbol/inlineClassMemberFunction.kt
@@ -0,0 +1,7 @@
+// PROBLEM: none
+
+inline class InlineClass(val x: Int) {
+ fun takeInline() = 1
+}
+
+val call = InlineClass(1).takeInline()
\ No newline at end of file
diff --git a/idea/tests/org/jetbrains/kotlin/idea/inspections/LocalInspectionTestGenerated.java b/idea/tests/org/jetbrains/kotlin/idea/inspections/LocalInspectionTestGenerated.java
index 6f67ab77377..772631e6965 100644
--- a/idea/tests/org/jetbrains/kotlin/idea/inspections/LocalInspectionTestGenerated.java
+++ b/idea/tests/org/jetbrains/kotlin/idea/inspections/LocalInspectionTestGenerated.java
@@ -6377,6 +6377,16 @@ public class LocalInspectionTestGenerated extends AbstractLocalInspectionTest {
runTest("idea/testData/inspectionsLocal/unusedSymbol/dataInlineClassDeclaration.kt");
}
+ @TestMetadata("functionWithInlineClass.kt")
+ public void testFunctionWithInlineClass() throws Exception {
+ runTest("idea/testData/inspectionsLocal/unusedSymbol/functionWithInlineClass.kt");
+ }
+
+ @TestMetadata("functionWithInlineClassReceiver.kt")
+ public void testFunctionWithInlineClassReceiver() throws Exception {
+ runTest("idea/testData/inspectionsLocal/unusedSymbol/functionWithInlineClassReceiver.kt");
+ }
+
@TestMetadata("inAnonymous.kt")
public void testInAnonymous() throws Exception {
runTest("idea/testData/inspectionsLocal/unusedSymbol/inAnonymous.kt");
@@ -6392,6 +6402,11 @@ public class LocalInspectionTestGenerated extends AbstractLocalInspectionTest {
runTest("idea/testData/inspectionsLocal/unusedSymbol/inAnonymousRunWrapped.kt");
}
+ @TestMetadata("inlineClassMemberFunction.kt")
+ public void testInlineClassMemberFunction() throws Exception {
+ runTest("idea/testData/inspectionsLocal/unusedSymbol/inlineClassMemberFunction.kt");
+ }
+
@TestMetadata("internal.kt")
public void testInternal() throws Exception {
runTest("idea/testData/inspectionsLocal/unusedSymbol/internal.kt");