diff --git a/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/diagnostic/compiler/based/DiagnosticCompilerTestFE10TestdataTestGenerated.java b/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/diagnostic/compiler/based/DiagnosticCompilerTestFE10TestdataTestGenerated.java index 59982ce7c8d..4bd89816b3d 100644 --- a/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/diagnostic/compiler/based/DiagnosticCompilerTestFE10TestdataTestGenerated.java +++ b/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/diagnostic/compiler/based/DiagnosticCompilerTestFE10TestdataTestGenerated.java @@ -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 { diff --git a/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/diagnostic/compiler/based/LLFirPreresolvedReversedDiagnosticCompilerFE10TestDataTestGenerated.java b/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/diagnostic/compiler/based/LLFirPreresolvedReversedDiagnosticCompilerFE10TestDataTestGenerated.java index a040b392f9c..e2b7f4b9f6c 100644 --- a/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/diagnostic/compiler/based/LLFirPreresolvedReversedDiagnosticCompilerFE10TestDataTestGenerated.java +++ b/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/diagnostic/compiler/based/LLFirPreresolvedReversedDiagnosticCompilerFE10TestDataTestGenerated.java @@ -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 { diff --git a/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirLightTreeOldFrontendDiagnosticsTestGenerated.java b/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirLightTreeOldFrontendDiagnosticsTestGenerated.java index 91f85bbfbc4..e21f32a453d 100644 --- a/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirLightTreeOldFrontendDiagnosticsTestGenerated.java +++ b/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirLightTreeOldFrontendDiagnosticsTestGenerated.java @@ -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 { diff --git a/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirPsiOldFrontendDiagnosticsTestGenerated.java b/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirPsiOldFrontendDiagnosticsTestGenerated.java index cfbe1730ad0..dfa824a937d 100644 --- a/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirPsiOldFrontendDiagnosticsTestGenerated.java +++ b/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirPsiOldFrontendDiagnosticsTestGenerated.java @@ -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 { diff --git a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/declaration/FirInlineDeclarationChecker.kt b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/declaration/FirInlineDeclarationChecker.kt index 478e386198b..85c955447eb 100644 --- a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/declaration/FirInlineDeclarationChecker.kt +++ b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/declaration/FirInlineDeclarationChecker.kt @@ -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( diff --git a/compiler/fir/tree/src/org/jetbrains/kotlin/fir/expressions/FirExpressionUtil.kt b/compiler/fir/tree/src/org/jetbrains/kotlin/fir/expressions/FirExpressionUtil.kt index f0586027977..5f4ea5f60f3 100644 --- a/compiler/fir/tree/src/org/jetbrains/kotlin/fir/expressions/FirExpressionUtil.kt +++ b/compiler/fir/tree/src/org/jetbrains/kotlin/fir/expressions/FirExpressionUtil.kt @@ -101,6 +101,9 @@ fun 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 = buildList { unwrapAndFlattenArgumentTo(this, flattenArrays) } diff --git a/compiler/testData/diagnostics/tests/inline/labelsAndNonInlineUsage.fir.kt b/compiler/testData/diagnostics/tests/inline/labelsAndNonInlineUsage.fir.kt new file mode 100644 index 00000000000..3f4aba8cad5 --- /dev/null +++ b/compiler/testData/diagnostics/tests/inline/labelsAndNonInlineUsage.fir.kt @@ -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(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() +} diff --git a/compiler/testData/diagnostics/tests/inline/labelsAndNonInlineUsage.kt b/compiler/testData/diagnostics/tests/inline/labelsAndNonInlineUsage.kt new file mode 100644 index 00000000000..52d054200c9 --- /dev/null +++ b/compiler/testData/diagnostics/tests/inline/labelsAndNonInlineUsage.kt @@ -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(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() +} diff --git a/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/DiagnosticTestGenerated.java b/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/DiagnosticTestGenerated.java index 426977c1d02..654e1584b0c 100644 --- a/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/DiagnosticTestGenerated.java +++ b/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/DiagnosticTestGenerated.java @@ -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 {