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