From eec039f5a26a790213bea0c4ab2c0d8191b71d64 Mon Sep 17 00:00:00 2001 From: Pavel Kirpichenkov Date: Fri, 24 Jan 2020 19:16:11 +0300 Subject: [PATCH] [NI] Report error about unknown parameter type of lambda argument KT-34335 --- ...irOldFrontendDiagnosticsTestGenerated.java | 10 +++++ .../DelegatedPropertyInferenceSession.kt | 6 ++- .../DiagnosticReporterByTrackingStrategy.kt | 14 +++++++ .../inference/CoroutineInferenceSession.kt | 6 ++- .../calls/tower/ManyCandidatesResolver.kt | 3 +- .../calls/components/InferenceSession.kt | 10 ++++- .../calls/components/KotlinCallCompleter.kt | 3 +- .../components/PostponeArgumentsChecks.kt | 20 +++++++-- .../components/PostponedArgumentsAnalyzer.kt | 4 +- .../KotlinConstraintSystemCompleter.kt | 41 ++++++++++++++++--- .../calls/model/KotlinCallDiagnostics.kt | 9 ++++ ...tionalExpectedTypeForLambdaArgument.fir.kt | 36 ++++++++++++++++ ...FunctionalExpectedTypeForLambdaArgument.kt | 36 ++++++++++++++++ ...unctionalExpectedTypeForLambdaArgument.txt | 9 ++++ .../inference/nothingType/kt34335.fir.kt | 19 +++++++++ .../tests/inference/nothingType/kt34335.kt | 19 +++++++++ .../tests/inference/nothingType/kt34335.txt | 8 ++++ .../FunctionPlaceholder.kt | 2 +- ...AdapterBecuaseOfRecursiveUpperBound.fir.kt | 1 - .../noAdapterBecuaseOfRecursiveUpperBound.kt | 5 +-- .../diagnostics/tests/regressions/kt10843.kt | 4 +- .../tests/resolve/newLineLambda.kt | 2 +- .../resolve/overloadConflicts/allLambdas.kt | 2 +- .../checkers/DiagnosticsTestGenerated.java | 10 +++++ .../DiagnosticsUsingJavacTestGenerated.java | 10 +++++ 25 files changed, 260 insertions(+), 29 deletions(-) create mode 100644 compiler/testData/diagnostics/tests/inference/nonFunctionalExpectedTypeForLambdaArgument.fir.kt create mode 100644 compiler/testData/diagnostics/tests/inference/nonFunctionalExpectedTypeForLambdaArgument.kt create mode 100644 compiler/testData/diagnostics/tests/inference/nonFunctionalExpectedTypeForLambdaArgument.txt create mode 100644 compiler/testData/diagnostics/tests/inference/nothingType/kt34335.fir.kt create mode 100644 compiler/testData/diagnostics/tests/inference/nothingType/kt34335.kt create mode 100644 compiler/testData/diagnostics/tests/inference/nothingType/kt34335.txt diff --git a/compiler/fir/resolve/tests/org/jetbrains/kotlin/fir/FirOldFrontendDiagnosticsTestGenerated.java b/compiler/fir/resolve/tests/org/jetbrains/kotlin/fir/FirOldFrontendDiagnosticsTestGenerated.java index 0f7c21a9820..fed9c47f203 100644 --- a/compiler/fir/resolve/tests/org/jetbrains/kotlin/fir/FirOldFrontendDiagnosticsTestGenerated.java +++ b/compiler/fir/resolve/tests/org/jetbrains/kotlin/fir/FirOldFrontendDiagnosticsTestGenerated.java @@ -10126,6 +10126,11 @@ public class FirOldFrontendDiagnosticsTestGenerated extends AbstractFirOldFronte runTest("compiler/testData/diagnostics/tests/inference/noInformationForParameter.kt"); } + @TestMetadata("nonFunctionalExpectedTypeForLambdaArgument.kt") + public void testNonFunctionalExpectedTypeForLambdaArgument() throws Exception { + runTest("compiler/testData/diagnostics/tests/inference/nonFunctionalExpectedTypeForLambdaArgument.kt"); + } + @TestMetadata("nullableTypeArgumentWithNotNullUpperBound.kt") public void testNullableTypeArgumentWithNotNullUpperBound() throws Exception { runTest("compiler/testData/diagnostics/tests/inference/nullableTypeArgumentWithNotNullUpperBound.kt"); @@ -10901,6 +10906,11 @@ public class FirOldFrontendDiagnosticsTestGenerated extends AbstractFirOldFronte runTest("compiler/testData/diagnostics/tests/inference/nothingType/kt32388.kt"); } + @TestMetadata("kt34335.kt") + public void testKt34335() throws Exception { + runTest("compiler/testData/diagnostics/tests/inference/nothingType/kt34335.kt"); + } + @TestMetadata("lambdaNothingAndExpectedType.kt") public void testLambdaNothingAndExpectedType() throws Exception { runTest("compiler/testData/diagnostics/tests/inference/nothingType/lambdaNothingAndExpectedType.kt"); diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/DelegatedPropertyInferenceSession.kt b/compiler/frontend/src/org/jetbrains/kotlin/resolve/DelegatedPropertyInferenceSession.kt index aa3c09be762..b2a69e6287a 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/DelegatedPropertyInferenceSession.kt +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/DelegatedPropertyInferenceSession.kt @@ -81,7 +81,8 @@ class DelegatedPropertyInferenceSession( override fun inferPostponedVariables( lambda: ResolvedLambdaAtom, - initialStorage: ConstraintStorage + initialStorage: ConstraintStorage, + diagnosticsHolder: KotlinDiagnosticsHolder ): Map = emptyMap() override fun writeOnlyStubs(callInfo: SingleCallResolutionResult): Boolean = false @@ -101,7 +102,8 @@ object InferenceSessionForExistingCandidates : InferenceSession { override fun currentConstraintSystem(): ConstraintStorage = ConstraintStorage.Empty override fun inferPostponedVariables( lambda: ResolvedLambdaAtom, - initialStorage: ConstraintStorage + initialStorage: ConstraintStorage, + diagnosticsHolder: KotlinDiagnosticsHolder ): Map = emptyMap() override fun writeOnlyStubs(callInfo: SingleCallResolutionResult): Boolean = false diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/DiagnosticReporterByTrackingStrategy.kt b/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/DiagnosticReporterByTrackingStrategy.kt index c636e8483c0..12212c1991b 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/DiagnosticReporterByTrackingStrategy.kt +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/DiagnosticReporterByTrackingStrategy.kt @@ -182,6 +182,20 @@ class DiagnosticReporterByTrackingStrategy( ResolvedToSamWithVarargDiagnostic::class.java -> { trace.report(TYPE_INFERENCE_CANDIDATE_WITH_SAM_AND_VARARG.on(callArgument.psiCallArgument.valueArgument.asElement())) } + + NotEnoughInformationForLambdaParameter::class.java -> { + val unknownParameterTypeDiagnostic = diagnostic as NotEnoughInformationForLambdaParameter + val lambdaArgument = unknownParameterTypeDiagnostic.lambdaArgument + val parameterIndex = unknownParameterTypeDiagnostic.parameterIndex + + val argumentExpression = KtPsiUtil.deparenthesize(lambdaArgument.psiCallArgument.valueArgument.getArgumentExpression()) + if (argumentExpression !is KtLambdaExpression) return + + val parameter = argumentExpression.valueParameters.getOrNull(parameterIndex) + reportIfNonNull(parameter) { + trace.report(CANNOT_INFER_PARAMETER_TYPE.on(it)) + } + } } } diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/inference/CoroutineInferenceSession.kt b/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/inference/CoroutineInferenceSession.kt index 5697da05623..b01a224789c 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/inference/CoroutineInferenceSession.kt +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/inference/CoroutineInferenceSession.kt @@ -102,7 +102,8 @@ class CoroutineInferenceSession( override fun inferPostponedVariables( lambda: ResolvedLambdaAtom, - initialStorage: ConstraintStorage + initialStorage: ConstraintStorage, + diagnosticsHolder: KotlinDiagnosticsHolder ): Map { val commonSystem = buildCommonSystem(initialStorage) @@ -110,7 +111,8 @@ class CoroutineInferenceSession( kotlinConstraintSystemCompleter.completeConstraintSystem( context, builtIns.unitType, - partiallyResolvedCallsInfo.map { it.callResolutionResult.resultCallAtom } + partiallyResolvedCallsInfo.map { it.callResolutionResult.resultCallAtom }, + diagnosticsHolder ) updateCalls(lambda, commonSystem) diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/tower/ManyCandidatesResolver.kt b/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/tower/ManyCandidatesResolver.kt index 8b4d58744a0..57814c28f2d 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/tower/ManyCandidatesResolver.kt +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/tower/ManyCandidatesResolver.kt @@ -85,7 +85,8 @@ abstract class ManyCandidatesResolver( constraintSystem.asConstraintSystemCompleterContext(), KotlinConstraintSystemCompleter.ConstraintSystemCompletionMode.FULL, atoms, - builtIns.unitType + builtIns.unitType, + diagnosticHolder ) { postponedArgumentsAnalyzer.analyze( constraintSystem.asPostponedArgumentsAnalyzerContext(), resolutionCallbacks, it, diagnosticHolder diff --git a/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/components/InferenceSession.kt b/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/components/InferenceSession.kt index 9f3a75dba05..95f1c53b96e 100644 --- a/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/components/InferenceSession.kt +++ b/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/components/InferenceSession.kt @@ -21,7 +21,8 @@ interface InferenceSession { override fun currentConstraintSystem(): ConstraintStorage = ConstraintStorage.Empty override fun inferPostponedVariables( lambda: ResolvedLambdaAtom, - initialStorage: ConstraintStorage + initialStorage: ConstraintStorage, + diagnosticsHolder: KotlinDiagnosticsHolder ): Map = emptyMap() override fun writeOnlyStubs(callInfo: SingleCallResolutionResult): Boolean = false @@ -35,7 +36,12 @@ interface InferenceSession { fun addCompletedCallInfo(callInfo: CompletedCallInfo) fun addErrorCallInfo(callInfo: ErrorCallInfo) fun currentConstraintSystem(): ConstraintStorage - fun inferPostponedVariables(lambda: ResolvedLambdaAtom, initialStorage: ConstraintStorage): Map + fun inferPostponedVariables( + lambda: ResolvedLambdaAtom, + initialStorage: ConstraintStorage, + diagnosticsHolder: KotlinDiagnosticsHolder + ): Map + fun writeOnlyStubs(callInfo: SingleCallResolutionResult): Boolean fun callCompleted(resolvedAtom: ResolvedAtom): Boolean fun shouldCompleteResolvedSubAtomsOf(resolvedCallAtom: ResolvedCallAtom): Boolean diff --git a/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/components/KotlinCallCompleter.kt b/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/components/KotlinCallCompleter.kt index 31b963f0323..e8c8b52ef8a 100644 --- a/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/components/KotlinCallCompleter.kt +++ b/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/components/KotlinCallCompleter.kt @@ -131,7 +131,8 @@ class KotlinCallCompleter( constraintSystem.asConstraintSystemCompleterContext(), completionMode, listOf(resolvedCallAtom), - returnType + returnType, + diagnosticsHolder ) { if (collectAllCandidatesMode) { it.setEmptyAnalyzedResults() diff --git a/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/components/PostponeArgumentsChecks.kt b/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/components/PostponeArgumentsChecks.kt index 90bd58a8ab9..e1296e108ed 100644 --- a/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/components/PostponeArgumentsChecks.kt +++ b/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/components/PostponeArgumentsChecks.kt @@ -24,6 +24,7 @@ import org.jetbrains.kotlin.resolve.calls.inference.model.ArgumentConstraintPosi import org.jetbrains.kotlin.resolve.calls.inference.model.LHSArgumentConstraintPosition import org.jetbrains.kotlin.resolve.calls.inference.model.TypeVariableForLambdaReturnType import org.jetbrains.kotlin.resolve.calls.model.* +import org.jetbrains.kotlin.types.ErrorUtils import org.jetbrains.kotlin.types.UnwrappedType import org.jetbrains.kotlin.types.Variance import org.jetbrains.kotlin.types.typeUtil.builtIns @@ -40,7 +41,7 @@ fun resolveKtPrimitive( checkSimpleArgument(csBuilder, argument, expectedType, diagnosticsHolder, isReceiver) is LambdaKotlinCallArgument -> - preprocessLambdaArgument(csBuilder, argument, expectedType) + preprocessLambdaArgument(csBuilder, argument, expectedType, diagnosticsHolder) is CallableReferenceKotlinCallArgument -> preprocessCallableReference(csBuilder, argument, expectedType, diagnosticsHolder) @@ -57,6 +58,7 @@ private fun preprocessLambdaArgument( csBuilder: ConstraintSystemBuilder, argument: LambdaKotlinCallArgument, expectedType: UnwrappedType?, + diagnosticsHolder: KotlinDiagnosticsHolder, forceResolution: Boolean = false, returnTypeVariable: TypeVariableForLambdaReturnType? = null ): ResolvedAtom { @@ -65,7 +67,7 @@ private fun preprocessLambdaArgument( } val resolvedArgument = extractLambdaInfoFromFunctionalType(expectedType, argument, returnTypeVariable) - ?: extraLambdaInfo(expectedType, argument, csBuilder) + ?: extraLambdaInfo(expectedType, argument, csBuilder, diagnosticsHolder) if (expectedType != null) { val lambdaType = createFunctionType( @@ -81,7 +83,8 @@ private fun preprocessLambdaArgument( private fun extraLambdaInfo( expectedType: UnwrappedType?, argument: LambdaKotlinCallArgument, - csBuilder: ConstraintSystemBuilder + csBuilder: ConstraintSystemBuilder, + diagnosticsHolder: KotlinDiagnosticsHolder ): ResolvedLambdaAtom { val builtIns = csBuilder.builtIns val isSuspend = expectedType?.isSuspendFunctionType ?: false @@ -96,7 +99,14 @@ private fun extraLambdaInfo( argumentAsFunctionExpression?.returnType ?: expectedType?.arguments?.singleOrNull()?.type?.unwrap()?.takeIf { isFunctionSupertype } ?: typeVariable.defaultType - val parameters = argument.parametersTypes?.map { it ?: builtIns.nothingType } ?: emptyList() + val parameters = argument.parametersTypes?.mapIndexed { index, parameterType -> + if (parameterType != null) { + parameterType + } else { + diagnosticsHolder.addDiagnostic(NotEnoughInformationForLambdaParameter(argument, index)) + ErrorUtils.createErrorType("") + } + } ?: emptyList() val newTypeVariableUsed = returnType == typeVariable.defaultType if (newTypeVariableUsed) csBuilder.registerVariable(typeVariable) @@ -177,6 +187,7 @@ private fun extractLambdaInfoFromFunctionalType( fun LambdaWithTypeVariableAsExpectedTypeAtom.transformToResolvedLambda( csBuilder: ConstraintSystemBuilder, + diagnosticsHolder: KotlinDiagnosticsHolder, expectedType: UnwrappedType? = null, returnTypeVariable: TypeVariableForLambdaReturnType? = null ): ResolvedLambdaAtom { @@ -186,6 +197,7 @@ fun LambdaWithTypeVariableAsExpectedTypeAtom.transformToResolvedLambda( csBuilder, atom, fixedExpectedType, + diagnosticsHolder, forceResolution = true, returnTypeVariable = returnTypeVariable ) as ResolvedLambdaAtom diff --git a/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/components/PostponedArgumentsAnalyzer.kt b/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/components/PostponedArgumentsAnalyzer.kt index b31a2df94bc..12e5fbc810a 100644 --- a/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/components/PostponedArgumentsAnalyzer.kt +++ b/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/components/PostponedArgumentsAnalyzer.kt @@ -51,7 +51,7 @@ class PostponedArgumentsAnalyzer( is LambdaWithTypeVariableAsExpectedTypeAtom -> analyzeLambda( - c, resolutionCallbacks, argument.transformToResolvedLambda(c.getBuilder()), diagnosticsHolder + c, resolutionCallbacks, argument.transformToResolvedLambda(c.getBuilder(), diagnosticsHolder), diagnosticsHolder ) is ResolvedCallableReferenceAtom -> @@ -147,7 +147,7 @@ class PostponedArgumentsAnalyzer( if (inferenceSession != null) { val storageSnapshot = c.getBuilder().currentStorage() - val postponedVariables = inferenceSession.inferPostponedVariables(lambda, storageSnapshot) + val postponedVariables = inferenceSession.inferPostponedVariables(lambda, storageSnapshot, diagnosticHolder) for ((constructor, resultType) in postponedVariables) { val variableWithConstraints = storageSnapshot.notFixedTypeVariables[constructor] ?: continue diff --git a/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/inference/components/KotlinConstraintSystemCompleter.kt b/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/inference/components/KotlinConstraintSystemCompleter.kt index a72df3e662d..41b87963266 100644 --- a/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/inference/components/KotlinConstraintSystemCompleter.kt +++ b/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/inference/components/KotlinConstraintSystemCompleter.kt @@ -49,13 +49,34 @@ class KotlinConstraintSystemCompleter( completionMode: ConstraintSystemCompletionMode, topLevelAtoms: List, topLevelType: UnwrappedType, + diagnosticsHolder: KotlinDiagnosticsHolder, analyze: (PostponedResolvedAtom) -> Unit ) { - runCompletion(c, completionMode, topLevelAtoms, topLevelType, collectVariablesFromContext = false, analyze = analyze) + runCompletion( + c, + completionMode, + topLevelAtoms, + topLevelType, + diagnosticsHolder, + collectVariablesFromContext = false, + analyze = analyze + ) } - fun completeConstraintSystem(c: Context, topLevelType: UnwrappedType, topLevelAtoms: List) { - runCompletion(c, ConstraintSystemCompletionMode.FULL, topLevelAtoms, topLevelType, collectVariablesFromContext = true) { + fun completeConstraintSystem( + c: Context, + topLevelType: UnwrappedType, + topLevelAtoms: List, + diagnosticsHolder: KotlinDiagnosticsHolder + ) { + runCompletion( + c, + ConstraintSystemCompletionMode.FULL, + topLevelAtoms, + topLevelType, + diagnosticsHolder, + collectVariablesFromContext = true, + ) { error("Shouldn't be called in complete constraint system mode") } } @@ -65,6 +86,7 @@ class KotlinConstraintSystemCompleter( completionMode: ConstraintSystemCompletionMode, topLevelAtoms: List, topLevelType: UnwrappedType, + diagnosticsHolder: KotlinDiagnosticsHolder, collectVariablesFromContext: Boolean, analyze: (PostponedResolvedAtom) -> Unit ) { @@ -80,7 +102,13 @@ class KotlinConstraintSystemCompleter( if ( completionMode == ConstraintSystemCompletionMode.FULL && - resolveLambdaOrCallableReferenceWithTypeVariableAsExpectedType(c, variableForFixation, topLevelAtoms, analyze) + resolveLambdaOrCallableReferenceWithTypeVariableAsExpectedType( + c, + variableForFixation, + topLevelAtoms, + diagnosticsHolder, + analyze + ) ) { continue } @@ -104,7 +132,7 @@ class KotlinConstraintSystemCompleter( getOrderedNotAnalyzedPostponedArguments(topLevelAtoms).forEach(analyze) if (c.notFixedTypeVariables.isNotEmpty() && c.postponedTypeVariables.isEmpty()) { - runCompletion(c, completionMode, topLevelAtoms, topLevelType, analyze) + runCompletion(c, completionMode, topLevelAtoms, topLevelType, diagnosticsHolder, analyze) } } } @@ -116,6 +144,7 @@ class KotlinConstraintSystemCompleter( c: Context, variableForFixation: VariableFixationFinder.VariableForFixation, topLevelAtoms: List, + diagnosticsHolder: KotlinDiagnosticsHolder, analyze: (PostponedResolvedAtom) -> Unit ): Boolean { val variable = variableForFixation.variable as TypeConstructor @@ -156,7 +185,7 @@ class KotlinConstraintSystemCompleter( isSuitable = KotlinType::isBuiltinFunctionalType, typeVariableCreator = { TypeVariableForLambdaReturnType(postponedAtom.atom, builtIns, "_R") }, newAtomCreator = { returnVariable, expectedType -> - postponedAtom.transformToResolvedLambda(csBuilder, expectedType, returnVariable) + postponedAtom.transformToResolvedLambda(csBuilder, diagnosticsHolder, expectedType, returnVariable) } ) else -> return false diff --git a/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/model/KotlinCallDiagnostics.kt b/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/model/KotlinCallDiagnostics.kt index e404dc3c0fc..ab020e1806d 100644 --- a/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/model/KotlinCallDiagnostics.kt +++ b/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/model/KotlinCallDiagnostics.kt @@ -209,3 +209,12 @@ class ResolvedToSamWithVarargDiagnostic(val argument: KotlinCallArgument) : Kotl reporter.onCallArgument(argument, this) } } + +class NotEnoughInformationForLambdaParameter( + val lambdaArgument: LambdaKotlinCallArgument, + val parameterIndex: Int +) : KotlinCallDiagnostic(INAPPLICABLE) { + override fun report(reporter: DiagnosticReporter) { + reporter.onCallArgument(lambdaArgument, this) + } +} diff --git a/compiler/testData/diagnostics/tests/inference/nonFunctionalExpectedTypeForLambdaArgument.fir.kt b/compiler/testData/diagnostics/tests/inference/nonFunctionalExpectedTypeForLambdaArgument.fir.kt new file mode 100644 index 00000000000..92bb0a159b9 --- /dev/null +++ b/compiler/testData/diagnostics/tests/inference/nonFunctionalExpectedTypeForLambdaArgument.fir.kt @@ -0,0 +1,36 @@ +// !WITH_NEW_INFERENCE +// !DIAGNOSTICS: -UNUSED_PARAMETER + +fun callAny(arg: Any?) {} +fun callParam(arg: T) {} + +fun testAny() { + callAny { error -> error } + callAny l@{ error -> error } + callAny({error -> error}) + callAny(({error -> error})) + callAny(l@{error -> error}) + callAny((l@{error -> error})) +} + +fun testAnyCall() { + callAny { + error -> error() + } +} + +fun testParam() { + callParam { + param -> param + } +} + +fun testParamCall() { + callParam { + param -> param() + } +} + +fun testNoContext() { + { it -> it } +} diff --git a/compiler/testData/diagnostics/tests/inference/nonFunctionalExpectedTypeForLambdaArgument.kt b/compiler/testData/diagnostics/tests/inference/nonFunctionalExpectedTypeForLambdaArgument.kt new file mode 100644 index 00000000000..4f2a8dd8a9d --- /dev/null +++ b/compiler/testData/diagnostics/tests/inference/nonFunctionalExpectedTypeForLambdaArgument.kt @@ -0,0 +1,36 @@ +// !WITH_NEW_INFERENCE +// !DIAGNOSTICS: -UNUSED_PARAMETER + +fun callAny(arg: Any?) {} +fun callParam(arg: T) {} + +fun testAny() { + callAny { error -> error } + callAny l@{ error -> error } + callAny({error -> error}) + callAny(({error -> error})) + callAny(l@{error -> error}) + callAny((l@{error -> error})) +} + +fun testAnyCall() { + callAny { + error -> error() + } +} + +fun testParam() { + callParam { + param -> param + } +} + +fun testParamCall() { + callParam { + param -> param() + } +} + +fun testNoContext() { + { it -> it } +} diff --git a/compiler/testData/diagnostics/tests/inference/nonFunctionalExpectedTypeForLambdaArgument.txt b/compiler/testData/diagnostics/tests/inference/nonFunctionalExpectedTypeForLambdaArgument.txt new file mode 100644 index 00000000000..56d073a3af9 --- /dev/null +++ b/compiler/testData/diagnostics/tests/inference/nonFunctionalExpectedTypeForLambdaArgument.txt @@ -0,0 +1,9 @@ +package + +public fun callAny(/*0*/ arg: kotlin.Any?): kotlin.Unit +public fun callParam(/*0*/ arg: T): kotlin.Unit +public fun testAny(): kotlin.Unit +public fun testAnyCall(): kotlin.Unit +public fun testNoContext(): kotlin.Unit +public fun testParam(): kotlin.Unit +public fun testParamCall(): kotlin.Unit diff --git a/compiler/testData/diagnostics/tests/inference/nothingType/kt34335.fir.kt b/compiler/testData/diagnostics/tests/inference/nothingType/kt34335.fir.kt new file mode 100644 index 00000000000..21e5905dac8 --- /dev/null +++ b/compiler/testData/diagnostics/tests/inference/nothingType/kt34335.fir.kt @@ -0,0 +1,19 @@ +// !LANGUAGE: +NewInference +// !WITH_NEW_INFERENCE +// !DIAGNOSTICS: -UNUSED_PARAMETER + +fun call(vararg x: Any?) {} +fun Any.call(vararg args: Any?): R = TODO() +fun println(message: Any?) {} + +fun foo(action: (Int) -> Unit) { + action(10) +} + +fun test1() { + call({ x -> println(x::class) }) // x inside the lambda is inferred to `Nothing`, the lambda is `(Nothing) -> Unit`. +} + +fun test2() { + ::foo.call({ x -> println(x::class) }) +} diff --git a/compiler/testData/diagnostics/tests/inference/nothingType/kt34335.kt b/compiler/testData/diagnostics/tests/inference/nothingType/kt34335.kt new file mode 100644 index 00000000000..282d2b8ac78 --- /dev/null +++ b/compiler/testData/diagnostics/tests/inference/nothingType/kt34335.kt @@ -0,0 +1,19 @@ +// !LANGUAGE: +NewInference +// !WITH_NEW_INFERENCE +// !DIAGNOSTICS: -UNUSED_PARAMETER + +fun call(vararg x: Any?) {} +fun Any.call(vararg args: Any?): R = TODO() +fun println(message: Any?) {} + +fun foo(action: (Int) -> Unit) { + action(10) +} + +fun test1() { + call({ x -> println(x::class) }) // x inside the lambda is inferred to `Nothing`, the lambda is `(Nothing) -> Unit`. +} + +fun test2() { + ::foo.call({ x -> println(x::class) }) +} diff --git a/compiler/testData/diagnostics/tests/inference/nothingType/kt34335.txt b/compiler/testData/diagnostics/tests/inference/nothingType/kt34335.txt new file mode 100644 index 00000000000..0e5977585df --- /dev/null +++ b/compiler/testData/diagnostics/tests/inference/nothingType/kt34335.txt @@ -0,0 +1,8 @@ +package + +public fun call(/*0*/ vararg x: kotlin.Any? /*kotlin.Array*/): kotlin.Unit +public fun foo(/*0*/ action: (kotlin.Int) -> kotlin.Unit): kotlin.Unit +public fun println(/*0*/ message: kotlin.Any?): kotlin.Unit +public fun test1(): kotlin.Unit +public fun test2(): kotlin.Unit +public fun kotlin.Any.call(/*0*/ vararg args: kotlin.Any? /*kotlin.Array*/): R diff --git a/compiler/testData/diagnostics/tests/inference/reportingImprovements/FunctionPlaceholder.kt b/compiler/testData/diagnostics/tests/inference/reportingImprovements/FunctionPlaceholder.kt index 7c8f413b183..4dad10ffaa8 100644 --- a/compiler/testData/diagnostics/tests/inference/reportingImprovements/FunctionPlaceholder.kt +++ b/compiler/testData/diagnostics/tests/inference/reportingImprovements/FunctionPlaceholder.kt @@ -8,7 +8,7 @@ fun bar(f: (T) -> R) = f fun test() { foo { it } - foo { x -> x} + foo { x -> x} foo { x: Int -> x} bar { it + 1 } diff --git a/compiler/testData/diagnostics/tests/j+k/samByProjectedType/noAdapterBecuaseOfRecursiveUpperBound.fir.kt b/compiler/testData/diagnostics/tests/j+k/samByProjectedType/noAdapterBecuaseOfRecursiveUpperBound.fir.kt index bff8339f4bc..e19d68079ee 100644 --- a/compiler/testData/diagnostics/tests/j+k/samByProjectedType/noAdapterBecuaseOfRecursiveUpperBound.fir.kt +++ b/compiler/testData/diagnostics/tests/j+k/samByProjectedType/noAdapterBecuaseOfRecursiveUpperBound.fir.kt @@ -1,4 +1,3 @@ -// !WITH_NEW_INFERENCE // !CHECK_TYPE // FILE: Function.java public interface Function> { diff --git a/compiler/testData/diagnostics/tests/j+k/samByProjectedType/noAdapterBecuaseOfRecursiveUpperBound.kt b/compiler/testData/diagnostics/tests/j+k/samByProjectedType/noAdapterBecuaseOfRecursiveUpperBound.kt index c0b62ef75f0..8ae8eaaa41f 100644 --- a/compiler/testData/diagnostics/tests/j+k/samByProjectedType/noAdapterBecuaseOfRecursiveUpperBound.kt +++ b/compiler/testData/diagnostics/tests/j+k/samByProjectedType/noAdapterBecuaseOfRecursiveUpperBound.kt @@ -1,4 +1,3 @@ -// !WITH_NEW_INFERENCE // !CHECK_TYPE // FILE: Function.java public interface Function> { @@ -17,12 +16,12 @@ public class A { // FILE: main.kt fun main() { A().foo { - x -> + x -> "" } A.bar { - x -> + x -> "" } } diff --git a/compiler/testData/diagnostics/tests/regressions/kt10843.kt b/compiler/testData/diagnostics/tests/regressions/kt10843.kt index 0f7a68de53c..66e4fbd0bf7 100644 --- a/compiler/testData/diagnostics/tests/regressions/kt10843.kt +++ b/compiler/testData/diagnostics/tests/regressions/kt10843.kt @@ -3,6 +3,6 @@ // See EA-76890 / KT-10843: NPE during analysis fun lambda(x : Int?) = x?.let l { y -> - if (y > 0) return@l x - y + if (y > 0) return@l x + y }!! diff --git a/compiler/testData/diagnostics/tests/resolve/newLineLambda.kt b/compiler/testData/diagnostics/tests/resolve/newLineLambda.kt index 6636c894309..8fdbf5d6d37 100644 --- a/compiler/testData/diagnostics/tests/resolve/newLineLambda.kt +++ b/compiler/testData/diagnostics/tests/resolve/newLineLambda.kt @@ -113,6 +113,6 @@ fun testTwoLambdas() { fun f1(): (() -> Unit) -> (() -> Unit) -> Unit { return { l1 -> l1() - { l2 -> l2() } + { l2 -> l2() } } } diff --git a/compiler/testData/diagnostics/tests/resolve/overloadConflicts/allLambdas.kt b/compiler/testData/diagnostics/tests/resolve/overloadConflicts/allLambdas.kt index 4e002ee7f8b..a1995d1d6e8 100644 --- a/compiler/testData/diagnostics/tests/resolve/overloadConflicts/allLambdas.kt +++ b/compiler/testData/diagnostics/tests/resolve/overloadConflicts/allLambdas.kt @@ -7,4 +7,4 @@ object X2 fun foo(x: T1, f: (T1) -> T1) = X1 fun foo(xf: () -> T2, f: (T2) -> T2) = X2 -val test: X2 = foo({ 0 }, { it -> it + 1 }) \ No newline at end of file +val test: X2 = foo({ 0 }, { it -> it + 1 }) \ No newline at end of file diff --git a/compiler/tests/org/jetbrains/kotlin/checkers/DiagnosticsTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/checkers/DiagnosticsTestGenerated.java index 235cb4100cc..a625a3f6f16 100644 --- a/compiler/tests/org/jetbrains/kotlin/checkers/DiagnosticsTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/checkers/DiagnosticsTestGenerated.java @@ -10133,6 +10133,11 @@ public class DiagnosticsTestGenerated extends AbstractDiagnosticsTest { runTest("compiler/testData/diagnostics/tests/inference/noInformationForParameter.kt"); } + @TestMetadata("nonFunctionalExpectedTypeForLambdaArgument.kt") + public void testNonFunctionalExpectedTypeForLambdaArgument() throws Exception { + runTest("compiler/testData/diagnostics/tests/inference/nonFunctionalExpectedTypeForLambdaArgument.kt"); + } + @TestMetadata("nullableTypeArgumentWithNotNullUpperBound.kt") public void testNullableTypeArgumentWithNotNullUpperBound() throws Exception { runTest("compiler/testData/diagnostics/tests/inference/nullableTypeArgumentWithNotNullUpperBound.kt"); @@ -10908,6 +10913,11 @@ public class DiagnosticsTestGenerated extends AbstractDiagnosticsTest { runTest("compiler/testData/diagnostics/tests/inference/nothingType/kt32388.kt"); } + @TestMetadata("kt34335.kt") + public void testKt34335() throws Exception { + runTest("compiler/testData/diagnostics/tests/inference/nothingType/kt34335.kt"); + } + @TestMetadata("lambdaNothingAndExpectedType.kt") public void testLambdaNothingAndExpectedType() throws Exception { runTest("compiler/testData/diagnostics/tests/inference/nothingType/lambdaNothingAndExpectedType.kt"); diff --git a/compiler/tests/org/jetbrains/kotlin/checkers/javac/DiagnosticsUsingJavacTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/checkers/javac/DiagnosticsUsingJavacTestGenerated.java index 146394cb3cd..87bb33cd873 100644 --- a/compiler/tests/org/jetbrains/kotlin/checkers/javac/DiagnosticsUsingJavacTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/checkers/javac/DiagnosticsUsingJavacTestGenerated.java @@ -10128,6 +10128,11 @@ public class DiagnosticsUsingJavacTestGenerated extends AbstractDiagnosticsUsing runTest("compiler/testData/diagnostics/tests/inference/noInformationForParameter.kt"); } + @TestMetadata("nonFunctionalExpectedTypeForLambdaArgument.kt") + public void testNonFunctionalExpectedTypeForLambdaArgument() throws Exception { + runTest("compiler/testData/diagnostics/tests/inference/nonFunctionalExpectedTypeForLambdaArgument.kt"); + } + @TestMetadata("nullableTypeArgumentWithNotNullUpperBound.kt") public void testNullableTypeArgumentWithNotNullUpperBound() throws Exception { runTest("compiler/testData/diagnostics/tests/inference/nullableTypeArgumentWithNotNullUpperBound.kt"); @@ -10903,6 +10908,11 @@ public class DiagnosticsUsingJavacTestGenerated extends AbstractDiagnosticsUsing runTest("compiler/testData/diagnostics/tests/inference/nothingType/kt32388.kt"); } + @TestMetadata("kt34335.kt") + public void testKt34335() throws Exception { + runTest("compiler/testData/diagnostics/tests/inference/nothingType/kt34335.kt"); + } + @TestMetadata("lambdaNothingAndExpectedType.kt") public void testLambdaNothingAndExpectedType() throws Exception { runTest("compiler/testData/diagnostics/tests/inference/nothingType/lambdaNothingAndExpectedType.kt");