[NI] Run completion on subatoms of error calls

Call transformer previously ran completion of argument atoms
only for non-error candidates. This led to missing diagnostics,
i.e. from collection literal resolver.

Now arguments of calls resolved to error descriptor are completed,
with exception to not found provideDelegate calls.
provideDelegate's subatoms are not completed after failure, because
it is a part of delegate competion, which does not end with
unresolved provideDelegate.
Completing after provideDelegate failure removes constraint system
from resolved arguments, which breaks resolve for get/setValue.

^KT-33592 Fixed
This commit is contained in:
Pavel Kirpichenkov
2019-12-02 20:07:17 +03:00
parent 29fbb8e22f
commit 3de6289c6c
16 changed files with 73 additions and 10 deletions
@@ -49,8 +49,8 @@ class DelegatedPropertyInferenceSession(
private fun ResolvedCallAtom.addConstraintForThis(descriptor: CallableDescriptor, commonSystem: ConstraintSystemBuilder) {
val typeOfThis = variableDescriptor.extensionReceiverParameter?.type
?: variableDescriptor.dispatchReceiverParameter?.type
?: builtIns.nullableNothingType
?: variableDescriptor.dispatchReceiverParameter?.type
?: builtIns.nullableNothingType
val valueParameterForThis = descriptor.valueParameters.getOrNull(0) ?: return
val substitutedType = freshVariablesSubstitutor.safeSubstitute(valueParameterForThis.type.unwrap())
@@ -85,6 +85,8 @@ class DelegatedPropertyInferenceSession(
): Map<TypeConstructor, UnwrappedType> = emptyMap()
override fun writeOnlyStubs(callInfo: SingleCallResolutionResult): Boolean = false
override fun shouldCompleteResolvedSubAtomsOf(resolvedCallAtom: ResolvedCallAtom) = true
}
object InferenceSessionForExistingCandidates : InferenceSession {
@@ -104,4 +106,7 @@ object InferenceSessionForExistingCandidates : InferenceSession {
override fun writeOnlyStubs(callInfo: SingleCallResolutionResult): Boolean = false
override fun callCompleted(resolvedAtom: ResolvedAtom): Boolean = false
override fun shouldCompleteResolvedSubAtomsOf(resolvedCallAtom: ResolvedCallAtom): Boolean {
return !ErrorUtils.isError(resolvedCallAtom.candidateDescriptor)
}
}
@@ -107,6 +107,8 @@ class CoroutineInferenceSession(
return commonSystem.fixedTypeVariables.cast() // TODO: SUB
}
override fun shouldCompleteResolvedSubAtomsOf(resolvedCallAtom: ResolvedCallAtom) = true
private fun createNonFixedTypeToVariableSubstitutor(): NewTypeSubstitutorByConstructorMap {
val bindings = hashMapOf<TypeConstructor, UnwrappedType>()
for ((variable, nonFixedType) in stubsForPostponedVariables) {
@@ -138,7 +138,7 @@ class KotlinToResolvedCallTransformer(
typeApproximator, missingSupertypesResolver
)
if (!ErrorUtils.isError(candidate.candidateDescriptor)) {
if (context.inferenceSession.shouldCompleteResolvedSubAtomsOf(candidate)) {
candidate.subResolvedAtoms?.forEach { subKtPrimitive ->
ktPrimitiveCompleter.completeAll(subKtPrimitive)
}
@@ -61,6 +61,8 @@ abstract class ManyCandidatesResolver<D : CallableDescriptor>(
override fun callCompleted(resolvedAtom: ResolvedAtom): Boolean =
!completedCalls.add(resolvedAtom)
override fun shouldCompleteResolvedSubAtomsOf(resolvedCallAtom: ResolvedCallAtom) = true
fun resolveCandidates(resolutionCallbacks: KotlinResolutionCallbacks): List<ResolutionResultCallInfo<D>> {
val resolvedCallsInfo = partiallyResolvedCallsInfo.toList()
@@ -73,6 +73,8 @@ class ResolvedAtomCompleter(
}
fun completeAll(resolvedAtom: ResolvedAtom) {
if (!resolvedAtom.analyzed)
return
resolvedAtom.subResolvedAtoms?.forEach { subKtPrimitive ->
completeAll(subKtPrimitive)
}