K2: handle extra value parameter in FirCallCompleter properly

#KT-60450 Fixed
This commit is contained in:
Mikhail Glukhikh
2023-08-25 18:06:58 +02:00
committed by Space Team
parent 0068a3f6b8
commit 6ce096f0ed
7 changed files with 60 additions and 0 deletions
@@ -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 {
@@ -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 {
@@ -0,0 +1,12 @@
FILE: forEachOnZip.kt
public final fun main(): R|kotlin/Unit| {
lval l: R|kotlin/collections/List<kotlin/String>| = R|kotlin/collections/listOf|<R|kotlin/String|>()
R|<local>/l|.R|kotlin/collections/zip|<R|kotlin/String|, R|kotlin/String|>(R|<local>/l|).R|kotlin/collections/forEach|<R|kotlin/Pair<kotlin/String, kotlin/String>|>(<L> = forEach@fun <anonymous>(left: R|kotlin/Pair<kotlin/String, kotlin/String>|, right: <ERROR TYPE REF: Lambda or anonymous function has more parameters than expected>): R|kotlin/Unit| <inline=Inline, kind=UNKNOWN> {
^@forEach Unit
}
)
R|<local>/l|.R|kotlin/collections/zip|<R|kotlin/String|, R|kotlin/String|>(R|<local>/l|).R|kotlin/collections/forEach<Inapplicable(INAPPLICABLE): kotlin/collections/forEach>#|<R|kotlin/Pair<kotlin/String, kotlin/String>|>(<L> = forEach@fun <anonymous>(left: R|kotlin/Pair<kotlin/String, kotlin/String>|, right: <ERROR TYPE REF: Cannot infer type for parameter right>): R|kotlin/Unit| <inline=Unknown, kind=UNKNOWN> {
^@forEach Unit
}
)
}
@@ -0,0 +1,10 @@
// ISSUE: KT-60450
fun main() {
val l = listOf<String>()
l.zip(l).forEach { left, <!CANNOT_INFER_PARAMETER_TYPE!>right<!><!SYNTAX!><!>
}
l.zip(l).forEach <!ARGUMENT_TYPE_MISMATCH!>{ left, <!CANNOT_INFER_PARAMETER_TYPE!>right<!> ->
}<!>
}
@@ -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 {
@@ -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 {
@@ -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))