[NI] Report error about unknown parameter type of lambda argument

KT-34335
This commit is contained in:
Pavel Kirpichenkov
2020-01-24 19:16:11 +03:00
parent 9fb8579252
commit eec039f5a2
25 changed files with 260 additions and 29 deletions
@@ -10126,6 +10126,11 @@ public class FirOldFrontendDiagnosticsTestGenerated extends AbstractFirOldFronte
runTest("compiler/testData/diagnostics/tests/inference/noInformationForParameter.kt"); 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") @TestMetadata("nullableTypeArgumentWithNotNullUpperBound.kt")
public void testNullableTypeArgumentWithNotNullUpperBound() throws Exception { public void testNullableTypeArgumentWithNotNullUpperBound() throws Exception {
runTest("compiler/testData/diagnostics/tests/inference/nullableTypeArgumentWithNotNullUpperBound.kt"); 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"); 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") @TestMetadata("lambdaNothingAndExpectedType.kt")
public void testLambdaNothingAndExpectedType() throws Exception { public void testLambdaNothingAndExpectedType() throws Exception {
runTest("compiler/testData/diagnostics/tests/inference/nothingType/lambdaNothingAndExpectedType.kt"); runTest("compiler/testData/diagnostics/tests/inference/nothingType/lambdaNothingAndExpectedType.kt");
@@ -81,7 +81,8 @@ class DelegatedPropertyInferenceSession(
override fun inferPostponedVariables( override fun inferPostponedVariables(
lambda: ResolvedLambdaAtom, lambda: ResolvedLambdaAtom,
initialStorage: ConstraintStorage initialStorage: ConstraintStorage,
diagnosticsHolder: KotlinDiagnosticsHolder
): Map<TypeConstructor, UnwrappedType> = emptyMap() ): Map<TypeConstructor, UnwrappedType> = emptyMap()
override fun writeOnlyStubs(callInfo: SingleCallResolutionResult): Boolean = false override fun writeOnlyStubs(callInfo: SingleCallResolutionResult): Boolean = false
@@ -101,7 +102,8 @@ object InferenceSessionForExistingCandidates : InferenceSession {
override fun currentConstraintSystem(): ConstraintStorage = ConstraintStorage.Empty override fun currentConstraintSystem(): ConstraintStorage = ConstraintStorage.Empty
override fun inferPostponedVariables( override fun inferPostponedVariables(
lambda: ResolvedLambdaAtom, lambda: ResolvedLambdaAtom,
initialStorage: ConstraintStorage initialStorage: ConstraintStorage,
diagnosticsHolder: KotlinDiagnosticsHolder
): Map<TypeConstructor, UnwrappedType> = emptyMap() ): Map<TypeConstructor, UnwrappedType> = emptyMap()
override fun writeOnlyStubs(callInfo: SingleCallResolutionResult): Boolean = false override fun writeOnlyStubs(callInfo: SingleCallResolutionResult): Boolean = false
@@ -182,6 +182,20 @@ class DiagnosticReporterByTrackingStrategy(
ResolvedToSamWithVarargDiagnostic::class.java -> { ResolvedToSamWithVarargDiagnostic::class.java -> {
trace.report(TYPE_INFERENCE_CANDIDATE_WITH_SAM_AND_VARARG.on(callArgument.psiCallArgument.valueArgument.asElement())) 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))
}
}
} }
} }
@@ -102,7 +102,8 @@ class CoroutineInferenceSession(
override fun inferPostponedVariables( override fun inferPostponedVariables(
lambda: ResolvedLambdaAtom, lambda: ResolvedLambdaAtom,
initialStorage: ConstraintStorage initialStorage: ConstraintStorage,
diagnosticsHolder: KotlinDiagnosticsHolder
): Map<TypeConstructor, UnwrappedType> { ): Map<TypeConstructor, UnwrappedType> {
val commonSystem = buildCommonSystem(initialStorage) val commonSystem = buildCommonSystem(initialStorage)
@@ -110,7 +111,8 @@ class CoroutineInferenceSession(
kotlinConstraintSystemCompleter.completeConstraintSystem( kotlinConstraintSystemCompleter.completeConstraintSystem(
context, context,
builtIns.unitType, builtIns.unitType,
partiallyResolvedCallsInfo.map { it.callResolutionResult.resultCallAtom } partiallyResolvedCallsInfo.map { it.callResolutionResult.resultCallAtom },
diagnosticsHolder
) )
updateCalls(lambda, commonSystem) updateCalls(lambda, commonSystem)
@@ -85,7 +85,8 @@ abstract class ManyCandidatesResolver<D : CallableDescriptor>(
constraintSystem.asConstraintSystemCompleterContext(), constraintSystem.asConstraintSystemCompleterContext(),
KotlinConstraintSystemCompleter.ConstraintSystemCompletionMode.FULL, KotlinConstraintSystemCompleter.ConstraintSystemCompletionMode.FULL,
atoms, atoms,
builtIns.unitType builtIns.unitType,
diagnosticHolder
) { ) {
postponedArgumentsAnalyzer.analyze( postponedArgumentsAnalyzer.analyze(
constraintSystem.asPostponedArgumentsAnalyzerContext(), resolutionCallbacks, it, diagnosticHolder constraintSystem.asPostponedArgumentsAnalyzerContext(), resolutionCallbacks, it, diagnosticHolder
@@ -21,7 +21,8 @@ interface InferenceSession {
override fun currentConstraintSystem(): ConstraintStorage = ConstraintStorage.Empty override fun currentConstraintSystem(): ConstraintStorage = ConstraintStorage.Empty
override fun inferPostponedVariables( override fun inferPostponedVariables(
lambda: ResolvedLambdaAtom, lambda: ResolvedLambdaAtom,
initialStorage: ConstraintStorage initialStorage: ConstraintStorage,
diagnosticsHolder: KotlinDiagnosticsHolder
): Map<TypeConstructor, UnwrappedType> = emptyMap() ): Map<TypeConstructor, UnwrappedType> = emptyMap()
override fun writeOnlyStubs(callInfo: SingleCallResolutionResult): Boolean = false override fun writeOnlyStubs(callInfo: SingleCallResolutionResult): Boolean = false
@@ -35,7 +36,12 @@ interface InferenceSession {
fun addCompletedCallInfo(callInfo: CompletedCallInfo) fun addCompletedCallInfo(callInfo: CompletedCallInfo)
fun addErrorCallInfo(callInfo: ErrorCallInfo) fun addErrorCallInfo(callInfo: ErrorCallInfo)
fun currentConstraintSystem(): ConstraintStorage fun currentConstraintSystem(): ConstraintStorage
fun inferPostponedVariables(lambda: ResolvedLambdaAtom, initialStorage: ConstraintStorage): Map<TypeConstructor, UnwrappedType> fun inferPostponedVariables(
lambda: ResolvedLambdaAtom,
initialStorage: ConstraintStorage,
diagnosticsHolder: KotlinDiagnosticsHolder
): Map<TypeConstructor, UnwrappedType>
fun writeOnlyStubs(callInfo: SingleCallResolutionResult): Boolean fun writeOnlyStubs(callInfo: SingleCallResolutionResult): Boolean
fun callCompleted(resolvedAtom: ResolvedAtom): Boolean fun callCompleted(resolvedAtom: ResolvedAtom): Boolean
fun shouldCompleteResolvedSubAtomsOf(resolvedCallAtom: ResolvedCallAtom): Boolean fun shouldCompleteResolvedSubAtomsOf(resolvedCallAtom: ResolvedCallAtom): Boolean
@@ -131,7 +131,8 @@ class KotlinCallCompleter(
constraintSystem.asConstraintSystemCompleterContext(), constraintSystem.asConstraintSystemCompleterContext(),
completionMode, completionMode,
listOf(resolvedCallAtom), listOf(resolvedCallAtom),
returnType returnType,
diagnosticsHolder
) { ) {
if (collectAllCandidatesMode) { if (collectAllCandidatesMode) {
it.setEmptyAnalyzedResults() it.setEmptyAnalyzedResults()
@@ -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.LHSArgumentConstraintPosition
import org.jetbrains.kotlin.resolve.calls.inference.model.TypeVariableForLambdaReturnType import org.jetbrains.kotlin.resolve.calls.inference.model.TypeVariableForLambdaReturnType
import org.jetbrains.kotlin.resolve.calls.model.* import org.jetbrains.kotlin.resolve.calls.model.*
import org.jetbrains.kotlin.types.ErrorUtils
import org.jetbrains.kotlin.types.UnwrappedType import org.jetbrains.kotlin.types.UnwrappedType
import org.jetbrains.kotlin.types.Variance import org.jetbrains.kotlin.types.Variance
import org.jetbrains.kotlin.types.typeUtil.builtIns import org.jetbrains.kotlin.types.typeUtil.builtIns
@@ -40,7 +41,7 @@ fun resolveKtPrimitive(
checkSimpleArgument(csBuilder, argument, expectedType, diagnosticsHolder, isReceiver) checkSimpleArgument(csBuilder, argument, expectedType, diagnosticsHolder, isReceiver)
is LambdaKotlinCallArgument -> is LambdaKotlinCallArgument ->
preprocessLambdaArgument(csBuilder, argument, expectedType) preprocessLambdaArgument(csBuilder, argument, expectedType, diagnosticsHolder)
is CallableReferenceKotlinCallArgument -> is CallableReferenceKotlinCallArgument ->
preprocessCallableReference(csBuilder, argument, expectedType, diagnosticsHolder) preprocessCallableReference(csBuilder, argument, expectedType, diagnosticsHolder)
@@ -57,6 +58,7 @@ private fun preprocessLambdaArgument(
csBuilder: ConstraintSystemBuilder, csBuilder: ConstraintSystemBuilder,
argument: LambdaKotlinCallArgument, argument: LambdaKotlinCallArgument,
expectedType: UnwrappedType?, expectedType: UnwrappedType?,
diagnosticsHolder: KotlinDiagnosticsHolder,
forceResolution: Boolean = false, forceResolution: Boolean = false,
returnTypeVariable: TypeVariableForLambdaReturnType? = null returnTypeVariable: TypeVariableForLambdaReturnType? = null
): ResolvedAtom { ): ResolvedAtom {
@@ -65,7 +67,7 @@ private fun preprocessLambdaArgument(
} }
val resolvedArgument = extractLambdaInfoFromFunctionalType(expectedType, argument, returnTypeVariable) val resolvedArgument = extractLambdaInfoFromFunctionalType(expectedType, argument, returnTypeVariable)
?: extraLambdaInfo(expectedType, argument, csBuilder) ?: extraLambdaInfo(expectedType, argument, csBuilder, diagnosticsHolder)
if (expectedType != null) { if (expectedType != null) {
val lambdaType = createFunctionType( val lambdaType = createFunctionType(
@@ -81,7 +83,8 @@ private fun preprocessLambdaArgument(
private fun extraLambdaInfo( private fun extraLambdaInfo(
expectedType: UnwrappedType?, expectedType: UnwrappedType?,
argument: LambdaKotlinCallArgument, argument: LambdaKotlinCallArgument,
csBuilder: ConstraintSystemBuilder csBuilder: ConstraintSystemBuilder,
diagnosticsHolder: KotlinDiagnosticsHolder
): ResolvedLambdaAtom { ): ResolvedLambdaAtom {
val builtIns = csBuilder.builtIns val builtIns = csBuilder.builtIns
val isSuspend = expectedType?.isSuspendFunctionType ?: false val isSuspend = expectedType?.isSuspendFunctionType ?: false
@@ -96,7 +99,14 @@ private fun extraLambdaInfo(
argumentAsFunctionExpression?.returnType ?: expectedType?.arguments?.singleOrNull()?.type?.unwrap()?.takeIf { isFunctionSupertype } argumentAsFunctionExpression?.returnType ?: expectedType?.arguments?.singleOrNull()?.type?.unwrap()?.takeIf { isFunctionSupertype }
?: typeVariable.defaultType ?: 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("<Unknown lambda parameter type>")
}
} ?: emptyList()
val newTypeVariableUsed = returnType == typeVariable.defaultType val newTypeVariableUsed = returnType == typeVariable.defaultType
if (newTypeVariableUsed) csBuilder.registerVariable(typeVariable) if (newTypeVariableUsed) csBuilder.registerVariable(typeVariable)
@@ -177,6 +187,7 @@ private fun extractLambdaInfoFromFunctionalType(
fun LambdaWithTypeVariableAsExpectedTypeAtom.transformToResolvedLambda( fun LambdaWithTypeVariableAsExpectedTypeAtom.transformToResolvedLambda(
csBuilder: ConstraintSystemBuilder, csBuilder: ConstraintSystemBuilder,
diagnosticsHolder: KotlinDiagnosticsHolder,
expectedType: UnwrappedType? = null, expectedType: UnwrappedType? = null,
returnTypeVariable: TypeVariableForLambdaReturnType? = null returnTypeVariable: TypeVariableForLambdaReturnType? = null
): ResolvedLambdaAtom { ): ResolvedLambdaAtom {
@@ -186,6 +197,7 @@ fun LambdaWithTypeVariableAsExpectedTypeAtom.transformToResolvedLambda(
csBuilder, csBuilder,
atom, atom,
fixedExpectedType, fixedExpectedType,
diagnosticsHolder,
forceResolution = true, forceResolution = true,
returnTypeVariable = returnTypeVariable returnTypeVariable = returnTypeVariable
) as ResolvedLambdaAtom ) as ResolvedLambdaAtom
@@ -51,7 +51,7 @@ class PostponedArgumentsAnalyzer(
is LambdaWithTypeVariableAsExpectedTypeAtom -> is LambdaWithTypeVariableAsExpectedTypeAtom ->
analyzeLambda( analyzeLambda(
c, resolutionCallbacks, argument.transformToResolvedLambda(c.getBuilder()), diagnosticsHolder c, resolutionCallbacks, argument.transformToResolvedLambda(c.getBuilder(), diagnosticsHolder), diagnosticsHolder
) )
is ResolvedCallableReferenceAtom -> is ResolvedCallableReferenceAtom ->
@@ -147,7 +147,7 @@ class PostponedArgumentsAnalyzer(
if (inferenceSession != null) { if (inferenceSession != null) {
val storageSnapshot = c.getBuilder().currentStorage() val storageSnapshot = c.getBuilder().currentStorage()
val postponedVariables = inferenceSession.inferPostponedVariables(lambda, storageSnapshot) val postponedVariables = inferenceSession.inferPostponedVariables(lambda, storageSnapshot, diagnosticHolder)
for ((constructor, resultType) in postponedVariables) { for ((constructor, resultType) in postponedVariables) {
val variableWithConstraints = storageSnapshot.notFixedTypeVariables[constructor] ?: continue val variableWithConstraints = storageSnapshot.notFixedTypeVariables[constructor] ?: continue
@@ -49,13 +49,34 @@ class KotlinConstraintSystemCompleter(
completionMode: ConstraintSystemCompletionMode, completionMode: ConstraintSystemCompletionMode,
topLevelAtoms: List<ResolvedAtom>, topLevelAtoms: List<ResolvedAtom>,
topLevelType: UnwrappedType, topLevelType: UnwrappedType,
diagnosticsHolder: KotlinDiagnosticsHolder,
analyze: (PostponedResolvedAtom) -> Unit 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<ResolvedAtom>) { fun completeConstraintSystem(
runCompletion(c, ConstraintSystemCompletionMode.FULL, topLevelAtoms, topLevelType, collectVariablesFromContext = true) { c: Context,
topLevelType: UnwrappedType,
topLevelAtoms: List<ResolvedAtom>,
diagnosticsHolder: KotlinDiagnosticsHolder
) {
runCompletion(
c,
ConstraintSystemCompletionMode.FULL,
topLevelAtoms,
topLevelType,
diagnosticsHolder,
collectVariablesFromContext = true,
) {
error("Shouldn't be called in complete constraint system mode") error("Shouldn't be called in complete constraint system mode")
} }
} }
@@ -65,6 +86,7 @@ class KotlinConstraintSystemCompleter(
completionMode: ConstraintSystemCompletionMode, completionMode: ConstraintSystemCompletionMode,
topLevelAtoms: List<ResolvedAtom>, topLevelAtoms: List<ResolvedAtom>,
topLevelType: UnwrappedType, topLevelType: UnwrappedType,
diagnosticsHolder: KotlinDiagnosticsHolder,
collectVariablesFromContext: Boolean, collectVariablesFromContext: Boolean,
analyze: (PostponedResolvedAtom) -> Unit analyze: (PostponedResolvedAtom) -> Unit
) { ) {
@@ -80,7 +102,13 @@ class KotlinConstraintSystemCompleter(
if ( if (
completionMode == ConstraintSystemCompletionMode.FULL && completionMode == ConstraintSystemCompletionMode.FULL &&
resolveLambdaOrCallableReferenceWithTypeVariableAsExpectedType(c, variableForFixation, topLevelAtoms, analyze) resolveLambdaOrCallableReferenceWithTypeVariableAsExpectedType(
c,
variableForFixation,
topLevelAtoms,
diagnosticsHolder,
analyze
)
) { ) {
continue continue
} }
@@ -104,7 +132,7 @@ class KotlinConstraintSystemCompleter(
getOrderedNotAnalyzedPostponedArguments(topLevelAtoms).forEach(analyze) getOrderedNotAnalyzedPostponedArguments(topLevelAtoms).forEach(analyze)
if (c.notFixedTypeVariables.isNotEmpty() && c.postponedTypeVariables.isEmpty()) { 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, c: Context,
variableForFixation: VariableFixationFinder.VariableForFixation, variableForFixation: VariableFixationFinder.VariableForFixation,
topLevelAtoms: List<ResolvedAtom>, topLevelAtoms: List<ResolvedAtom>,
diagnosticsHolder: KotlinDiagnosticsHolder,
analyze: (PostponedResolvedAtom) -> Unit analyze: (PostponedResolvedAtom) -> Unit
): Boolean { ): Boolean {
val variable = variableForFixation.variable as TypeConstructor val variable = variableForFixation.variable as TypeConstructor
@@ -156,7 +185,7 @@ class KotlinConstraintSystemCompleter(
isSuitable = KotlinType::isBuiltinFunctionalType, isSuitable = KotlinType::isBuiltinFunctionalType,
typeVariableCreator = { TypeVariableForLambdaReturnType(postponedAtom.atom, builtIns, "_R") }, typeVariableCreator = { TypeVariableForLambdaReturnType(postponedAtom.atom, builtIns, "_R") },
newAtomCreator = { returnVariable, expectedType -> newAtomCreator = { returnVariable, expectedType ->
postponedAtom.transformToResolvedLambda(csBuilder, expectedType, returnVariable) postponedAtom.transformToResolvedLambda(csBuilder, diagnosticsHolder, expectedType, returnVariable)
} }
) )
else -> return false else -> return false
@@ -209,3 +209,12 @@ class ResolvedToSamWithVarargDiagnostic(val argument: KotlinCallArgument) : Kotl
reporter.onCallArgument(argument, this) reporter.onCallArgument(argument, this)
} }
} }
class NotEnoughInformationForLambdaParameter(
val lambdaArgument: LambdaKotlinCallArgument,
val parameterIndex: Int
) : KotlinCallDiagnostic(INAPPLICABLE) {
override fun report(reporter: DiagnosticReporter) {
reporter.onCallArgument(lambdaArgument, this)
}
}
@@ -0,0 +1,36 @@
// !WITH_NEW_INFERENCE
// !DIAGNOSTICS: -UNUSED_PARAMETER
fun callAny(arg: Any?) {}
fun <T> 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 -> <!UNRESOLVED_REFERENCE!>error<!>()
}
}
fun testParam() {
callParam {
param -> param
}
}
fun testParamCall() {
callParam {
param -> <!UNRESOLVED_REFERENCE!>param<!>()
}
}
fun testNoContext() {
{ it -> it }
}
@@ -0,0 +1,36 @@
// !WITH_NEW_INFERENCE
// !DIAGNOSTICS: -UNUSED_PARAMETER
fun callAny(arg: Any?) {}
fun <T> callParam(arg: T) {}
fun testAny() {
callAny { <!CANNOT_INFER_PARAMETER_TYPE!>error<!> -> <!DEBUG_INFO_ELEMENT_WITH_ERROR_TYPE!>error<!> }
callAny l@{ <!CANNOT_INFER_PARAMETER_TYPE!>error<!> -> <!DEBUG_INFO_ELEMENT_WITH_ERROR_TYPE!>error<!> }
callAny({<!CANNOT_INFER_PARAMETER_TYPE!>error<!> -> <!DEBUG_INFO_ELEMENT_WITH_ERROR_TYPE!>error<!>})
callAny(({<!CANNOT_INFER_PARAMETER_TYPE!>error<!> -> <!DEBUG_INFO_ELEMENT_WITH_ERROR_TYPE!>error<!>}))
callAny(l@{<!CANNOT_INFER_PARAMETER_TYPE!>error<!> -> <!DEBUG_INFO_ELEMENT_WITH_ERROR_TYPE!>error<!>})
callAny((l@{<!CANNOT_INFER_PARAMETER_TYPE!>error<!> -> <!DEBUG_INFO_ELEMENT_WITH_ERROR_TYPE!>error<!>}))
}
fun testAnyCall() {
callAny {
<!CANNOT_INFER_PARAMETER_TYPE!>error<!> -> <!NI;DEBUG_INFO_MISSING_UNRESOLVED, OI;DEBUG_INFO_ELEMENT_WITH_ERROR_TYPE!>error()<!>
}
}
fun testParam() {
<!NI;NEW_INFERENCE_NO_INFORMATION_FOR_PARAMETER, OI;TYPE_INFERENCE_NO_INFORMATION_FOR_PARAMETER!>callParam<!> {
<!CANNOT_INFER_PARAMETER_TYPE!>param<!> -> <!DEBUG_INFO_ELEMENT_WITH_ERROR_TYPE!>param<!>
}
}
fun testParamCall() {
<!NI;NEW_INFERENCE_NO_INFORMATION_FOR_PARAMETER, OI;TYPE_INFERENCE_NO_INFORMATION_FOR_PARAMETER!>callParam<!> {
<!CANNOT_INFER_PARAMETER_TYPE!>param<!> -> <!NI;DEBUG_INFO_MISSING_UNRESOLVED, OI;DEBUG_INFO_ELEMENT_WITH_ERROR_TYPE!>param()<!>
}
}
fun testNoContext() {
<!UNUSED_LAMBDA_EXPRESSION!>{ <!CANNOT_INFER_PARAMETER_TYPE!>it<!> -> <!DEBUG_INFO_ELEMENT_WITH_ERROR_TYPE!>it<!> }<!>
}
@@ -0,0 +1,9 @@
package
public fun callAny(/*0*/ arg: kotlin.Any?): kotlin.Unit
public fun </*0*/ T> 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
@@ -0,0 +1,19 @@
// !LANGUAGE: +NewInference
// !WITH_NEW_INFERENCE
// !DIAGNOSTICS: -UNUSED_PARAMETER
fun call(vararg x: Any?) {}
fun <R> 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) })
}
@@ -0,0 +1,19 @@
// !LANGUAGE: +NewInference
// !WITH_NEW_INFERENCE
// !DIAGNOSTICS: -UNUSED_PARAMETER
fun call(vararg x: Any?) {}
fun <R> Any.call(vararg args: Any?): R = TODO()
fun println(message: Any?) {}
fun foo(action: (Int) -> Unit) {
action(10)
}
fun test1() {
call({ <!NI;CANNOT_INFER_PARAMETER_TYPE!>x<!> -> println(<!NI;DEBUG_INFO_ELEMENT_WITH_ERROR_TYPE!>x<!>::class) }) // x inside the lambda is inferred to `Nothing`, the lambda is `(Nothing) -> Unit`.
}
fun test2() {
::foo.<!NI;NEW_INFERENCE_NO_INFORMATION_FOR_PARAMETER!>call<!>({ <!NI;CANNOT_INFER_PARAMETER_TYPE!>x<!> -> println(<!NI;DEBUG_INFO_ELEMENT_WITH_ERROR_TYPE!>x<!>::class) })
}
@@ -0,0 +1,8 @@
package
public fun call(/*0*/ vararg x: kotlin.Any? /*kotlin.Array<out kotlin.Any?>*/): 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 </*0*/ R> kotlin.Any.call(/*0*/ vararg args: kotlin.Any? /*kotlin.Array<out kotlin.Any?>*/): R
@@ -8,7 +8,7 @@ fun <T, R> bar(f: (T) -> R) = f
fun test() { fun test() {
<!OI;TYPE_INFERENCE_PARAMETER_CONSTRAINT_ERROR!>foo<!> <!TYPE_MISMATCH!>{ <!UNRESOLVED_REFERENCE!>it<!> }<!> <!OI;TYPE_INFERENCE_PARAMETER_CONSTRAINT_ERROR!>foo<!> <!TYPE_MISMATCH!>{ <!UNRESOLVED_REFERENCE!>it<!> }<!>
<!OI;TYPE_INFERENCE_PARAMETER_CONSTRAINT_ERROR!>foo<!> <!TYPE_MISMATCH!>{ <!OI;CANNOT_INFER_PARAMETER_TYPE!>x<!> -> <!OI;DEBUG_INFO_ELEMENT_WITH_ERROR_TYPE!>x<!>}<!> <!OI;TYPE_INFERENCE_PARAMETER_CONSTRAINT_ERROR!>foo<!> <!TYPE_MISMATCH!>{ <!CANNOT_INFER_PARAMETER_TYPE!>x<!> -> <!DEBUG_INFO_ELEMENT_WITH_ERROR_TYPE!>x<!>}<!>
<!OI;TYPE_INFERENCE_PARAMETER_CONSTRAINT_ERROR!>foo<!> <!TYPE_MISMATCH!>{ x: Int -> x}<!> <!OI;TYPE_INFERENCE_PARAMETER_CONSTRAINT_ERROR!>foo<!> <!TYPE_MISMATCH!>{ x: Int -> x}<!>
<!NI;NEW_INFERENCE_NO_INFORMATION_FOR_PARAMETER, OI;TYPE_INFERENCE_NO_INFORMATION_FOR_PARAMETER!>bar<!> { <!DEBUG_INFO_ELEMENT_WITH_ERROR_TYPE!>it<!> <!DEBUG_INFO_ELEMENT_WITH_ERROR_TYPE!>+<!> 1 } <!NI;NEW_INFERENCE_NO_INFORMATION_FOR_PARAMETER, OI;TYPE_INFERENCE_NO_INFORMATION_FOR_PARAMETER!>bar<!> { <!DEBUG_INFO_ELEMENT_WITH_ERROR_TYPE!>it<!> <!DEBUG_INFO_ELEMENT_WITH_ERROR_TYPE!>+<!> 1 }
@@ -1,4 +1,3 @@
// !WITH_NEW_INFERENCE
// !CHECK_TYPE // !CHECK_TYPE
// FILE: Function.java // FILE: Function.java
public interface Function<E extends CharSequence, F extends java.util.Map<String, E>> { public interface Function<E extends CharSequence, F extends java.util.Map<String, E>> {
@@ -1,4 +1,3 @@
// !WITH_NEW_INFERENCE
// !CHECK_TYPE // !CHECK_TYPE
// FILE: Function.java // FILE: Function.java
public interface Function<E extends CharSequence, F extends java.util.Map<String, E>> { public interface Function<E extends CharSequence, F extends java.util.Map<String, E>> {
@@ -17,12 +16,12 @@ public class A {
// FILE: main.kt // FILE: main.kt
fun main() { fun main() {
A().foo <!TYPE_MISMATCH!>{ A().foo <!TYPE_MISMATCH!>{
<!OI;CANNOT_INFER_PARAMETER_TYPE, UNUSED_ANONYMOUS_PARAMETER!>x<!> -> <!CANNOT_INFER_PARAMETER_TYPE, UNUSED_ANONYMOUS_PARAMETER!>x<!> ->
"" ""
}<!> }<!>
A.bar <!TYPE_MISMATCH!>{ A.bar <!TYPE_MISMATCH!>{
<!OI;CANNOT_INFER_PARAMETER_TYPE, UNUSED_ANONYMOUS_PARAMETER!>x<!> -> <!CANNOT_INFER_PARAMETER_TYPE, UNUSED_ANONYMOUS_PARAMETER!>x<!> ->
"" ""
}<!> }<!>
} }
+2 -2
View File
@@ -3,6 +3,6 @@
// See EA-76890 / KT-10843: NPE during analysis // See EA-76890 / KT-10843: NPE during analysis
fun lambda(x : Int?) = x?.<!FUNCTION_CALL_EXPECTED, NI;NEW_INFERENCE_NO_INFORMATION_FOR_PARAMETER, NO_VALUE_FOR_PARAMETER, OI;TYPE_INFERENCE_NO_INFORMATION_FOR_PARAMETER!>let<!> <!DEBUG_INFO_ELEMENT_WITH_ERROR_TYPE!>l<!> { fun lambda(x : Int?) = x?.<!FUNCTION_CALL_EXPECTED, NI;NEW_INFERENCE_NO_INFORMATION_FOR_PARAMETER, NO_VALUE_FOR_PARAMETER, OI;TYPE_INFERENCE_NO_INFORMATION_FOR_PARAMETER!>let<!> <!DEBUG_INFO_ELEMENT_WITH_ERROR_TYPE!>l<!> {
<!OI;CANNOT_INFER_PARAMETER_TYPE!>y<!> -> <!OI;CANNOT_INFER_PARAMETER_TYPE!>y<!> ->
if (<!OI;DEBUG_INFO_ELEMENT_WITH_ERROR_TYPE!>y<!> <!NI;UNREACHABLE_CODE!><!NI;UNRESOLVED_REFERENCE, OI;DEBUG_INFO_ELEMENT_WITH_ERROR_TYPE!>><!> 0<!>) <!NI;UNREACHABLE_CODE!>return<!UNRESOLVED_REFERENCE!>@l<!> x<!> if (<!DEBUG_INFO_ELEMENT_WITH_ERROR_TYPE!>y<!> <!DEBUG_INFO_ELEMENT_WITH_ERROR_TYPE!>><!> 0) return<!UNRESOLVED_REFERENCE!>@l<!> x
<!NI;UNREACHABLE_CODE, OI;DEBUG_INFO_ELEMENT_WITH_ERROR_TYPE!>y<!> <!DEBUG_INFO_ELEMENT_WITH_ERROR_TYPE!>y<!>
}<!NOT_NULL_ASSERTION_ON_LAMBDA_EXPRESSION!>!!<!> }<!NOT_NULL_ASSERTION_ON_LAMBDA_EXPRESSION!>!!<!>
@@ -113,6 +113,6 @@ fun testTwoLambdas() {
fun f1(): (() -> Unit) -> (() -> Unit) -> Unit { fun f1(): (() -> Unit) -> (() -> Unit) -> Unit {
return { l1 -> return { l1 ->
<!NI;TYPE_MISMATCH, TYPE_MISMATCH!>l1() <!NI;TYPE_MISMATCH, TYPE_MISMATCH!>l1()
<!UNEXPECTED_TRAILING_LAMBDA_ON_A_NEW_LINE!>{ <!OI;CANNOT_INFER_PARAMETER_TYPE!>l2<!> -> <!OI;DEBUG_INFO_ELEMENT_WITH_ERROR_TYPE!><!NI;FUNCTION_EXPECTED!>l2<!>()<!> }<!><!> <!UNEXPECTED_TRAILING_LAMBDA_ON_A_NEW_LINE!>{ <!CANNOT_INFER_PARAMETER_TYPE!>l2<!> -> <!NI;DEBUG_INFO_MISSING_UNRESOLVED, OI;DEBUG_INFO_ELEMENT_WITH_ERROR_TYPE!>l2()<!> }<!><!>
} }
} }
@@ -7,4 +7,4 @@ object X2
fun <T1> foo(x: T1, f: (T1) -> T1) = X1 fun <T1> foo(x: T1, f: (T1) -> T1) = X1
fun <T2> foo(xf: () -> T2, f: (T2) -> T2) = X2 fun <T2> foo(xf: () -> T2, f: (T2) -> T2) = X2
val test: X2 = <!NI;OVERLOAD_RESOLUTION_AMBIGUITY, OI;CANNOT_COMPLETE_RESOLVE!>foo<!>({ 0 }, { <!OI;CANNOT_INFER_PARAMETER_TYPE!>it<!> -> <!OI;DEBUG_INFO_ELEMENT_WITH_ERROR_TYPE!>it<!> <!NI;UNREACHABLE_CODE!><!OI;DEBUG_INFO_ELEMENT_WITH_ERROR_TYPE!>+<!> 1<!> }) val test: X2 = <!NI;OVERLOAD_RESOLUTION_AMBIGUITY, OI;CANNOT_COMPLETE_RESOLVE!>foo<!>({ 0 }, { <!OI;CANNOT_INFER_PARAMETER_TYPE!>it<!> -> <!DEBUG_INFO_ELEMENT_WITH_ERROR_TYPE!>it<!> <!DEBUG_INFO_ELEMENT_WITH_ERROR_TYPE!>+<!> 1 })
@@ -10133,6 +10133,11 @@ public class DiagnosticsTestGenerated extends AbstractDiagnosticsTest {
runTest("compiler/testData/diagnostics/tests/inference/noInformationForParameter.kt"); 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") @TestMetadata("nullableTypeArgumentWithNotNullUpperBound.kt")
public void testNullableTypeArgumentWithNotNullUpperBound() throws Exception { public void testNullableTypeArgumentWithNotNullUpperBound() throws Exception {
runTest("compiler/testData/diagnostics/tests/inference/nullableTypeArgumentWithNotNullUpperBound.kt"); 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"); 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") @TestMetadata("lambdaNothingAndExpectedType.kt")
public void testLambdaNothingAndExpectedType() throws Exception { public void testLambdaNothingAndExpectedType() throws Exception {
runTest("compiler/testData/diagnostics/tests/inference/nothingType/lambdaNothingAndExpectedType.kt"); runTest("compiler/testData/diagnostics/tests/inference/nothingType/lambdaNothingAndExpectedType.kt");
@@ -10128,6 +10128,11 @@ public class DiagnosticsUsingJavacTestGenerated extends AbstractDiagnosticsUsing
runTest("compiler/testData/diagnostics/tests/inference/noInformationForParameter.kt"); 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") @TestMetadata("nullableTypeArgumentWithNotNullUpperBound.kt")
public void testNullableTypeArgumentWithNotNullUpperBound() throws Exception { public void testNullableTypeArgumentWithNotNullUpperBound() throws Exception {
runTest("compiler/testData/diagnostics/tests/inference/nullableTypeArgumentWithNotNullUpperBound.kt"); 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"); 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") @TestMetadata("lambdaNothingAndExpectedType.kt")
public void testLambdaNothingAndExpectedType() throws Exception { public void testLambdaNothingAndExpectedType() throws Exception {
runTest("compiler/testData/diagnostics/tests/inference/nothingType/lambdaNothingAndExpectedType.kt"); runTest("compiler/testData/diagnostics/tests/inference/nothingType/lambdaNothingAndExpectedType.kt");