From 178ca3daaecff8c6027d19ba276b6ae317fa15b8 Mon Sep 17 00:00:00 2001 From: Alexander Udalov Date: Wed, 11 Nov 2015 20:24:13 +0300 Subject: [PATCH] Add call to type variable and mapping descriptor -> variable Since type parameter descriptor represents a single declaration of a type parameter, multiple variables in one system may correspond to one type parameter (e.g. in case of nested calls). Hence it's not possible to map type parameters uniquely onto type variables and additional information is required --- .../kotlin/diagnostics/rendering/Renderers.kt | 6 ++--- .../kotlin/resolve/calls/CallCompleter.kt | 3 ++- .../resolve/calls/GenericCandidateResolver.kt | 9 +++---- .../calls/inference/ConstraintSystem.kt | 6 +++-- .../inference/ConstraintSystemBuilderImpl.kt | 22 ++++++++++------ .../calls/inference/ConstraintSystemImpl.kt | 4 +-- .../calls/inference/ConstraintsUtil.java | 5 +++- .../calls/inference/InferenceErrorData.java | 25 ++++++++++++++----- .../resolve/calls/inference/TypeVariable.kt | 21 +++++++++++++++- .../calls/inference/constraintSystemUtils.kt | 6 +++-- .../kotlin/types/TypeIntersector.java | 3 ++- .../AbstractConstraintSystemTest.kt | 3 ++- .../jetbrains/kotlin/idea/util/FuzzyType.kt | 3 ++- .../idea/quickfix/AddGenericUpperBoundFix.kt | 3 ++- 14 files changed, 83 insertions(+), 36 deletions(-) diff --git a/compiler/frontend/src/org/jetbrains/kotlin/diagnostics/rendering/Renderers.kt b/compiler/frontend/src/org/jetbrains/kotlin/diagnostics/rendering/Renderers.kt index 05dc70c1d82..f8ab00dc801 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/diagnostics/rendering/Renderers.kt +++ b/compiler/frontend/src/org/jetbrains/kotlin/diagnostics/rendering/Renderers.kt @@ -251,7 +251,7 @@ public object Renderers { val systemWithoutWeakConstraints = constraintSystem.filterConstraintsOut(ConstraintPositionKind.TYPE_BOUND_POSITION) val typeParameterDescriptor = inferenceErrorData.descriptor.typeParameters.firstOrNull { - !ConstraintsUtil.checkUpperBoundIsSatisfied(systemWithoutWeakConstraints, it, true) + !ConstraintsUtil.checkUpperBoundIsSatisfied(systemWithoutWeakConstraints, it, inferenceErrorData.call, true) } if (typeParameterDescriptor == null && status.hasConflictingConstraints()) { return renderConflictingSubstitutionsInferenceError(inferenceErrorData, result) @@ -261,8 +261,8 @@ public object Renderers { return result } - val inferredValueForTypeParameter = - systemWithoutWeakConstraints.getTypeBounds(systemWithoutWeakConstraints.descriptorToVariable(typeParameterDescriptor)).value + val typeVariable = systemWithoutWeakConstraints.descriptorToVariable(inferenceErrorData.call.toHandle(), typeParameterDescriptor) + val inferredValueForTypeParameter = systemWithoutWeakConstraints.getTypeBounds(typeVariable).value if (inferredValueForTypeParameter == null) { LOG.error(renderDebugMessage("System without weak constraints is not successful, there is no value for type parameter " + typeParameterDescriptor.getName() + "\n: " + systemWithoutWeakConstraints, inferenceErrorData)) 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 34d2db08056..759127392e1 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/CallCompleter.kt +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/CallCompleter.kt @@ -204,7 +204,8 @@ public class CallCompleter( val errorData = InferenceErrorData.create( getCandidateDescriptor(), getConstraintSystem()!!, valueArgumentsCheckingResult.argumentTypes, - receiverType, context.expectedType) + receiverType, context.expectedType, context.call + ) tracing.typeInferenceFailed(context.trace, errorData) addStatus(ResolutionStatus.OTHER_ERROR) 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 7f73d61b1bb..086ce2242c7 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/GenericCandidateResolver.kt +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/GenericCandidateResolver.kt @@ -32,13 +32,10 @@ import org.jetbrains.kotlin.resolve.calls.context.ContextDependency.INDEPENDENT import org.jetbrains.kotlin.resolve.calls.context.ResolutionContext import org.jetbrains.kotlin.resolve.calls.context.ResolutionResultsCache import org.jetbrains.kotlin.resolve.calls.context.TemporaryTraceAndCache -import org.jetbrains.kotlin.resolve.calls.inference.ConstraintSystem -import org.jetbrains.kotlin.resolve.calls.inference.ConstraintSystemBuilderImpl +import org.jetbrains.kotlin.resolve.calls.inference.* import org.jetbrains.kotlin.resolve.calls.inference.constraintPosition.ConstraintPosition import org.jetbrains.kotlin.resolve.calls.inference.constraintPosition.ConstraintPositionKind.RECEIVER_POSITION import org.jetbrains.kotlin.resolve.calls.inference.constraintPosition.ConstraintPositionKind.VALUE_PARAMETER_POSITION -import org.jetbrains.kotlin.resolve.calls.inference.getNestedTypeParameters -import org.jetbrains.kotlin.resolve.calls.inference.getNestedTypeVariables import org.jetbrains.kotlin.resolve.calls.results.ResolutionStatus import org.jetbrains.kotlin.resolve.calls.results.ResolutionStatus.INCOMPLETE_TYPE_INFERENCE import org.jetbrains.kotlin.resolve.calls.results.ResolutionStatus.OTHER_ERROR @@ -56,7 +53,7 @@ class GenericCandidateResolver(private val argumentTypeResolver: ArgumentTypeRes val candidate = candidateCall.candidateDescriptor val builder = ConstraintSystemBuilderImpl() - builder.registerTypeVariables(candidate.typeParameters) + builder.registerTypeVariables(candidateCall.call.toHandle(), candidate.typeParameters) val substituteDontCare = makeConstantSubstitutor(candidate.typeParameters, DONT_CARE) @@ -158,7 +155,7 @@ class GenericCandidateResolver(private val argumentTypeResolver: ArgumentTypeRes val conversion = candidateDescriptor.typeParameters.zip(candidateWithFreshVariables.typeParameters).toMap() val freshVariables = returnType.getNestedTypeParameters().map { conversion[it] }.filterNotNull() - builder.registerTypeVariables(freshVariables, external = true) + builder.registerTypeVariables(resultingCall.call.toHandle(), freshVariables, external = true) builder.addSubtypeConstraint(candidateWithFreshVariables.returnType, effectiveExpectedType, constraintPosition) return true diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/inference/ConstraintSystem.kt b/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/inference/ConstraintSystem.kt index d235ae2c4b0..213b7a90eec 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/inference/ConstraintSystem.kt +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/inference/ConstraintSystem.kt @@ -34,7 +34,7 @@ interface ConstraintSystem { */ val typeVariables: Set - fun descriptorToVariable(descriptor: TypeParameterDescriptor): TypeVariable + fun descriptorToVariable(call: CallHandle, descriptor: TypeParameterDescriptor): TypeVariable /** * Returns the resulting type constraints of solving the constraint system for specific type parameter descriptor. @@ -66,7 +66,9 @@ interface ConstraintSystem { * Registers variables in a constraint system. Returns a substitutor which maps type parameter descriptors given as parameters * to the corresponding type variables of the system. Use that substitutor to provide constraints to the system */ - fun registerTypeVariables(typeParameters: Collection, external: Boolean = false): TypeSubstitutor + fun registerTypeVariables( + call: CallHandle, typeParameters: Collection, external: Boolean = false + ): TypeSubstitutor /** * Adds a constraint that the constraining type is a subtype of the subject type. diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/inference/ConstraintSystemBuilderImpl.kt b/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/inference/ConstraintSystemBuilderImpl.kt index dc8d364f63d..88095902759 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/inference/ConstraintSystemBuilderImpl.kt +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/inference/ConstraintSystemBuilderImpl.kt @@ -64,19 +64,25 @@ class ConstraintSystemBuilderImpl : ConstraintSystem.Builder { }) } - override fun registerTypeVariables(typeParameters: Collection, external: Boolean): TypeSubstitutor { + override fun registerTypeVariables( + call: CallHandle, typeParameters: Collection, external: Boolean + ): TypeSubstitutor { if (typeParameters.isEmpty()) return TypeSubstitutor.EMPTY - val typeVariables = (if (external) { - typeParameters.toList() + val typeVariables = if (external) { + typeParameters.map { + TypeVariable(call, it, it, true) + } } - else ArrayList(typeParameters.size).apply { + else { + val freshTypeParameters = ArrayList(typeParameters.size) DescriptorSubstitutor.substituteTypeParameters( - typeParameters.toList(), TypeSubstitution.EMPTY, typeParameters.first().containingDeclaration, this + typeParameters.toList(), TypeSubstitution.EMPTY, typeParameters.first().containingDeclaration, freshTypeParameters ) - }).zip(typeParameters).map { - val (fresh, original) = it - TypeVariable(fresh, original, external) + freshTypeParameters.zip(typeParameters).map { + val (fresh, original) = it + TypeVariable(call, fresh, original, external) + } } for ((descriptor, typeVariable) in typeParameters.zip(typeVariables)) { diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/inference/ConstraintSystemImpl.kt b/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/inference/ConstraintSystemImpl.kt index 715d61d4339..19d7ae99f5a 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/inference/ConstraintSystemImpl.kt +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/inference/ConstraintSystemImpl.kt @@ -111,8 +111,8 @@ internal class ConstraintSystemImpl( override val typeVariables: Set get() = allTypeParameterBounds.keys - override fun descriptorToVariable(descriptor: TypeParameterDescriptor): TypeVariable = - descriptorToVariable[descriptor] ?: throw IllegalArgumentException("Unknown descriptor: $descriptor") + override fun descriptorToVariable(call: CallHandle, descriptor: TypeParameterDescriptor): TypeVariable = + descriptorToVariable[descriptor] ?: throw IllegalArgumentException("Unknown descriptor: $descriptor, call: $call") override fun getTypeBounds(typeVariable: TypeVariable): TypeBoundsImpl { return allTypeParameterBounds[typeVariable] ?: diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/inference/ConstraintsUtil.java b/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/inference/ConstraintsUtil.java index 14c0c710c6d..039203765c4 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/inference/ConstraintsUtil.java +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/inference/ConstraintsUtil.java @@ -21,6 +21,7 @@ import com.google.common.collect.Maps; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.jetbrains.kotlin.descriptors.TypeParameterDescriptor; +import org.jetbrains.kotlin.psi.Call; import org.jetbrains.kotlin.types.*; import org.jetbrains.kotlin.types.checker.KotlinTypeChecker; @@ -84,9 +85,11 @@ public class ConstraintsUtil { public static boolean checkUpperBoundIsSatisfied( @NotNull ConstraintSystem constraintSystem, @NotNull TypeParameterDescriptor typeParameter, + @NotNull Call call, boolean substituteOtherTypeParametersInBound ) { - KotlinType type = constraintSystem.getTypeBounds(constraintSystem.descriptorToVariable(typeParameter)).getValue(); + TypeVariable typeVariable = constraintSystem.descriptorToVariable(TypeVariableKt.toHandle(call), typeParameter); + KotlinType type = constraintSystem.getTypeBounds(typeVariable).getValue(); if (type == null) return true; for (KotlinType upperBound : typeParameter.getUpperBounds()) { if (!substituteOtherTypeParametersInBound && diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/inference/InferenceErrorData.java b/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/inference/InferenceErrorData.java index a286100cb87..806eb18f4b1 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/inference/InferenceErrorData.java +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/inference/InferenceErrorData.java @@ -19,6 +19,7 @@ package org.jetbrains.kotlin.resolve.calls.inference; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.jetbrains.kotlin.descriptors.CallableDescriptor; +import org.jetbrains.kotlin.psi.Call; import org.jetbrains.kotlin.types.KotlinType; import java.util.List; @@ -34,22 +35,34 @@ public class InferenceErrorData { public final KotlinType expectedType; @NotNull public final List valueArgumentsTypes; - + @NotNull + public final Call call; private InferenceErrorData( - @NotNull CallableDescriptor descriptor, @NotNull ConstraintSystem constraintSystem, - @NotNull List valueArgumentsTypes, @Nullable KotlinType receiverArgumentType, @NotNull KotlinType expectedType + @NotNull CallableDescriptor descriptor, + @NotNull ConstraintSystem constraintSystem, + @NotNull List valueArgumentsTypes, + @Nullable KotlinType receiverArgumentType, + @NotNull KotlinType expectedType, + @NotNull Call call ) { this.descriptor = descriptor; this.constraintSystem = constraintSystem; this.receiverArgumentType = receiverArgumentType; this.valueArgumentsTypes = valueArgumentsTypes; this.expectedType = expectedType; + this.call = call; } @NotNull - public static InferenceErrorData create(@NotNull CallableDescriptor descriptor, @NotNull ConstraintSystem constraintSystem, - @NotNull List valueArgumentsTypes, @Nullable KotlinType receiverArgumentType, @NotNull KotlinType expectedType) { - return new InferenceErrorData(descriptor, constraintSystem, valueArgumentsTypes, receiverArgumentType, expectedType); + public static InferenceErrorData create( + @NotNull CallableDescriptor descriptor, + @NotNull ConstraintSystem constraintSystem, + @NotNull List valueArgumentsTypes, + @Nullable KotlinType receiverArgumentType, + @NotNull KotlinType expectedType, + @NotNull Call call + ) { + return new InferenceErrorData(descriptor, constraintSystem, valueArgumentsTypes, receiverArgumentType, expectedType, call); } } diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/inference/TypeVariable.kt b/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/inference/TypeVariable.kt index c302a0f945f..834115b716d 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/inference/TypeVariable.kt +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/inference/TypeVariable.kt @@ -19,13 +19,15 @@ package org.jetbrains.kotlin.resolve.calls.inference import org.jetbrains.kotlin.descriptors.TypeParameterDescriptor import org.jetbrains.kotlin.descriptors.annotations.Annotations import org.jetbrains.kotlin.name.Name +import org.jetbrains.kotlin.psi.Call import org.jetbrains.kotlin.resolve.descriptorUtil.hasOnlyInputTypesAnnotation import org.jetbrains.kotlin.resolve.scopes.MemberScope import org.jetbrains.kotlin.types.KotlinType import org.jetbrains.kotlin.types.KotlinTypeImpl class TypeVariable( - val freshTypeParameter: TypeParameterDescriptor, + val call: CallHandle, + internal val freshTypeParameter: TypeParameterDescriptor, val originalTypeParameter: TypeParameterDescriptor, val isExternal: Boolean ) { @@ -36,3 +38,20 @@ class TypeVariable( fun hasOnlyInputTypesAnnotation(): Boolean = originalTypeParameter.hasOnlyInputTypesAnnotation() } + +interface CallHandle { + object NONE : CallHandle +} + +class CallBasedCallHandle(val call: Call): CallHandle { + override fun equals(other: Any?) = + other is CallBasedCallHandle && call === other.call + + override fun hashCode() = + System.identityHashCode(call) + + override fun toString() = + call.toString() +} + +fun Call.toHandle(): CallHandle = CallBasedCallHandle(this) diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/inference/constraintSystemUtils.kt b/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/inference/constraintSystemUtils.kt index 1fedecee99e..f700ed2c925 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/inference/constraintSystemUtils.kt +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/inference/constraintSystemUtils.kt @@ -24,8 +24,10 @@ import org.jetbrains.kotlin.types.TypeProjection import org.jetbrains.kotlin.types.TypeProjectionImpl import java.util.* -fun ConstraintSystem.getNestedTypeVariables(type: KotlinType): List = - type.getNestedTypeParameters().filter { it in typeParameterDescriptors }.map { descriptorToVariable(it) } +fun ConstraintSystem.getNestedTypeVariables(type: KotlinType): List { + val nestedTypeParameters = type.getNestedTypeParameters().toSet() + return typeVariables.filter { it.originalTypeParameter in nestedTypeParameters } +} fun ConstraintSystem.filterConstraintsOut(excludePositionKind: ConstraintPositionKind): ConstraintSystem { return toBuilder { !it.derivedFrom(excludePositionKind) }.build() diff --git a/compiler/frontend/src/org/jetbrains/kotlin/types/TypeIntersector.java b/compiler/frontend/src/org/jetbrains/kotlin/types/TypeIntersector.java index 3f019bd223f..0ab95bc1d5d 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/types/TypeIntersector.java +++ b/compiler/frontend/src/org/jetbrains/kotlin/types/TypeIntersector.java @@ -24,6 +24,7 @@ import org.jetbrains.kotlin.builtins.KotlinBuiltIns; import org.jetbrains.kotlin.descriptors.ClassifierDescriptor; import org.jetbrains.kotlin.descriptors.TypeParameterDescriptor; import org.jetbrains.kotlin.descriptors.annotations.Annotations; +import org.jetbrains.kotlin.resolve.calls.inference.CallHandle; import org.jetbrains.kotlin.resolve.calls.inference.ConstraintSystem; import org.jetbrains.kotlin.resolve.calls.inference.ConstraintSystemBuilderImpl; import org.jetbrains.kotlin.resolve.scopes.ChainedScope; @@ -185,7 +186,7 @@ public class TypeIntersector { processAllTypeParameters(withParameters, Variance.INVARIANT, processor); processAllTypeParameters(expected, Variance.INVARIANT, processor); ConstraintSystem.Builder constraintSystem = new ConstraintSystemBuilderImpl(); - constraintSystem.registerTypeVariables(parameters.keySet(), false); + constraintSystem.registerTypeVariables(CallHandle.NONE.INSTANCE, parameters.keySet(), false); constraintSystem.addSubtypeConstraint(withParameters, expected, SPECIAL.position()); return constraintSystem.build().getStatus().isSuccessful(); diff --git a/compiler/tests/org/jetbrains/kotlin/resolve/constraintSystem/AbstractConstraintSystemTest.kt b/compiler/tests/org/jetbrains/kotlin/resolve/constraintSystem/AbstractConstraintSystemTest.kt index 248db3025de..9375fd88fc7 100644 --- a/compiler/tests/org/jetbrains/kotlin/resolve/constraintSystem/AbstractConstraintSystemTest.kt +++ b/compiler/tests/org/jetbrains/kotlin/resolve/constraintSystem/AbstractConstraintSystemTest.kt @@ -20,6 +20,7 @@ import org.jetbrains.kotlin.cli.jvm.compiler.KotlinCoreEnvironment import org.jetbrains.kotlin.diagnostics.rendering.Renderers import org.jetbrains.kotlin.renderer.DescriptorRenderer import org.jetbrains.kotlin.resolve.TypeResolver +import org.jetbrains.kotlin.resolve.calls.inference.CallHandle import org.jetbrains.kotlin.resolve.calls.inference.ConstraintContext import org.jetbrains.kotlin.resolve.calls.inference.ConstraintSystemBuilderImpl import org.jetbrains.kotlin.resolve.calls.inference.constraintPosition.ConstraintPositionKind.SPECIAL @@ -81,7 +82,7 @@ abstract public class AbstractConstraintSystemTest() : KotlinLiteFixture() { val variables = parseVariables(constraintsFileText) val fixVariables = constraintsFileText.contains("FIX_VARIABLES") val typeParameterDescriptors = variables.map { testDeclarations.getParameterDescriptor(it) } - val substitutor = builder.registerTypeVariables(typeParameterDescriptors) + val substitutor = builder.registerTypeVariables(CallHandle.NONE, typeParameterDescriptors) val constraints = parseConstraints(constraintsFileText) diff --git a/idea/ide-common/src/org/jetbrains/kotlin/idea/util/FuzzyType.kt b/idea/ide-common/src/org/jetbrains/kotlin/idea/util/FuzzyType.kt index c27afc934cf..784849806a8 100644 --- a/idea/ide-common/src/org/jetbrains/kotlin/idea/util/FuzzyType.kt +++ b/idea/ide-common/src/org/jetbrains/kotlin/idea/util/FuzzyType.kt @@ -20,6 +20,7 @@ package org.jetbrains.kotlin.idea.util import org.jetbrains.kotlin.descriptors.CallableDescriptor import org.jetbrains.kotlin.descriptors.TypeParameterDescriptor +import org.jetbrains.kotlin.resolve.calls.inference.CallHandle import org.jetbrains.kotlin.resolve.calls.inference.ConstraintSystemBuilderImpl import org.jetbrains.kotlin.resolve.calls.inference.constraintPosition.ConstraintPositionKind import org.jetbrains.kotlin.types.* @@ -115,7 +116,7 @@ class FuzzyType( } val builder = ConstraintSystemBuilderImpl() - val typeVariableSubstitutor = builder.registerTypeVariables(freeParameters + otherType.freeParameters) + val typeVariableSubstitutor = builder.registerTypeVariables(CallHandle.NONE, freeParameters + otherType.freeParameters) when (matchKind) { MatchKind.IS_SUBTYPE -> builder.addSubtypeConstraint( diff --git a/idea/src/org/jetbrains/kotlin/idea/quickfix/AddGenericUpperBoundFix.kt b/idea/src/org/jetbrains/kotlin/idea/quickfix/AddGenericUpperBoundFix.kt index 7aacb264b6a..c0a370cf8a1 100644 --- a/idea/src/org/jetbrains/kotlin/idea/quickfix/AddGenericUpperBoundFix.kt +++ b/idea/src/org/jetbrains/kotlin/idea/quickfix/AddGenericUpperBoundFix.kt @@ -87,7 +87,8 @@ public class AddGenericUpperBoundFix( typeParameterDescriptor -> if (ConstraintsUtil.checkUpperBoundIsSatisfied( - successfulConstraintSystem, typeParameterDescriptor, /* substituteOtherTypeParametersInBound */ true + successfulConstraintSystem, typeParameterDescriptor, inferenceData.call, + /* substituteOtherTypeParametersInBound */ true )) return@factory null val upperBound = typeParameterDescriptor.upperBounds.singleOrNull() ?: return@factory null