NI: some review fixes for improved postponed arguments analysis

This commit is contained in:
Victor Petukhov
2020-05-25 12:41:38 +03:00
parent 756326cefe
commit e70242f6f1
3 changed files with 29 additions and 30 deletions
@@ -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
}
@@ -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(
@@ -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 })
/*