NI: some review fixes for improved postponed arguments analysis
This commit is contained in:
+11
-11
@@ -111,10 +111,13 @@ class KotlinConstraintSystemCompleter(
|
||||
TypeVariableDependencyInformationProvider(notFixedTypeVariables, postponedArguments, topLevelType, this)
|
||||
|
||||
// Stage 2: collect parameter types for postponed arguments
|
||||
postponedArgumentInputTypesResolver.collectParameterTypesAndBuildNewExpectedTypes(
|
||||
val wasBuiltNewExpectedTypeForSomeArgument = postponedArgumentInputTypesResolver.collectParameterTypesAndBuildNewExpectedTypes(
|
||||
asPostponedArgumentInputTypesResolverContext(), postponedArgumentsWithRevisableType, completionMode, dependencyProvider
|
||||
)
|
||||
|
||||
if (wasBuiltNewExpectedTypeForSomeArgument)
|
||||
continue
|
||||
|
||||
if (completionMode == ConstraintSystemCompletionMode.FULL) {
|
||||
// Stage 3: fix variables for parameter types of all postponed arguments
|
||||
for (argument in postponedArguments) {
|
||||
@@ -133,32 +136,29 @@ class KotlinConstraintSystemCompleter(
|
||||
|
||||
// Stage 4: create atoms with revised expected types if needed
|
||||
for (argument in postponedArgumentsWithRevisableType) {
|
||||
postponedArgumentInputTypesResolver.transformToAtomWithNewFunctionalExpectedType(
|
||||
val wasTransformedSomeArgument = postponedArgumentInputTypesResolver.transformToAtomWithNewFunctionalExpectedType(
|
||||
asPostponedArgumentInputTypesResolverContext(), argument, diagnosticsHolder
|
||||
)
|
||||
|
||||
if (wasTransformedSomeArgument)
|
||||
continue@completion
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* We should get not analyzed postponed arguments again because they can be changed by
|
||||
* the stage of fixation type variables for parameters or analysing postponed arguments with fixed parameter types (see stage #1 and #4)
|
||||
*/
|
||||
val revisedPostponedArguments = getOrderedNotAnalyzedPostponedArguments(topLevelAtoms)
|
||||
|
||||
// Stage 5: analyze the next ready postponed argument
|
||||
if (analyzeNextReadyPostponedArgument(revisedPostponedArguments, completionMode, analyze))
|
||||
if (analyzeNextReadyPostponedArgument(postponedArguments, completionMode, analyze))
|
||||
continue
|
||||
|
||||
// Stage 6: fix type variables – fix if possible or report not enough information (if completion mode is full)
|
||||
val wasFixedSomeVariable = fixVariablesOrReportNotEnoughInformation(
|
||||
completionMode, topLevelAtoms, topLevelType, collectVariablesFromContext, revisedPostponedArguments, diagnosticsHolder
|
||||
completionMode, topLevelAtoms, topLevelType, collectVariablesFromContext, postponedArguments, diagnosticsHolder
|
||||
)
|
||||
if (wasFixedSomeVariable)
|
||||
continue
|
||||
|
||||
// Stage 7: force analysis of remaining not analyzed postponed arguments and rerun stages if there are
|
||||
if (completionMode == ConstraintSystemCompletionMode.FULL) {
|
||||
if (analyzeRemainingNotAnalyzedPostponedArgument(revisedPostponedArguments, analyze))
|
||||
if (analyzeRemainingNotAnalyzedPostponedArgument(postponedArguments, analyze))
|
||||
continue
|
||||
}
|
||||
|
||||
|
||||
+16
-17
@@ -304,7 +304,7 @@ class PostponedArgumentInputTypesResolver(
|
||||
else -> parameterTypesInfo.annotations
|
||||
}
|
||||
|
||||
val nexExpectedType = KotlinTypeFactory.simpleType(
|
||||
val newExpectedType = KotlinTypeFactory.simpleType(
|
||||
annotations,
|
||||
functionalConstructor,
|
||||
variablesForParameterTypes + variableForReturnType.defaultType.asTypeProjection(),
|
||||
@@ -312,12 +312,12 @@ class PostponedArgumentInputTypesResolver(
|
||||
)
|
||||
|
||||
getBuilder().addSubtypeConstraint(
|
||||
nexExpectedType,
|
||||
newExpectedType,
|
||||
expectedType,
|
||||
ArgumentConstraintPosition(argument.atom)
|
||||
)
|
||||
|
||||
return nexExpectedType
|
||||
return newExpectedType
|
||||
}
|
||||
|
||||
fun collectParameterTypesAndBuildNewExpectedTypes(
|
||||
@@ -325,7 +325,7 @@ class PostponedArgumentInputTypesResolver(
|
||||
postponedArguments: List<PostponedAtomWithRevisableExpectedType>,
|
||||
completionMode: KotlinConstraintSystemCompleter.ConstraintSystemCompletionMode,
|
||||
dependencyProvider: TypeVariableDependencyInformationProvider
|
||||
) {
|
||||
): Boolean {
|
||||
// We can collect parameter types from declaration in any mode, they can't change during completion.
|
||||
val postponedArgumentsToCollectTypesFromDeclaredParameters = postponedArguments
|
||||
.filterIsInstance<LambdaWithTypeVariableAsExpectedTypeAtom>()
|
||||
@@ -349,27 +349,24 @@ class PostponedArgumentInputTypesResolver(
|
||||
postponedArguments
|
||||
}
|
||||
|
||||
do {
|
||||
val wasTransformedSomePostponedArgument =
|
||||
postponedArgumentsToCollectParameterTypesAndBuildNewExpectedType.filter { it.revisedExpectedType == null }.any { argument ->
|
||||
val parameterTypesInfo =
|
||||
c.extractParameterTypesInfo(argument, postponedArguments, dependencyProvider) ?: return@any false
|
||||
val newExpectedType =
|
||||
c.buildNewFunctionalExpectedType(argument, parameterTypesInfo) ?: return@any false
|
||||
return postponedArgumentsToCollectParameterTypesAndBuildNewExpectedType.filter { it.revisedExpectedType == null }.any { argument ->
|
||||
val parameterTypesInfo =
|
||||
c.extractParameterTypesInfo(argument, postponedArguments, dependencyProvider) ?: return@any false
|
||||
val newExpectedType =
|
||||
c.buildNewFunctionalExpectedType(argument, parameterTypesInfo) ?: return@any false
|
||||
|
||||
argument.revisedExpectedType = newExpectedType
|
||||
argument.revisedExpectedType = newExpectedType
|
||||
|
||||
true
|
||||
}
|
||||
} while (wasTransformedSomePostponedArgument)
|
||||
true
|
||||
}
|
||||
}
|
||||
|
||||
fun transformToAtomWithNewFunctionalExpectedType(
|
||||
c: Context,
|
||||
argument: PostponedAtomWithRevisableExpectedType,
|
||||
diagnosticsHolder: KotlinDiagnosticsHolder
|
||||
) {
|
||||
val revisedExpectedType = argument.revisedExpectedType?.takeIf { it.isFunctionOrKFunctionTypeWithAnySuspendability } ?: return
|
||||
): Boolean {
|
||||
val revisedExpectedType = argument.revisedExpectedType?.takeIf { it.isFunctionOrKFunctionTypeWithAnySuspendability } ?: return false
|
||||
|
||||
when (argument) {
|
||||
is PostponedCallableReferenceAtom ->
|
||||
@@ -380,6 +377,8 @@ class PostponedArgumentInputTypesResolver(
|
||||
argument.transformToResolvedLambda(c.getBuilder(), diagnosticsHolder, revisedExpectedType)
|
||||
else -> throw IllegalStateException("Unsupported postponed argument type of $argument")
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
private fun getAllDeeplyRelatedTypeVariables(
|
||||
|
||||
Vendored
+2
-2
@@ -119,8 +119,8 @@ fun main() {
|
||||
* K <: (A) -> Unit -> TypeVariable(_RP1) >: A
|
||||
* K >: (C) -> TypeVariable(_R) -> TypeVariable(_RP1) <: C
|
||||
*/
|
||||
val x12 = selectC(id <!TYPE_MISMATCH, TYPE_MISMATCH, TYPE_MISMATCH, TYPE_MISMATCH, TYPE_MISMATCH, TYPE_MISMATCH, TYPE_MISMATCH, TYPE_MISMATCH, TYPE_MISMATCH!>{ <!DEBUG_INFO_EXPRESSION_TYPE("C")!>it<!> }<!>, id <!TYPE_MISMATCH, TYPE_MISMATCH, TYPE_MISMATCH, TYPE_MISMATCH!>{ x: B -> }<!><!NO_VALUE_FOR_PARAMETER!>)<!>
|
||||
val x13 = selectA(id <!TYPE_MISMATCH, TYPE_MISMATCH, TYPE_MISMATCH, TYPE_MISMATCH, TYPE_MISMATCH, TYPE_MISMATCH, TYPE_MISMATCH, TYPE_MISMATCH, TYPE_MISMATCH!>{ <!DEBUG_INFO_EXPRESSION_TYPE("A")!>it<!> }<!>, id <!TYPE_MISMATCH, TYPE_MISMATCH, TYPE_MISMATCH, TYPE_MISMATCH!>{ x: C -> }<!><!NO_VALUE_FOR_PARAMETER!>)<!>
|
||||
val x12 = selectC(id <!TYPE_MISMATCH, TYPE_MISMATCH, TYPE_MISMATCH, TYPE_MISMATCH, TYPE_MISMATCH, TYPE_MISMATCH, TYPE_MISMATCH, TYPE_MISMATCH, TYPE_MISMATCH!>{ <!DEBUG_INFO_EXPRESSION_TYPE("C")!>it<!> }<!>, id <!TYPE_MISMATCH, TYPE_MISMATCH, TYPE_MISMATCH!>{ x: B -> }<!><!NO_VALUE_FOR_PARAMETER!>)<!>
|
||||
val x13 = selectA(id <!TYPE_MISMATCH, TYPE_MISMATCH, TYPE_MISMATCH, TYPE_MISMATCH, TYPE_MISMATCH, TYPE_MISMATCH, TYPE_MISMATCH, TYPE_MISMATCH, TYPE_MISMATCH!>{ <!DEBUG_INFO_EXPRESSION_TYPE("A")!>it<!> }<!>, id <!TYPE_MISMATCH, TYPE_MISMATCH, TYPE_MISMATCH!>{ x: C -> }<!><!NO_VALUE_FOR_PARAMETER!>)<!>
|
||||
val x14 = selectC(id { <!DEBUG_INFO_EXPRESSION_TYPE("C")!>it<!> }, id { x: A -> }, { x -> x })
|
||||
val x15 = selectC(id { <!DEBUG_INFO_EXPRESSION_TYPE("C")!>it<!> }, { x: A -> }, id { x -> x })
|
||||
/*
|
||||
|
||||
Reference in New Issue
Block a user