diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/coroutines/coroutineCodegenUtil.kt b/compiler/backend/src/org/jetbrains/kotlin/codegen/coroutines/coroutineCodegenUtil.kt index 98ad453c493..af035086bdb 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/coroutines/coroutineCodegenUtil.kt +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/coroutines/coroutineCodegenUtil.kt @@ -189,7 +189,7 @@ fun ResolvedCall<*>.replaceSuspensionFunctionWithRealDescriptor( Pair(it, typeArguments[candidateDescriptor.typeParameters[it.index]]!!.asTypeProjection()) }.toMap() - newCall.setResultingSubstitutor( + newCall.setSubstitutor( TypeConstructorSubstitution.createByParametersMap(newTypeArguments).buildSubstitutor() ) diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/CallCompleter.kt b/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/CallCompleter.kt index e27ac4b3977..47900174cc4 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/CallCompleter.kt +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/CallCompleter.kt @@ -254,7 +254,7 @@ class CallCompleter( system.resultingSubstitutor.replaceWithContravariantApproximatingSubstitution() } else system.resultingSubstitutor - setResultingSubstitutor(resultingSubstitutor) + setSubstitutor(resultingSubstitutor) } private fun MutableResolvedCall.updateResolutionStatusFromConstraintSystem( diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/CandidateResolver.kt b/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/CandidateResolver.kt index 9e2a09eefb3..b01b9627eba 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/CandidateResolver.kt +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/CandidateResolver.kt @@ -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) } } diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/GenericCandidateResolver.kt b/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/GenericCandidateResolver.kt index 24a35e347cd..490dac8ef07 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/GenericCandidateResolver.kt +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/GenericCandidateResolver.kt @@ -353,7 +353,7 @@ class GenericCandidateResolver( resultingSystem.resultingSubstitutor.replaceWithContravariantApproximatingSubstitution() } else resultingSystem.resultingSubstitutor - resolvedCall.setResultingSubstitutor(resultingSubstitutor) + resolvedCall.setSubstitutor(resultingSubstitutor) } // See KT-5385 diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/inference/BuilderInferenceSession.kt b/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/inference/BuilderInferenceSession.kt index 5883e7e8300..962ce7b3dcc 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/inference/BuilderInferenceSession.kt +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/inference/BuilderInferenceSession.kt @@ -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) + } } } diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/model/MutableResolvedCall.java b/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/model/MutableResolvedCall.java index 849ae8490b5..9d88dc478bf 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/model/MutableResolvedCall.java +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/model/MutableResolvedCall.java @@ -64,7 +64,7 @@ public interface MutableResolvedCall extends Resol void setConstraintSystem(@NotNull ConstraintSystem constraintSystem); - void setResultingSubstitutor(@NotNull TypeSubstitutor substitutor); + void setSubstitutor(@NotNull TypeSubstitutor substitutor); @Nullable TypeSubstitutor getKnownTypeParametersSubstitutor(); diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/model/ResolvedCallImpl.java b/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/model/ResolvedCallImpl.java index 058d198edd0..072697869fb 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/model/ResolvedCallImpl.java +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/model/ResolvedCallImpl.java @@ -195,22 +195,15 @@ public class ResolvedCallImpl 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 implements MutableRe } } + @Override + public void setSubstitutor(@NotNull TypeSubstitutor substitutor) { + setResultingSubstitutor(substitutor); + setResolvedCallSubstitutor(substitutor); + } + @Override public void setConstraintSystem(@NotNull ConstraintSystem constraintSystem) { this.constraintSystem = constraintSystem; diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/tower/ResolvedAtomCompleter.kt b/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/tower/ResolvedAtomCompleter.kt index b6238c33721..e726f4b2e35 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/tower/ResolvedAtomCompleter.kt +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/tower/ResolvedAtomCompleter.kt @@ -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) diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/util/callUtil.kt b/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/util/callUtil.kt index 67e27e8c47f..0afdfc3ecb5 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/util/callUtil.kt +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/util/callUtil.kt @@ -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 ResolvedCallImpl.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 } } diff --git a/core/descriptors/src/org/jetbrains/kotlin/resolve/DescriptorUtils.kt b/core/descriptors/src/org/jetbrains/kotlin/resolve/DescriptorUtils.kt index ba80da08e0f..f7ab0e3eaa7 100644 --- a/core/descriptors/src/org/jetbrains/kotlin/resolve/DescriptorUtils.kt +++ b/core/descriptors/src/org/jetbrains/kotlin/resolve/DescriptorUtils.kt @@ -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.shouldBeUsedToSubstitute() = +private fun 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.shouldBeSubstituteWithStubTypes() = valueParameters.none { it.type.isError } && returnType?.isError != true && dispatchReceiverParameter?.type?.isError != true && extensionReceiverParameter?.type?.isError != true + && containsStubTypes()