Split setting substitutor descriptor for entire resolved call into two parts: setting resulting substitutor and setting substitutor for resolved call's types

This commit is contained in:
Victor Petukhov
2021-05-24 15:00:59 +03:00
parent fd5169186e
commit d8c68aacdd
10 changed files with 43 additions and 27 deletions
@@ -189,7 +189,7 @@ fun ResolvedCall<*>.replaceSuspensionFunctionWithRealDescriptor(
Pair(it, typeArguments[candidateDescriptor.typeParameters[it.index]]!!.asTypeProjection()) Pair(it, typeArguments[candidateDescriptor.typeParameters[it.index]]!!.asTypeProjection())
}.toMap() }.toMap()
newCall.setResultingSubstitutor( newCall.setSubstitutor(
TypeConstructorSubstitution.createByParametersMap(newTypeArguments).buildSubstitutor() TypeConstructorSubstitution.createByParametersMap(newTypeArguments).buildSubstitutor()
) )
@@ -254,7 +254,7 @@ class CallCompleter(
system.resultingSubstitutor.replaceWithContravariantApproximatingSubstitution() system.resultingSubstitutor.replaceWithContravariantApproximatingSubstitution()
} else system.resultingSubstitutor } else system.resultingSubstitutor
setResultingSubstitutor(resultingSubstitutor) setSubstitutor(resultingSubstitutor)
} }
private fun <D : CallableDescriptor> MutableResolvedCall<D>.updateResolutionStatusFromConstraintSystem( private fun <D : CallableDescriptor> MutableResolvedCall<D>.updateResolutionStatusFromConstraintSystem(
@@ -108,7 +108,7 @@ class CandidateResolver(
private fun CallCandidateResolutionContext<*>.processTypeArguments() = check { private fun CallCandidateResolutionContext<*>.processTypeArguments() = check {
val ktTypeArguments = call.typeArguments val ktTypeArguments = call.typeArguments
if (candidateCall.knownTypeParametersSubstitutor != null) { if (candidateCall.knownTypeParametersSubstitutor != null) {
candidateCall.setResultingSubstitutor(candidateCall.knownTypeParametersSubstitutor!!) candidateCall.setSubstitutor(candidateCall.knownTypeParametersSubstitutor!!)
} else if (ktTypeArguments.isNotEmpty()) { } else if (ktTypeArguments.isNotEmpty()) {
// Explicit type arguments passed // Explicit type arguments passed
@@ -137,7 +137,7 @@ class CandidateResolver(
checkGenericBoundsInAFunctionCall(ktTypeArguments, typeArguments, candidateDescriptor, substitutor, trace) checkGenericBoundsInAFunctionCall(ktTypeArguments, typeArguments, candidateDescriptor, substitutor, trace)
} }
candidateCall.setResultingSubstitutor(substitutor) candidateCall.setSubstitutor(substitutor)
} }
} }
@@ -353,7 +353,7 @@ class GenericCandidateResolver(
resultingSystem.resultingSubstitutor.replaceWithContravariantApproximatingSubstitution() resultingSystem.resultingSubstitutor.replaceWithContravariantApproximatingSubstitution()
} else resultingSystem.resultingSubstitutor } else resultingSystem.resultingSubstitutor
resolvedCall.setResultingSubstitutor(resultingSubstitutor) resolvedCall.setSubstitutor(resultingSubstitutor)
} }
// See KT-5385 // See KT-5385
@@ -15,19 +15,18 @@ import org.jetbrains.kotlin.psi.psiUtil.getParentOfType
import org.jetbrains.kotlin.psi.psiUtil.isAncestor import org.jetbrains.kotlin.psi.psiUtil.isAncestor
import org.jetbrains.kotlin.resolve.* import org.jetbrains.kotlin.resolve.*
import org.jetbrains.kotlin.resolve.calls.ArgumentTypeResolver import org.jetbrains.kotlin.resolve.calls.ArgumentTypeResolver
import org.jetbrains.kotlin.resolve.calls.callUtil.shouldBeSubstituteWithStubTypes
import org.jetbrains.kotlin.resolve.calls.callUtil.toOldSubstitution import org.jetbrains.kotlin.resolve.calls.callUtil.toOldSubstitution
import org.jetbrains.kotlin.resolve.calls.components.* import org.jetbrains.kotlin.resolve.calls.components.*
import org.jetbrains.kotlin.resolve.calls.context.BasicCallResolutionContext import org.jetbrains.kotlin.resolve.calls.context.BasicCallResolutionContext
import org.jetbrains.kotlin.resolve.calls.inference.components.ConstraintSystemCompletionMode import org.jetbrains.kotlin.resolve.calls.inference.components.*
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.* import org.jetbrains.kotlin.resolve.calls.inference.model.*
import org.jetbrains.kotlin.resolve.calls.model.* import org.jetbrains.kotlin.resolve.calls.model.*
import org.jetbrains.kotlin.resolve.calls.tower.* import org.jetbrains.kotlin.resolve.calls.tower.*
import org.jetbrains.kotlin.resolve.calls.util.FakeCallableDescriptorForObject import org.jetbrains.kotlin.resolve.calls.util.FakeCallableDescriptorForObject
import org.jetbrains.kotlin.resolve.deprecation.DeprecationResolver import org.jetbrains.kotlin.resolve.deprecation.DeprecationResolver
import org.jetbrains.kotlin.resolve.descriptorUtil.hasBuilderInferenceAnnotation import org.jetbrains.kotlin.resolve.descriptorUtil.hasBuilderInferenceAnnotation
import org.jetbrains.kotlin.resolve.descriptorUtil.shouldBeSubstituteWithStubTypes
import org.jetbrains.kotlin.types.* import org.jetbrains.kotlin.types.*
import org.jetbrains.kotlin.types.checker.NewCapturedType import org.jetbrains.kotlin.types.checker.NewCapturedType
import org.jetbrains.kotlin.types.expressions.DoubleColonExpressionResolver import org.jetbrains.kotlin.types.expressions.DoubleColonExpressionResolver
@@ -475,7 +474,13 @@ class BuilderInferenceSession(
val resolvedCall = trace.get(BindingContext.RESOLVED_CALL, call) val resolvedCall = trace.get(BindingContext.RESOLVED_CALL, call)
if (resolvedCall is ResolvedCallImpl<*>) { if (resolvedCall is ResolvedCallImpl<*>) {
resolvedCall.setResultingSubstitutor(substitutor.toOldSubstitution().buildSubstitutor()) val oldSubstitutor = substitutor.toOldSubstitution().buildSubstitutor()
if (resolvedCall.resultingDescriptor.shouldBeSubstituteWithStubTypes()) {
resolvedCall.setResultingSubstitutor(oldSubstitutor)
}
if (resolvedCall.shouldBeSubstituteWithStubTypes()) {
resolvedCall.setResolvedCallSubstitutor(oldSubstitutor)
}
} }
} }
@@ -64,7 +64,7 @@ public interface MutableResolvedCall<D extends CallableDescriptor> extends Resol
void setConstraintSystem(@NotNull ConstraintSystem constraintSystem); void setConstraintSystem(@NotNull ConstraintSystem constraintSystem);
void setResultingSubstitutor(@NotNull TypeSubstitutor substitutor); void setSubstitutor(@NotNull TypeSubstitutor substitutor);
@Nullable @Nullable
TypeSubstitutor getKnownTypeParametersSubstitutor(); TypeSubstitutor getKnownTypeParametersSubstitutor();
@@ -195,22 +195,15 @@ public class ResolvedCallImpl<D extends CallableDescriptor> implements MutableRe
return resultingDescriptor == null ? candidateDescriptor : resultingDescriptor; return resultingDescriptor == null ? candidateDescriptor : resultingDescriptor;
} }
@Override
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
public void setResultingSubstitutor(@NotNull TypeSubstitutor substitutor) { public void setResultingSubstitutor(@NotNull TypeSubstitutor substitutor) {
D descriptorToSubstitute = resultingDescriptor != null && DescriptorUtilsKt.shouldBeUsedToSubstitute(resultingDescriptor) D descriptorToSubstitute = resultingDescriptor != null && DescriptorUtilsKt.shouldBeSubstituteWithStubTypes(resultingDescriptor)
? resultingDescriptor ? resultingDescriptor
: candidateDescriptor; : candidateDescriptor;
resultingDescriptor = (D) descriptorToSubstitute.substitute(substitutor); resultingDescriptor = (D) descriptorToSubstitute.substitute(substitutor);
//noinspection ConstantConditions }
if (resultingDescriptor == null) {
throw new AssertionError(
"resultingDescriptor shouldn't be null:\n" +
"candidateDescriptor: " + DescriptorRenderer.COMPACT_WITH_SHORT_TYPES.render(candidateDescriptor) + "\n" +
"substitution: " + substitutor.getSubstitution()
);
}
public void setResolvedCallSubstitutor(@NotNull TypeSubstitutor substitutor) {
for (TypeParameterDescriptor typeParameter : candidateDescriptor.getTypeParameters()) { for (TypeParameterDescriptor typeParameter : candidateDescriptor.getTypeParameters()) {
TypeProjection typeArgumentProjection = substitutor.getSubstitution().get(typeParameter.getDefaultType()); TypeProjection typeArgumentProjection = substitutor.getSubstitution().get(typeParameter.getDefaultType());
if (typeArgumentProjection != null) { if (typeArgumentProjection != null) {
@@ -257,6 +250,12 @@ public class ResolvedCallImpl<D extends CallableDescriptor> implements MutableRe
} }
} }
@Override
public void setSubstitutor(@NotNull TypeSubstitutor substitutor) {
setResultingSubstitutor(substitutor);
setResolvedCallSubstitutor(substitutor);
}
@Override @Override
public void setConstraintSystem(@NotNull ConstraintSystem constraintSystem) { public void setConstraintSystem(@NotNull ConstraintSystem constraintSystem) {
this.constraintSystem = constraintSystem; this.constraintSystem = constraintSystem;
@@ -477,7 +477,7 @@ class ResolvedAtomCompleter(
null, temporaryTrace, tracing, MutableDataFlowInfoForArguments.WithoutArgumentsCheck(DataFlowInfo.EMPTY) null, temporaryTrace, tracing, MutableDataFlowInfoForArguments.WithoutArgumentsCheck(DataFlowInfo.EMPTY)
) )
resolvedCall.setResultingSubstitutor(resultTypeInfo.substitutor) resolvedCall.setSubstitutor(resultTypeInfo.substitutor)
recordArgumentAdaptationForCallableReference(resolvedCall, callableCandidate.callableReferenceAdaptation) recordArgumentAdaptationForCallableReference(resolvedCall, callableCandidate.callableReferenceAdaptation)
@@ -37,11 +37,9 @@ import org.jetbrains.kotlin.resolve.calls.inference.components.NewTypeSubstituto
import org.jetbrains.kotlin.resolve.calls.model.* import org.jetbrains.kotlin.resolve.calls.model.*
import org.jetbrains.kotlin.resolve.calls.tower.NewResolvedCallImpl import org.jetbrains.kotlin.resolve.calls.tower.NewResolvedCallImpl
import org.jetbrains.kotlin.resolve.scopes.receivers.ExpressionReceiver import org.jetbrains.kotlin.resolve.scopes.receivers.ExpressionReceiver
import org.jetbrains.kotlin.types.KotlinType import org.jetbrains.kotlin.types.*
import org.jetbrains.kotlin.types.TypeProjection
import org.jetbrains.kotlin.types.TypeSubstitution
import org.jetbrains.kotlin.types.isError
import org.jetbrains.kotlin.types.typeUtil.asTypeProjection import org.jetbrains.kotlin.types.typeUtil.asTypeProjection
import org.jetbrains.kotlin.types.typeUtil.contains
import org.jetbrains.kotlin.utils.addToStdlib.safeAs import org.jetbrains.kotlin.utils.addToStdlib.safeAs
import org.jetbrains.kotlin.utils.sure import org.jetbrains.kotlin.utils.sure
@@ -335,3 +333,9 @@ fun NewTypeSubstitutor.toOldSubstitution(): TypeSubstitution = object : TypeSubs
return isEmpty return isEmpty
} }
} }
fun <D : CallableDescriptor> ResolvedCallImpl<D>.shouldBeSubstituteWithStubTypes() =
typeArguments.any { argument -> argument.value.contains { it is StubTypeForBuilderInference } }
|| dispatchReceiver?.type?.contains { it is StubTypeForBuilderInference } == true
|| extensionReceiver?.type?.contains { it is StubTypeForBuilderInference } == true
|| valueArguments.any { argument -> argument.key.type.contains { it is StubTypeForBuilderInference } }
@@ -32,6 +32,7 @@ import org.jetbrains.kotlin.types.checker.KotlinTypeChecker
import org.jetbrains.kotlin.types.checker.KotlinTypeRefiner import org.jetbrains.kotlin.types.checker.KotlinTypeRefiner
import org.jetbrains.kotlin.types.checker.REFINER_CAPABILITY import org.jetbrains.kotlin.types.checker.REFINER_CAPABILITY
import org.jetbrains.kotlin.types.refinement.TypeRefinement import org.jetbrains.kotlin.types.refinement.TypeRefinement
import org.jetbrains.kotlin.types.typeUtil.contains
import org.jetbrains.kotlin.types.typeUtil.isAnyOrNullableAny import org.jetbrains.kotlin.types.typeUtil.isAnyOrNullableAny
import org.jetbrains.kotlin.types.typeUtil.makeNullable import org.jetbrains.kotlin.types.typeUtil.makeNullable
import org.jetbrains.kotlin.utils.DFS import org.jetbrains.kotlin.utils.DFS
@@ -424,8 +425,15 @@ fun ModuleDescriptor.isTypeRefinementEnabled(): Boolean = getCapability(REFINER_
val VariableDescriptor.isUnderscoreNamed val VariableDescriptor.isUnderscoreNamed
get() = !name.isSpecial && name.identifier == "_" get() = !name.isSpecial && name.identifier == "_"
fun <D : CallableDescriptor> D.shouldBeUsedToSubstitute() = private fun <D : CallableDescriptor> D.containsStubTypes() =
valueParameters.any { parameter -> parameter.type.contains { it is StubTypeForBuilderInference } }
|| returnType?.contains { it is StubTypeForBuilderInference } == true
|| dispatchReceiverParameter?.type?.contains { it is StubTypeForBuilderInference } == true
|| extensionReceiverParameter?.type?.contains { it is StubTypeForBuilderInference } == true
fun <D : CallableDescriptor> D.shouldBeSubstituteWithStubTypes() =
valueParameters.none { it.type.isError } valueParameters.none { it.type.isError }
&& returnType?.isError != true && returnType?.isError != true
&& dispatchReceiverParameter?.type?.isError != true && dispatchReceiverParameter?.type?.isError != true
&& extensionReceiverParameter?.type?.isError != true && extensionReceiverParameter?.type?.isError != true
&& containsStubTypes()