From 6ce096f0ed4f0f52cf5ddf71b5047f6fef239f6f Mon Sep 17 00:00:00 2001 From: Mikhail Glukhikh Date: Fri, 25 Aug 2023 18:06:58 +0200 Subject: [PATCH] K2: handle extra value parameter in FirCallCompleter properly #KT-60450 Fixed --- ...nosticCompilerTestFirTestdataTestGenerated.java | 6 ++++++ ...DiagnosticCompilerFirTestDataTestGenerated.java | 6 ++++++ .../problems/forEachOnZip.fir.txt | 12 ++++++++++++ .../resolveWithStdlib/problems/forEachOnZip.kt | 10 ++++++++++ .../FirLightTreeDiagnosticsTestGenerated.java | 6 ++++++ .../runners/FirPsiDiagnosticTestGenerated.java | 6 ++++++ .../fir/resolve/inference/FirCallCompleter.kt | 14 ++++++++++++++ 7 files changed, 60 insertions(+) create mode 100644 compiler/fir/analysis-tests/testData/resolveWithStdlib/problems/forEachOnZip.fir.txt create mode 100644 compiler/fir/analysis-tests/testData/resolveWithStdlib/problems/forEachOnZip.kt diff --git a/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/diagnostic/compiler/based/DiagnosticCompilerTestFirTestdataTestGenerated.java b/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/diagnostic/compiler/based/DiagnosticCompilerTestFirTestdataTestGenerated.java index a1f98cbd6ed..6775378c357 100644 --- a/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/diagnostic/compiler/based/DiagnosticCompilerTestFirTestdataTestGenerated.java +++ b/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/diagnostic/compiler/based/DiagnosticCompilerTestFirTestdataTestGenerated.java @@ -6855,6 +6855,12 @@ public class DiagnosticCompilerTestFirTestdataTestGenerated extends AbstractDiag runTest("compiler/fir/analysis-tests/testData/resolveWithStdlib/problems/FieldAnnotationWithClasses.kt"); } + @Test + @TestMetadata("forEachOnZip.kt") + public void testForEachOnZip() throws Exception { + runTest("compiler/fir/analysis-tests/testData/resolveWithStdlib/problems/forEachOnZip.kt"); + } + @Test @TestMetadata("immutableName.kt") public void testImmutableName() throws Exception { diff --git a/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/diagnostic/compiler/based/LLFirPreresolvedReversedDiagnosticCompilerFirTestDataTestGenerated.java b/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/diagnostic/compiler/based/LLFirPreresolvedReversedDiagnosticCompilerFirTestDataTestGenerated.java index b9cbb3ec23e..2365129b6d9 100644 --- a/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/diagnostic/compiler/based/LLFirPreresolvedReversedDiagnosticCompilerFirTestDataTestGenerated.java +++ b/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/diagnostic/compiler/based/LLFirPreresolvedReversedDiagnosticCompilerFirTestDataTestGenerated.java @@ -6855,6 +6855,12 @@ public class LLFirPreresolvedReversedDiagnosticCompilerFirTestDataTestGenerated runTest("compiler/fir/analysis-tests/testData/resolveWithStdlib/problems/FieldAnnotationWithClasses.kt"); } + @Test + @TestMetadata("forEachOnZip.kt") + public void testForEachOnZip() throws Exception { + runTest("compiler/fir/analysis-tests/testData/resolveWithStdlib/problems/forEachOnZip.kt"); + } + @Test @TestMetadata("immutableName.kt") public void testImmutableName() throws Exception { diff --git a/compiler/fir/analysis-tests/testData/resolveWithStdlib/problems/forEachOnZip.fir.txt b/compiler/fir/analysis-tests/testData/resolveWithStdlib/problems/forEachOnZip.fir.txt new file mode 100644 index 00000000000..86f410eff43 --- /dev/null +++ b/compiler/fir/analysis-tests/testData/resolveWithStdlib/problems/forEachOnZip.fir.txt @@ -0,0 +1,12 @@ +FILE: forEachOnZip.kt + public final fun main(): R|kotlin/Unit| { + lval l: R|kotlin/collections/List| = R|kotlin/collections/listOf|() + R|/l|.R|kotlin/collections/zip|(R|/l|).R|kotlin/collections/forEach||>( = forEach@fun (left: R|kotlin/Pair|, right: ): R|kotlin/Unit| { + ^@forEach Unit + } + ) + R|/l|.R|kotlin/collections/zip|(R|/l|).R|kotlin/collections/forEach#||>( = forEach@fun (left: R|kotlin/Pair|, right: ): R|kotlin/Unit| { + ^@forEach Unit + } + ) + } diff --git a/compiler/fir/analysis-tests/testData/resolveWithStdlib/problems/forEachOnZip.kt b/compiler/fir/analysis-tests/testData/resolveWithStdlib/problems/forEachOnZip.kt new file mode 100644 index 00000000000..2ce0e2e872b --- /dev/null +++ b/compiler/fir/analysis-tests/testData/resolveWithStdlib/problems/forEachOnZip.kt @@ -0,0 +1,10 @@ +// ISSUE: KT-60450 +fun main() { + val l = listOf() + l.zip(l).forEach { left, right + + } + l.zip(l).forEach { left, right -> + + } +} diff --git a/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirLightTreeDiagnosticsTestGenerated.java b/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirLightTreeDiagnosticsTestGenerated.java index e266026b964..d2c6df82881 100644 --- a/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirLightTreeDiagnosticsTestGenerated.java +++ b/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirLightTreeDiagnosticsTestGenerated.java @@ -6855,6 +6855,12 @@ public class FirLightTreeDiagnosticsTestGenerated extends AbstractFirLightTreeDi runTest("compiler/fir/analysis-tests/testData/resolveWithStdlib/problems/FieldAnnotationWithClasses.kt"); } + @Test + @TestMetadata("forEachOnZip.kt") + public void testForEachOnZip() throws Exception { + runTest("compiler/fir/analysis-tests/testData/resolveWithStdlib/problems/forEachOnZip.kt"); + } + @Test @TestMetadata("immutableName.kt") public void testImmutableName() throws Exception { diff --git a/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirPsiDiagnosticTestGenerated.java b/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirPsiDiagnosticTestGenerated.java index dc1a257dea6..9b6fd123255 100644 --- a/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirPsiDiagnosticTestGenerated.java +++ b/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirPsiDiagnosticTestGenerated.java @@ -6855,6 +6855,12 @@ public class FirPsiDiagnosticTestGenerated extends AbstractFirPsiDiagnosticTest runTest("compiler/fir/analysis-tests/testData/resolveWithStdlib/problems/FieldAnnotationWithClasses.kt"); } + @Test + @TestMetadata("forEachOnZip.kt") + public void testForEachOnZip() throws Exception { + runTest("compiler/fir/analysis-tests/testData/resolveWithStdlib/problems/forEachOnZip.kt"); + } + @Test @TestMetadata("immutableName.kt") public void testImmutableName() throws Exception { diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/inference/FirCallCompleter.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/inference/FirCallCompleter.kt index 23a501640be..b16e720a8ae 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/inference/FirCallCompleter.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/inference/FirCallCompleter.kt @@ -32,6 +32,7 @@ import org.jetbrains.kotlin.fir.resolve.transformers.replaceLambdaArgumentInvoca import org.jetbrains.kotlin.fir.resolve.typeFromCallee import org.jetbrains.kotlin.fir.symbols.impl.FirValueParameterSymbol import org.jetbrains.kotlin.fir.types.* +import org.jetbrains.kotlin.fir.types.builder.buildErrorTypeRef import org.jetbrains.kotlin.fir.types.builder.buildResolvedTypeRef import org.jetbrains.kotlin.fir.types.impl.ConeClassLikeTypeImpl import org.jetbrains.kotlin.fir.visitors.transformSingle @@ -314,6 +315,19 @@ class FirCallCompleter( else -> parameters } lambdaArgument.valueParameters.forEachIndexed { index, parameter -> + if (index >= theParameters.size) { + // May happen in erroneous code, see KT-60450 + // In test forEachOnZip.kt we have two declared parameters, but in fact forEach expects only one + parameter.replaceReturnTypeRef( + buildErrorTypeRef { + diagnostic = ConeCannotInferValueParameterType( + parameter.symbol, "Lambda or anonymous function has more parameters than expected" + ) + source = parameter.source + } + ) + return@forEachIndexed + } val newReturnType = theParameters[index].approximateLambdaInputType(parameter.symbol) val newReturnTypeRef = if (parameter.returnTypeRef is FirImplicitTypeRef) { newReturnType.toFirResolvedTypeRef(parameter.source?.fakeElement(KtFakeSourceElementKind.ImplicitReturnTypeOfLambdaValueParameter))