[NI] Report error about unknown parameter type of lambda argument
KT-34335
This commit is contained in:
+8
-2
@@ -21,7 +21,8 @@ interface InferenceSession {
|
||||
override fun currentConstraintSystem(): ConstraintStorage = ConstraintStorage.Empty
|
||||
override fun inferPostponedVariables(
|
||||
lambda: ResolvedLambdaAtom,
|
||||
initialStorage: ConstraintStorage
|
||||
initialStorage: ConstraintStorage,
|
||||
diagnosticsHolder: KotlinDiagnosticsHolder
|
||||
): Map<TypeConstructor, UnwrappedType> = 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<TypeConstructor, UnwrappedType>
|
||||
fun inferPostponedVariables(
|
||||
lambda: ResolvedLambdaAtom,
|
||||
initialStorage: ConstraintStorage,
|
||||
diagnosticsHolder: KotlinDiagnosticsHolder
|
||||
): Map<TypeConstructor, UnwrappedType>
|
||||
|
||||
fun writeOnlyStubs(callInfo: SingleCallResolutionResult): Boolean
|
||||
fun callCompleted(resolvedAtom: ResolvedAtom): Boolean
|
||||
fun shouldCompleteResolvedSubAtomsOf(resolvedCallAtom: ResolvedCallAtom): Boolean
|
||||
|
||||
+2
-1
@@ -131,7 +131,8 @@ class KotlinCallCompleter(
|
||||
constraintSystem.asConstraintSystemCompleterContext(),
|
||||
completionMode,
|
||||
listOf(resolvedCallAtom),
|
||||
returnType
|
||||
returnType,
|
||||
diagnosticsHolder
|
||||
) {
|
||||
if (collectAllCandidatesMode) {
|
||||
it.setEmptyAnalyzedResults()
|
||||
|
||||
+16
-4
@@ -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("<Unknown lambda parameter type>")
|
||||
}
|
||||
} ?: 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
|
||||
|
||||
+2
-2
@@ -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
|
||||
|
||||
+35
-6
@@ -49,13 +49,34 @@ class KotlinConstraintSystemCompleter(
|
||||
completionMode: ConstraintSystemCompletionMode,
|
||||
topLevelAtoms: List<ResolvedAtom>,
|
||||
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<ResolvedAtom>) {
|
||||
runCompletion(c, ConstraintSystemCompletionMode.FULL, topLevelAtoms, topLevelType, collectVariablesFromContext = true) {
|
||||
fun completeConstraintSystem(
|
||||
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")
|
||||
}
|
||||
}
|
||||
@@ -65,6 +86,7 @@ class KotlinConstraintSystemCompleter(
|
||||
completionMode: ConstraintSystemCompletionMode,
|
||||
topLevelAtoms: List<ResolvedAtom>,
|
||||
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<ResolvedAtom>,
|
||||
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
|
||||
|
||||
+9
@@ -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)
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user