K2/PCLA: add explicit withPCLASession: Boolean parameter to analyzeLambda

This commit is contained in:
Mikhail Glukhikh
2024-01-23 17:50:43 +01:00
committed by Space Team
parent c7bc8547da
commit f0ac963474
5 changed files with 29 additions and 24 deletions
@@ -118,6 +118,7 @@ class FirOverloadByLambdaReturnTypeResolver(
firstAtom, firstAtom,
firstCandidate, firstCandidate,
forOverloadByLambdaReturnType = true, forOverloadByLambdaReturnType = true,
withPCLASession = false,
) )
while (iterator.hasNext()) { while (iterator.hasNext()) {
val (candidate, atom) = iterator.next() val (candidate, atom) = iterator.next()
@@ -30,7 +30,6 @@ import org.jetbrains.kotlin.resolve.calls.inference.model.VariableWithConstraint
import org.jetbrains.kotlin.resolve.calls.model.PostponedAtomWithRevisableExpectedType import org.jetbrains.kotlin.resolve.calls.model.PostponedAtomWithRevisableExpectedType
import org.jetbrains.kotlin.types.model.TypeConstructorMarker import org.jetbrains.kotlin.types.model.TypeConstructorMarker
import org.jetbrains.kotlin.types.model.TypeVariableMarker import org.jetbrains.kotlin.types.model.TypeVariableMarker
import org.jetbrains.kotlin.types.model.TypeVariableTypeConstructorMarker
import org.jetbrains.kotlin.utils.addIfNotNull import org.jetbrains.kotlin.utils.addIfNotNull
import org.jetbrains.kotlin.utils.addToStdlib.filterIsInstanceWithChecker import org.jetbrains.kotlin.utils.addToStdlib.filterIsInstanceWithChecker
@@ -47,7 +46,7 @@ class ConstraintSystemCompleter(components: BodyResolveComponents, private val c
candidateReturnType: ConeKotlinType, candidateReturnType: ConeKotlinType,
context: ResolutionContext, context: ResolutionContext,
collectVariablesFromContext: Boolean = false, collectVariablesFromContext: Boolean = false,
analyze: (PostponedResolvedAtom) -> Unit, analyze: (PostponedResolvedAtom, Boolean) -> Unit,
) = c.runCompletion(completionMode, topLevelAtoms, candidateReturnType, context, collectVariablesFromContext, analyze) ) = c.runCompletion(completionMode, topLevelAtoms, candidateReturnType, context, collectVariablesFromContext, analyze)
private fun ConstraintSystemCompletionContext.runCompletion( private fun ConstraintSystemCompletionContext.runCompletion(
@@ -56,7 +55,7 @@ class ConstraintSystemCompleter(components: BodyResolveComponents, private val c
topLevelType: ConeKotlinType, topLevelType: ConeKotlinType,
context: ResolutionContext, context: ResolutionContext,
collectVariablesFromContext: Boolean = false, collectVariablesFromContext: Boolean = false,
analyze: (PostponedResolvedAtom) -> Unit, analyze: (PostponedResolvedAtom, Boolean) -> Unit,
) { ) {
val topLevelTypeVariables = topLevelType.extractTypeVariables() val topLevelTypeVariables = topLevelType.extractTypeVariables()
@@ -75,8 +74,10 @@ class ConstraintSystemCompleter(components: BodyResolveComponents, private val c
) return ) return
// Stage 1: analyze postponed arguments with fixed parameter types // Stage 1: analyze postponed arguments with fixed parameter types
if (analyzeArgumentWithFixedParameterTypes(languageVersionSettings, postponedArguments, analyze)) if (analyzeArgumentWithFixedParameterTypes(languageVersionSettings, postponedArguments) {
continue analyze(it, /* withPCLASession = */ false)
}
) continue
val isThereAnyReadyForFixationVariable = findFirstVariableForFixation( val isThereAnyReadyForFixationVariable = findFirstVariableForFixation(
collectVariablesFromContext, collectVariablesFromContext,
@@ -141,8 +142,10 @@ class ConstraintSystemCompleter(components: BodyResolveComponents, private val c
} }
// Stage 5: analyze the next ready postponed argument // Stage 5: analyze the next ready postponed argument
if (analyzeNextReadyPostponedArgument(languageVersionSettings, postponedArguments, completionMode, analyze)) if (analyzeNextReadyPostponedArgument(languageVersionSettings, postponedArguments, completionMode) {
continue analyze(it, /* withPCLASession = */ false)
}
) continue
// Stage 6: fix next ready type variable with proper constraints // Stage 6: fix next ready type variable with proper constraints
if (fixNextReadyVariable(completionMode, topLevelAtoms, topLevelType, collectVariablesFromContext, postponedArguments)) if (fixNextReadyVariable(completionMode, topLevelAtoms, topLevelType, collectVariablesFromContext, postponedArguments))
@@ -159,8 +162,10 @@ class ConstraintSystemCompleter(components: BodyResolveComponents, private val c
if (completionMode == ConstraintSystemCompletionMode.PCLA_POSTPONED_CALL) { if (completionMode == ConstraintSystemCompletionMode.PCLA_POSTPONED_CALL) {
// Complete all lambdas, maybe with fixing type variables used as top-level input types. // Complete all lambdas, maybe with fixing type variables used as top-level input types.
// It's necessary because we need to process all data-flow info before going to the next statement. // It's necessary because we need to process all data-flow info before going to the next statement.
if (analyzeRemainingNotAnalyzedPostponedArgument(postponedArguments, analyze)) if (analyzeRemainingNotAnalyzedPostponedArgument(postponedArguments) {
continue analyze(it, /* withPCLASession = */ false)
}
) continue
} }
// Stage 8: report "not enough information" for uninferred type variables // Stage 8: report "not enough information" for uninferred type variables
@@ -176,8 +181,10 @@ class ConstraintSystemCompleter(components: BodyResolveComponents, private val c
// Stage 9: force analysis of remaining not analyzed postponed arguments and rerun stages if there are // Stage 9: force analysis of remaining not analyzed postponed arguments and rerun stages if there are
if (completionMode.allLambdasShouldBeAnalyzed) { if (completionMode.allLambdasShouldBeAnalyzed) {
if (analyzeRemainingNotAnalyzedPostponedArgument(postponedArguments, analyze)) if (analyzeRemainingNotAnalyzedPostponedArgument(postponedArguments) {
continue analyze(it, /* withPCLASession = */ false)
}
) continue
} }
break break
@@ -236,7 +243,7 @@ class ConstraintSystemCompleter(components: BodyResolveComponents, private val c
private fun ConstraintSystemCompletionContext.tryToCompleteWithPCLA( private fun ConstraintSystemCompletionContext.tryToCompleteWithPCLA(
completionMode: ConstraintSystemCompletionMode, completionMode: ConstraintSystemCompletionMode,
postponedArguments: List<PostponedResolvedAtom>, postponedArguments: List<PostponedResolvedAtom>,
analyze: (PostponedResolvedAtom) -> Unit, analyze: (PostponedResolvedAtom, Boolean) -> Unit,
): Boolean { ): Boolean {
if (!completionMode.allLambdasShouldBeAnalyzed) return false if (!completionMode.allLambdasShouldBeAnalyzed) return false
@@ -250,7 +257,7 @@ class ConstraintSystemCompleter(components: BodyResolveComponents, private val c
val notFixedInputTypeVariables = argument.inputTypes.flatMap { it.extractTypeVariables() }.filter { it !in fixedTypeVariables } val notFixedInputTypeVariables = argument.inputTypes.flatMap { it.extractTypeVariables() }.filter { it !in fixedTypeVariables }
if (notFixedInputTypeVariables.isEmpty()) continue if (notFixedInputTypeVariables.isEmpty()) continue
analyze(argument) analyze(argument, /* withPCLASession = */ true)
anyAnalyzed = true anyAnalyzed = true
} }
@@ -182,8 +182,8 @@ class FirCallCompleter(
listOf(call), listOf(call),
initialType, initialType,
transformer.resolutionContext transformer.resolutionContext
) { ) { atom, withPCLASession ->
analyzer.analyze(candidate.system, it, candidate) analyzer.analyze(candidate.system, atom, candidate, withPCLASession)
} }
} }
@@ -162,7 +162,7 @@ class FirDelegatedPropertyInferenceSession(
ConstraintSystemCompletionMode.FULL, ConstraintSystemCompletionMode.FULL,
notCompletedCalls as List<FirStatement>, notCompletedCalls as List<FirStatement>,
unitType, resolutionContext unitType, resolutionContext
) { lambdaAtom -> ) { lambdaAtom, withPCLASession ->
// Reversed here bc we want top-most call to avoid exponential visit // Reversed here bc we want top-most call to avoid exponential visit
val containingCandidateForLambda = notCompletedCalls.asReversed().first { val containingCandidateForLambda = notCompletedCalls.asReversed().first {
var found = false var found = false
@@ -177,6 +177,7 @@ class FirDelegatedPropertyInferenceSession(
parentSystem, parentSystem,
lambdaAtom, lambdaAtom,
containingCandidateForLambda, containingCandidateForLambda,
withPCLASession
) )
} }
} }
@@ -55,16 +55,17 @@ class PostponedArgumentsAnalyzer(
c: PostponedArgumentsAnalyzerContext, c: PostponedArgumentsAnalyzerContext,
argument: PostponedResolvedAtom, argument: PostponedResolvedAtom,
candidate: Candidate, candidate: Candidate,
withPCLASession: Boolean,
) { ) {
when (argument) { when (argument) {
is ResolvedLambdaAtom -> is ResolvedLambdaAtom ->
analyzeLambda(c, argument, candidate, forOverloadByLambdaReturnType = false) analyzeLambda(c, argument, candidate, forOverloadByLambdaReturnType = false, withPCLASession)
is LambdaWithTypeVariableAsExpectedTypeAtom -> is LambdaWithTypeVariableAsExpectedTypeAtom ->
analyzeLambda( analyzeLambda(
c, c,
argument.transformToResolvedLambda(c.getBuilder(), resolutionContext), argument.transformToResolvedLambda(c.getBuilder(), resolutionContext),
candidate, forOverloadByLambdaReturnType = false candidate, forOverloadByLambdaReturnType = false, withPCLASession
) )
is ResolvedCallableReferenceAtom -> processCallableReference(argument, candidate) is ResolvedCallableReferenceAtom -> processCallableReference(argument, candidate)
@@ -106,6 +107,7 @@ class PostponedArgumentsAnalyzer(
lambda: ResolvedLambdaAtom, lambda: ResolvedLambdaAtom,
candidate: Candidate, candidate: Candidate,
forOverloadByLambdaReturnType: Boolean, forOverloadByLambdaReturnType: Boolean,
withPCLASession: Boolean,
//diagnosticHolder: KotlinDiagnosticsHolder //diagnosticHolder: KotlinDiagnosticsHolder
): ReturnArgumentsAnalysisResult { ): ReturnArgumentsAnalysisResult {
// TODO: replace with `require(!lambda.analyzed)` when KT-54767 will be fixed // TODO: replace with `require(!lambda.analyzed)` when KT-54767 will be fixed
@@ -142,12 +144,6 @@ class PostponedArgumentsAnalyzer(
else -> null else -> null
} }
val withPCLASession =
lambda.inputTypes
.any { inputType ->
with(c) { inputType.extractTypeVariables() }.any(c.notFixedTypeVariables::contains)
}
val results = lambdaAnalyzer.analyzeAndGetLambdaReturnArguments( val results = lambdaAnalyzer.analyzeAndGetLambdaReturnArguments(
lambda, lambda,
receiver, receiver,