[FIR] Unwrap error expressions when detecting USAGE_IS_NOT_INLINABLE

Otherwise, false positive USAGE_IS_NOT_INLINABLE may be detected

^KT-65316: Fixed
This commit is contained in:
vladislav.grechko
2024-01-26 15:03:13 +01:00
committed by Space Team
parent ed246d372b
commit cd5b38b958
9 changed files with 112 additions and 4 deletions
@@ -20638,6 +20638,12 @@ public class DiagnosticCompilerTestFE10TestdataTestGenerated extends AbstractDia
runTest("compiler/testData/diagnostics/tests/inline/labeled.kt");
}
@Test
@TestMetadata("labelsAndNonInlineUsage.kt")
public void testLabelsAndNonInlineUsage() throws Exception {
runTest("compiler/testData/diagnostics/tests/inline/labelsAndNonInlineUsage.kt");
}
@Test
@TestMetadata("lambdaCast.kt")
public void testLambdaCast() throws Exception {
@@ -20638,6 +20638,12 @@ public class LLFirPreresolvedReversedDiagnosticCompilerFE10TestDataTestGenerated
runTest("compiler/testData/diagnostics/tests/inline/labeled.kt");
}
@Test
@TestMetadata("labelsAndNonInlineUsage.kt")
public void testLabelsAndNonInlineUsage() throws Exception {
runTest("compiler/testData/diagnostics/tests/inline/labelsAndNonInlineUsage.kt");
}
@Test
@TestMetadata("lambdaCast.kt")
public void testLambdaCast() throws Exception {
@@ -20632,6 +20632,12 @@ public class FirLightTreeOldFrontendDiagnosticsTestGenerated extends AbstractFir
runTest("compiler/testData/diagnostics/tests/inline/labeled.kt");
}
@Test
@TestMetadata("labelsAndNonInlineUsage.kt")
public void testLabelsAndNonInlineUsage() throws Exception {
runTest("compiler/testData/diagnostics/tests/inline/labelsAndNonInlineUsage.kt");
}
@Test
@TestMetadata("lambdaCast.kt")
public void testLambdaCast() throws Exception {
@@ -20638,6 +20638,12 @@ public class FirPsiOldFrontendDiagnosticsTestGenerated extends AbstractFirPsiDia
runTest("compiler/testData/diagnostics/tests/inline/labeled.kt");
}
@Test
@TestMetadata("labelsAndNonInlineUsage.kt")
public void testLabelsAndNonInlineUsage() throws Exception {
runTest("compiler/testData/diagnostics/tests/inline/labelsAndNonInlineUsage.kt");
}
@Test
@TestMetadata("lambdaCast.kt")
public void testLambdaCast() throws Exception {
@@ -132,7 +132,7 @@ object FirInlineDeclarationChecker : FirFunctionChecker(MppCheckerKind.Common) {
val calledFunctionSymbol = targetSymbol as? FirFunctionSymbol ?: return
val argumentMapping = functionCall.resolvedArgumentMapping ?: return
for ((wrappedArgument, valueParameter) in argumentMapping) {
val argument = wrappedArgument.unwrapArgument()
val argument = wrappedArgument.unwrapErrorExpression()?.unwrapArgument() ?: continue
val resolvedArgumentSymbol = argument.toResolvedCallableSymbol(session) as? FirVariableSymbol<*> ?: continue
val valueParameterOfOriginalInlineFunction = inlinableParameters.firstOrNull { it == resolvedArgumentSymbol }
@@ -163,7 +163,8 @@ object FirInlineDeclarationChecker : FirFunctionChecker(MppCheckerKind.Common) {
reporter: DiagnosticReporter,
) {
if (receiverExpression == null) return
val receiverSymbol = receiverExpression.toResolvedCallableSymbol(session) as? FirValueParameterSymbol ?: return
val receiverSymbol =
receiverExpression.unwrapErrorExpression()?.toResolvedCallableSymbol(session) as? FirValueParameterSymbol ?: return
if (receiverSymbol in inlinableParameters) {
if (!isInvokeOrInlineExtension(targetSymbol)) {
reporter.reportOn(
@@ -217,9 +218,9 @@ object FirInlineDeclarationChecker : FirFunctionChecker(MppCheckerKind.Common) {
val containingQualifiedAccess = context.callsOrAssignments.getOrNull(
context.callsOrAssignments.size - 2
) ?: return false
if (this == (containingQualifiedAccess as? FirQualifiedAccessExpression)?.explicitReceiver) return true
if (this == (containingQualifiedAccess as? FirQualifiedAccessExpression)?.explicitReceiver?.unwrapErrorExpression()) return true
val call = containingQualifiedAccess as? FirCall ?: return false
return call.arguments.any { it.unwrapArgument() == this }
return call.arguments.any { it.unwrapErrorExpression()?.unwrapArgument() == this }
}
private fun checkVisibilityAndAccess(
@@ -101,6 +101,9 @@ fun <T : FirStatement> FirBlock.replaceFirstStatement(factory: (T) -> FirStateme
return existing
}
fun FirExpression.unwrapErrorExpression(): FirExpression? =
if (this is FirErrorExpression) expression?.run { unwrapErrorExpression() } else this
fun FirExpression.unwrapArgument(): FirExpression = (this as? FirWrappedArgumentExpression)?.expression ?: this
fun FirExpression.unwrapAndFlattenArgument(flattenArrays: Boolean): List<FirExpression> = buildList { unwrapAndFlattenArgumentTo(this, flattenArrays) }
@@ -0,0 +1,37 @@
// !DIAGNOSTICS: -REDUNDANT_LABEL_WARNING -UNDERSCORE_IS_RESERVED
// See KT-65337
// !DIAGNOSTICS: -UNRESOLVED_REFERENCE
// KT-65319
inline fun inline(s: () -> Unit) {}
fun noInline(s: () -> Unit) {}
inline fun bar(s: () -> Unit) {
inline(s)
noInline(<!USAGE_IS_NOT_INLINABLE!>s<!>)
inline(l@ s)
noInline(l@ <!USAGE_IS_NOT_INLINABLE!>s<!>)
inline(l2@ l1@ s)
noInline(l2@ l1@ <!USAGE_IS_NOT_INLINABLE!>s<!>)
inline(_@ s)
noInline(_@ <!USAGE_IS_NOT_INLINABLE!>s<!>)
inline(__@ _@ s)
noInline(__@ _@ <!USAGE_IS_NOT_INLINABLE!>s<!>)
s()
(l@ s)()
(l2@ l1@ s)()
(_@ s)()
(__@ _@ s)()
s.invoke()
(l@ s).invoke()
(l2@ l1@ s).invoke()
(_@ s).invoke()
(__@ _@ s).invoke()
}
@@ -0,0 +1,37 @@
// !DIAGNOSTICS: -REDUNDANT_LABEL_WARNING -UNDERSCORE_IS_RESERVED
// See KT-65337
// !DIAGNOSTICS: -UNRESOLVED_REFERENCE
// KT-65319
inline fun inline(s: () -> Unit) {}
fun noInline(s: () -> Unit) {}
inline fun bar(s: () -> Unit) {
inline(s)
noInline(<!USAGE_IS_NOT_INLINABLE!>s<!>)
inline(l@ s)
noInline(l@ s)
inline(l2@ l1@ s)
noInline(l2@ l1@ s)
inline(_@ s)
noInline(_@ s)
inline(__@ _@ s)
noInline(__@ _@ s)
s()
(l@ s)()
(l2@ l1@ s)()
(_@ s)()
(__@ _@ s)()
s.invoke()
(l@ s).invoke()
(l2@ l1@ s).invoke()
(_@ s).invoke()
(__@ _@ s).invoke()
}
@@ -20638,6 +20638,12 @@ public class DiagnosticTestGenerated extends AbstractDiagnosticTest {
runTest("compiler/testData/diagnostics/tests/inline/labeled.kt");
}
@Test
@TestMetadata("labelsAndNonInlineUsage.kt")
public void testLabelsAndNonInlineUsage() throws Exception {
runTest("compiler/testData/diagnostics/tests/inline/labelsAndNonInlineUsage.kt");
}
@Test
@TestMetadata("lambdaCast.kt")
public void testLambdaCast() throws Exception {