[NI] Postpone calls with not enough information in builder inference
This commit is contained in:
+48
-15
@@ -19,18 +19,12 @@ import org.jetbrains.kotlin.resolve.calls.context.BasicCallResolutionContext
|
||||
import org.jetbrains.kotlin.resolve.calls.inference.components.KotlinConstraintSystemCompleter
|
||||
import org.jetbrains.kotlin.resolve.calls.inference.components.NewTypeSubstitutor
|
||||
import org.jetbrains.kotlin.resolve.calls.inference.components.NewTypeSubstitutorByConstructorMap
|
||||
import org.jetbrains.kotlin.resolve.calls.inference.model.ConstraintKind
|
||||
import org.jetbrains.kotlin.resolve.calls.inference.model.ConstraintStorage
|
||||
import org.jetbrains.kotlin.resolve.calls.inference.model.NewConstraintSystemImpl
|
||||
import org.jetbrains.kotlin.resolve.calls.inference.model.NewTypeVariable
|
||||
import org.jetbrains.kotlin.resolve.calls.inference.model.*
|
||||
import org.jetbrains.kotlin.resolve.calls.model.*
|
||||
import org.jetbrains.kotlin.resolve.calls.tower.*
|
||||
import org.jetbrains.kotlin.resolve.calls.util.FakeCallableDescriptorForObject
|
||||
import org.jetbrains.kotlin.resolve.deprecation.DeprecationResolver
|
||||
import org.jetbrains.kotlin.types.StubType
|
||||
import org.jetbrains.kotlin.types.TypeApproximator
|
||||
import org.jetbrains.kotlin.types.TypeConstructor
|
||||
import org.jetbrains.kotlin.types.UnwrappedType
|
||||
import org.jetbrains.kotlin.types.*
|
||||
import org.jetbrains.kotlin.types.expressions.DoubleColonExpressionResolver
|
||||
import org.jetbrains.kotlin.types.expressions.ExpressionTypingServices
|
||||
import org.jetbrains.kotlin.utils.addToStdlib.cast
|
||||
@@ -58,7 +52,20 @@ class CoroutineInferenceSession(
|
||||
private val commonCalls = arrayListOf<PSICompletedCallInfo>()
|
||||
private val diagnostics = arrayListOf<KotlinCallDiagnostic>()
|
||||
|
||||
override fun shouldRunCompletion(candidate: KotlinResolutionCandidate): Boolean = true
|
||||
override fun shouldRunCompletion(candidate: KotlinResolutionCandidate): Boolean {
|
||||
val system = candidate.getSystem() as NewConstraintSystemImpl
|
||||
val storage = system.getBuilder().currentStorage()
|
||||
fun ResolvedAtom.hasPostponed(): Boolean {
|
||||
if (this is PostponedResolvedAtom && !analyzed) return true
|
||||
return subResolvedAtoms?.any { it.hasPostponed() } == true
|
||||
}
|
||||
|
||||
return !storage.notFixedTypeVariables.keys.any {
|
||||
val variable = storage.allTypeVariables[it]
|
||||
val isPostponed = variable != null && variable in storage.postponedTypeVariables
|
||||
!isPostponed && !kotlinConstraintSystemCompleter.variableFixationFinder.isTypeVariableHasProperConstraint(system, it)
|
||||
} || candidate.getSubResolvedAtoms().any { it.hasPostponed() }
|
||||
}
|
||||
|
||||
override fun addCompletedCallInfo(callInfo: CompletedCallInfo) {
|
||||
require(callInfo is PSICompletedCallInfo) { "Wrong instance of callInfo: $callInfo" }
|
||||
@@ -100,7 +107,11 @@ class CoroutineInferenceSession(
|
||||
val commonSystem = buildCommonSystem(initialStorage)
|
||||
|
||||
val context = commonSystem.asConstraintSystemCompleterContext()
|
||||
kotlinConstraintSystemCompleter.completeConstraintSystem(context, builtIns.unitType)
|
||||
kotlinConstraintSystemCompleter.completeConstraintSystem(
|
||||
context,
|
||||
builtIns.unitType,
|
||||
partiallyResolvedCallsInfo.map { it.callResolutionResult.resultCallAtom }
|
||||
)
|
||||
|
||||
updateCalls(lambda, commonSystem)
|
||||
|
||||
@@ -132,7 +143,7 @@ class CoroutineInferenceSession(
|
||||
*
|
||||
* while substitutor from parameter map non-fixed types to the original type variable
|
||||
* */
|
||||
val callSubstitutor = storage.buildResultingSubstitutor(commonSystem) // substitutor only for fixed variables
|
||||
val callSubstitutor = storage.buildResultingSubstitutor(commonSystem, transformTypeVariablesToErrorTypes = false)
|
||||
|
||||
for (initialConstraint in storage.initialConstraints) {
|
||||
val lower = nonFixedToVariablesSubstitutor.safeSubstitute(callSubstitutor.safeSubstitute(initialConstraint.a as UnwrappedType)) // TODO: SUB
|
||||
@@ -164,6 +175,9 @@ class CoroutineInferenceSession(
|
||||
for (call in commonCalls) {
|
||||
integrateConstraints(commonSystem, call.callResolutionResult.constraintSystem, nonFixedToVariablesSubstitutor)
|
||||
}
|
||||
for (call in partiallyResolvedCallsInfo) {
|
||||
integrateConstraints(commonSystem, call.callResolutionResult.constraintSystem, nonFixedToVariablesSubstitutor)
|
||||
}
|
||||
for (diagnostic in diagnostics) {
|
||||
commonSystem.addError(diagnostic)
|
||||
}
|
||||
@@ -192,6 +206,16 @@ class CoroutineInferenceSession(
|
||||
}
|
||||
|
||||
val lambdaAtomCompleter = createResolvedAtomCompleter(nonFixedTypesToResultSubstitutor, topLevelCallContext)
|
||||
for (callInfo in partiallyResolvedCallsInfo) {
|
||||
val resolvedCall = completeCall(callInfo, lambdaAtomCompleter) ?: continue
|
||||
kotlinToResolvedCallTransformer.reportCallDiagnostic(
|
||||
callInfo.context,
|
||||
trace,
|
||||
callInfo.callResolutionResult.resultCallAtom,
|
||||
resolvedCall.resultingDescriptor,
|
||||
commonSystem.diagnostics
|
||||
)
|
||||
}
|
||||
lambdaAtomCompleter.completeAll(lambda)
|
||||
}
|
||||
|
||||
@@ -203,20 +227,29 @@ class CoroutineInferenceSession(
|
||||
val resultingCallSubstitutor = completedCall.callResolutionResult.constraintSystem.fixedTypeVariables.entries
|
||||
.associate { it.key to nonFixedTypesToResultSubstitutor.safeSubstitute(it.value as UnwrappedType) } // TODO: SUB
|
||||
|
||||
val resultingSubstitutor = NewTypeSubstitutorByConstructorMap((resultingCallSubstitutor + nonFixedTypesToResult).cast()) // TODO: SUB
|
||||
val resultingSubstitutor =
|
||||
NewTypeSubstitutorByConstructorMap((resultingCallSubstitutor + nonFixedTypesToResult).cast()) // TODO: SUB
|
||||
|
||||
val atomCompleter = createResolvedAtomCompleter(resultingSubstitutor, completedCall.context)
|
||||
val resultCallAtom = completedCall.callResolutionResult.resultCallAtom
|
||||
|
||||
completeCall(completedCall, atomCompleter)
|
||||
}
|
||||
|
||||
private fun completeCall(
|
||||
callInfo: CallInfo,
|
||||
atomCompleter: ResolvedAtomCompleter
|
||||
): ResolvedCall<*>? {
|
||||
val resultCallAtom = callInfo.callResolutionResult.resultCallAtom
|
||||
resultCallAtom.subResolvedAtoms?.forEach { subResolvedAtom ->
|
||||
atomCompleter.completeAll(subResolvedAtom)
|
||||
}
|
||||
atomCompleter.completeResolvedCall(resultCallAtom, completedCall.callResolutionResult.diagnostics)
|
||||
val resolvedCall = atomCompleter.completeResolvedCall(resultCallAtom, callInfo.callResolutionResult.diagnostics)
|
||||
|
||||
val callTrace = completedCall.context.trace
|
||||
val callTrace = callInfo.context.trace
|
||||
if (callTrace is TemporaryBindingTrace) {
|
||||
callTrace.commit()
|
||||
}
|
||||
return resolvedCall
|
||||
}
|
||||
|
||||
private fun createResolvedAtomCompleter(
|
||||
|
||||
+13
-7
@@ -26,7 +26,7 @@ abstract class ManyCandidatesResolver<D : CallableDescriptor>(
|
||||
protected val callComponents: KotlinCallComponents,
|
||||
val builtIns: KotlinBuiltIns
|
||||
) : InferenceSession {
|
||||
private val partiallyResolvedCallsInfo = arrayListOf<PSIPartialCallInfo>()
|
||||
protected val partiallyResolvedCallsInfo = arrayListOf<PSIPartialCallInfo>()
|
||||
private val errorCallsInfo = arrayListOf<PSIErrorCallInfo<D>>()
|
||||
private val completedCalls = hashSetOf<ResolvedAtom>()
|
||||
|
||||
@@ -170,18 +170,24 @@ data class ResolutionResultCallInfo<D : CallableDescriptor>(
|
||||
val overloadResolutionResults: OverloadResolutionResults<D>
|
||||
)
|
||||
|
||||
class PSIPartialCallInfo(
|
||||
override val callResolutionResult: PartialCallResolutionResult,
|
||||
abstract class CallInfo(
|
||||
open val callResolutionResult: SingleCallResolutionResult,
|
||||
val context: BasicCallResolutionContext,
|
||||
val tracingStrategy: TracingStrategy
|
||||
) : PartialCallInfo
|
||||
)
|
||||
|
||||
class PSIPartialCallInfo(
|
||||
override val callResolutionResult: PartialCallResolutionResult,
|
||||
context: BasicCallResolutionContext,
|
||||
tracingStrategy: TracingStrategy
|
||||
) : CallInfo(callResolutionResult, context, tracingStrategy), PartialCallInfo
|
||||
|
||||
class PSICompletedCallInfo(
|
||||
override val callResolutionResult: CompletedCallResolutionResult,
|
||||
val context: BasicCallResolutionContext,
|
||||
context: BasicCallResolutionContext,
|
||||
val resolvedCall: ResolvedCall<*>,
|
||||
val tracingStrategy: TracingStrategy
|
||||
) : CompletedCallInfo
|
||||
tracingStrategy: TracingStrategy
|
||||
) : CallInfo(callResolutionResult, context, tracingStrategy), CompletedCallInfo
|
||||
|
||||
class PSIErrorCallInfo<D : CallableDescriptor>(
|
||||
override val callResolutionResult: CallResolutionResult,
|
||||
|
||||
Reference in New Issue
Block a user