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())
}.toMap()
newCall.setResultingSubstitutor(
newCall.setSubstitutor(
TypeConstructorSubstitution.createByParametersMap(newTypeArguments).buildSubstitutor()
)
@@ -254,7 +254,7 @@ class CallCompleter(
system.resultingSubstitutor.replaceWithContravariantApproximatingSubstitution()
} else system.resultingSubstitutor
setResultingSubstitutor(resultingSubstitutor)
setSubstitutor(resultingSubstitutor)
}
private fun <D : CallableDescriptor> MutableResolvedCall<D>.updateResolutionStatusFromConstraintSystem(
@@ -108,7 +108,7 @@ class CandidateResolver(
private fun CallCandidateResolutionContext<*>.processTypeArguments() = check {
val ktTypeArguments = call.typeArguments
if (candidateCall.knownTypeParametersSubstitutor != null) {
candidateCall.setResultingSubstitutor(candidateCall.knownTypeParametersSubstitutor!!)
candidateCall.setSubstitutor(candidateCall.knownTypeParametersSubstitutor!!)
} else if (ktTypeArguments.isNotEmpty()) {
// Explicit type arguments passed
@@ -137,7 +137,7 @@ class CandidateResolver(
checkGenericBoundsInAFunctionCall(ktTypeArguments, typeArguments, candidateDescriptor, substitutor, trace)
}
candidateCall.setResultingSubstitutor(substitutor)
candidateCall.setSubstitutor(substitutor)
}
}
@@ -353,7 +353,7 @@ class GenericCandidateResolver(
resultingSystem.resultingSubstitutor.replaceWithContravariantApproximatingSubstitution()
} else resultingSystem.resultingSubstitutor
resolvedCall.setResultingSubstitutor(resultingSubstitutor)
resolvedCall.setSubstitutor(resultingSubstitutor)
}
// 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.resolve.*
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.components.*
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.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.components.*
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.resolve.descriptorUtil.hasBuilderInferenceAnnotation
import org.jetbrains.kotlin.resolve.descriptorUtil.shouldBeSubstituteWithStubTypes
import org.jetbrains.kotlin.types.*
import org.jetbrains.kotlin.types.checker.NewCapturedType
import org.jetbrains.kotlin.types.expressions.DoubleColonExpressionResolver
@@ -475,7 +474,13 @@ class BuilderInferenceSession(
val resolvedCall = trace.get(BindingContext.RESOLVED_CALL, call)
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 setResultingSubstitutor(@NotNull TypeSubstitutor substitutor);
void setSubstitutor(@NotNull TypeSubstitutor substitutor);
@Nullable
TypeSubstitutor getKnownTypeParametersSubstitutor();
@@ -195,22 +195,15 @@ public class ResolvedCallImpl<D extends CallableDescriptor> implements MutableRe
return resultingDescriptor == null ? candidateDescriptor : resultingDescriptor;
}
@Override
@SuppressWarnings("unchecked")
public void setResultingSubstitutor(@NotNull TypeSubstitutor substitutor) {
D descriptorToSubstitute = resultingDescriptor != null && DescriptorUtilsKt.shouldBeUsedToSubstitute(resultingDescriptor)
D descriptorToSubstitute = resultingDescriptor != null && DescriptorUtilsKt.shouldBeSubstituteWithStubTypes(resultingDescriptor)
? resultingDescriptor
: candidateDescriptor;
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()) {
TypeProjection typeArgumentProjection = substitutor.getSubstitution().get(typeParameter.getDefaultType());
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
public void setConstraintSystem(@NotNull ConstraintSystem constraintSystem) {
this.constraintSystem = constraintSystem;
@@ -477,7 +477,7 @@ class ResolvedAtomCompleter(
null, temporaryTrace, tracing, MutableDataFlowInfoForArguments.WithoutArgumentsCheck(DataFlowInfo.EMPTY)
)
resolvedCall.setResultingSubstitutor(resultTypeInfo.substitutor)
resolvedCall.setSubstitutor(resultTypeInfo.substitutor)
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.tower.NewResolvedCallImpl
import org.jetbrains.kotlin.resolve.scopes.receivers.ExpressionReceiver
import org.jetbrains.kotlin.types.KotlinType
import org.jetbrains.kotlin.types.TypeProjection
import org.jetbrains.kotlin.types.TypeSubstitution
import org.jetbrains.kotlin.types.isError
import org.jetbrains.kotlin.types.*
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.sure
@@ -335,3 +333,9 @@ fun NewTypeSubstitutor.toOldSubstitution(): TypeSubstitution = object : TypeSubs
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.REFINER_CAPABILITY
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.makeNullable
import org.jetbrains.kotlin.utils.DFS
@@ -424,8 +425,15 @@ fun ModuleDescriptor.isTypeRefinementEnabled(): Boolean = getCapability(REFINER_
val VariableDescriptor.isUnderscoreNamed
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 }
&& returnType?.isError != true
&& dispatchReceiverParameter?.type?.isError != true
&& extensionReceiverParameter?.type?.isError != true
&& containsStubTypes()