Get rid of originalToVariableSubstitutor and descriptorToVariable
Move the composite substitutor to GenericCandidateResolver where it was used, other places don't need it since they know the exact call (or NO_CALL), the substitutor for which should be used
This commit is contained in:
@@ -356,6 +356,10 @@ public class DelegatedPropertyResolver {
|
|||||||
KotlinType returnType = resolvedCall.getCandidateDescriptor().getReturnType();
|
KotlinType returnType = resolvedCall.getCandidateDescriptor().getReturnType();
|
||||||
if (returnType == null) return;
|
if (returnType == null) return;
|
||||||
|
|
||||||
|
TypeSubstitutor typeVariableSubstitutor =
|
||||||
|
constraintSystem.getTypeVariableSubstitutors().get(TypeVariableKt.toHandle(resolvedCall.getCall()));
|
||||||
|
assert typeVariableSubstitutor != null : "No substitutor in the system for call: " + resolvedCall.getCall();
|
||||||
|
|
||||||
TemporaryBindingTrace traceToResolveConventionMethods =
|
TemporaryBindingTrace traceToResolveConventionMethods =
|
||||||
TemporaryBindingTrace.create(trace, "Trace to resolve delegated property convention methods");
|
TemporaryBindingTrace.create(trace, "Trace to resolve delegated property convention methods");
|
||||||
OverloadResolutionResults<FunctionDescriptor>
|
OverloadResolutionResults<FunctionDescriptor>
|
||||||
@@ -368,15 +372,12 @@ public class DelegatedPropertyResolver {
|
|||||||
FunctionDescriptor descriptor = getMethodResults.getResultingDescriptor();
|
FunctionDescriptor descriptor = getMethodResults.getResultingDescriptor();
|
||||||
KotlinType returnTypeOfGetMethod = descriptor.getReturnType();
|
KotlinType returnTypeOfGetMethod = descriptor.getReturnType();
|
||||||
if (returnTypeOfGetMethod != null && !TypeUtils.noExpectedType(expectedType)) {
|
if (returnTypeOfGetMethod != null && !TypeUtils.noExpectedType(expectedType)) {
|
||||||
TypeSubstitutor substitutor =
|
KotlinType returnTypeInSystem = typeVariableSubstitutor.substitute(returnTypeOfGetMethod, Variance.INVARIANT);
|
||||||
constraintSystem.getTypeVariableSubstitutors().get(TypeVariableKt.toHandle(resolvedCall.getCall()));
|
|
||||||
assert substitutor != null : "No substitutor in the system for call: " + resolvedCall.getCall();
|
|
||||||
KotlinType returnTypeInSystem = substitutor.substitute(returnTypeOfGetMethod, Variance.INVARIANT);
|
|
||||||
if (returnTypeInSystem != null) {
|
if (returnTypeInSystem != null) {
|
||||||
constraintSystem.addSupertypeConstraint(expectedType, returnTypeInSystem, FROM_COMPLETER.position());
|
constraintSystem.addSupertypeConstraint(expectedType, returnTypeInSystem, FROM_COMPLETER.position());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
addConstraintForThisValue(constraintSystem, descriptor);
|
addConstraintForThisValue(constraintSystem, typeVariableSubstitutor, descriptor);
|
||||||
}
|
}
|
||||||
if (!propertyDescriptor.isVar()) return;
|
if (!propertyDescriptor.isVar()) return;
|
||||||
|
|
||||||
@@ -399,9 +400,12 @@ public class DelegatedPropertyResolver {
|
|||||||
|
|
||||||
if (!noExpectedType(expectedType)) {
|
if (!noExpectedType(expectedType)) {
|
||||||
constraintSystem.addSubtypeConstraint(
|
constraintSystem.addSubtypeConstraint(
|
||||||
expectedType, valueParameterForThis.getType(), FROM_COMPLETER.position());
|
expectedType,
|
||||||
|
typeVariableSubstitutor.substitute(valueParameterForThis.getType(), Variance.INVARIANT),
|
||||||
|
FROM_COMPLETER.position()
|
||||||
|
);
|
||||||
}
|
}
|
||||||
addConstraintForThisValue(constraintSystem, descriptor);
|
addConstraintForThisValue(constraintSystem, typeVariableSubstitutor, descriptor);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -412,7 +416,11 @@ public class DelegatedPropertyResolver {
|
|||||||
results.getResultCode() == OverloadResolutionResults.Code.SINGLE_CANDIDATE_ARGUMENT_MISMATCH);
|
results.getResultCode() == OverloadResolutionResults.Code.SINGLE_CANDIDATE_ARGUMENT_MISMATCH);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void addConstraintForThisValue(ConstraintSystem.Builder constraintSystem, FunctionDescriptor resultingDescriptor) {
|
private void addConstraintForThisValue(
|
||||||
|
ConstraintSystem.Builder constraintSystem,
|
||||||
|
TypeSubstitutor typeVariableSubstitutor,
|
||||||
|
FunctionDescriptor resultingDescriptor
|
||||||
|
) {
|
||||||
ReceiverParameterDescriptor extensionReceiver = propertyDescriptor.getExtensionReceiverParameter();
|
ReceiverParameterDescriptor extensionReceiver = propertyDescriptor.getExtensionReceiverParameter();
|
||||||
ReceiverParameterDescriptor dispatchReceiver = propertyDescriptor.getDispatchReceiverParameter();
|
ReceiverParameterDescriptor dispatchReceiver = propertyDescriptor.getDispatchReceiverParameter();
|
||||||
KotlinType typeOfThis =
|
KotlinType typeOfThis =
|
||||||
@@ -424,7 +432,11 @@ public class DelegatedPropertyResolver {
|
|||||||
if (valueParameters.isEmpty()) return;
|
if (valueParameters.isEmpty()) return;
|
||||||
ValueParameterDescriptor valueParameterForThis = valueParameters.get(0);
|
ValueParameterDescriptor valueParameterForThis = valueParameters.get(0);
|
||||||
|
|
||||||
constraintSystem.addSubtypeConstraint(typeOfThis, valueParameterForThis.getType(), FROM_COMPLETER.position());
|
constraintSystem.addSubtypeConstraint(
|
||||||
|
typeOfThis,
|
||||||
|
typeVariableSubstitutor.substitute(valueParameterForThis.getType(), Variance.INVARIANT),
|
||||||
|
FROM_COMPLETER.position()
|
||||||
|
);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
+36
-7
@@ -86,7 +86,11 @@ class GenericCandidateResolver(private val argumentTypeResolver: ArgumentTypeRes
|
|||||||
if (receiverArgument is ExpressionReceiver) {
|
if (receiverArgument is ExpressionReceiver) {
|
||||||
receiverType = updateResultTypeForSmartCasts(receiverType, receiverArgument.expression, context)
|
receiverType = updateResultTypeForSmartCasts(receiverType, receiverArgument.expression, context)
|
||||||
}
|
}
|
||||||
builder.addSubtypeConstraint(receiverType, receiverParameter.type, RECEIVER_POSITION.position())
|
builder.addSubtypeConstraint(
|
||||||
|
receiverType,
|
||||||
|
builder.compositeSubstitutor().substitute(receiverParameter.type, Variance.INVARIANT),
|
||||||
|
RECEIVER_POSITION.position()
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
val constraintSystem = builder.build()
|
val constraintSystem = builder.build()
|
||||||
@@ -100,6 +104,16 @@ class GenericCandidateResolver(private val argumentTypeResolver: ArgumentTypeRes
|
|||||||
return OTHER_ERROR
|
return OTHER_ERROR
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Creates a substitutor which maps types to their representation in the constraint system.
|
||||||
|
// In case when some type parameter descriptor is represented by more than one variable in the system, the behavior is undefined.
|
||||||
|
private fun ConstraintSystem.Builder.compositeSubstitutor(): TypeSubstitutor {
|
||||||
|
return TypeSubstitutor.create(object : TypeSubstitution() {
|
||||||
|
override fun get(key: KotlinType): TypeProjection? {
|
||||||
|
return typeVariableSubstitutors.values.reversed().asSequence().mapNotNull { it.substitution.get(key) }.firstOrNull()
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
fun addConstraintForValueArgument(
|
fun addConstraintForValueArgument(
|
||||||
valueArgument: ValueArgument,
|
valueArgument: ValueArgument,
|
||||||
valueParameterDescriptor: ValueParameterDescriptor,
|
valueParameterDescriptor: ValueParameterDescriptor,
|
||||||
@@ -108,7 +122,6 @@ class GenericCandidateResolver(private val argumentTypeResolver: ArgumentTypeRes
|
|||||||
context: CallCandidateResolutionContext<*>,
|
context: CallCandidateResolutionContext<*>,
|
||||||
resolveFunctionArgumentBodies: ResolveArgumentsMode
|
resolveFunctionArgumentBodies: ResolveArgumentsMode
|
||||||
) {
|
) {
|
||||||
|
|
||||||
val effectiveExpectedType = getEffectiveExpectedType(valueParameterDescriptor, valueArgument)
|
val effectiveExpectedType = getEffectiveExpectedType(valueParameterDescriptor, valueArgument)
|
||||||
val argumentExpression = valueArgument.getArgumentExpression()
|
val argumentExpression = valueArgument.getArgumentExpression()
|
||||||
|
|
||||||
@@ -124,7 +137,11 @@ class GenericCandidateResolver(private val argumentTypeResolver: ArgumentTypeRes
|
|||||||
if (addConstraintForNestedCall(argumentExpression, constraintPosition, builder, newContext, effectiveExpectedType)) return
|
if (addConstraintForNestedCall(argumentExpression, constraintPosition, builder, newContext, effectiveExpectedType)) return
|
||||||
|
|
||||||
val type = updateResultTypeForSmartCasts(typeInfoForCall.type, argumentExpression, context.replaceDataFlowInfo(dataFlowInfoForArgument))
|
val type = updateResultTypeForSmartCasts(typeInfoForCall.type, argumentExpression, context.replaceDataFlowInfo(dataFlowInfoForArgument))
|
||||||
builder.addSubtypeConstraint(type, effectiveExpectedType, constraintPosition)
|
builder.addSubtypeConstraint(
|
||||||
|
type,
|
||||||
|
builder.compositeSubstitutor().substitute(effectiveExpectedType, Variance.INVARIANT),
|
||||||
|
constraintPosition
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun addConstraintForNestedCall(
|
private fun addConstraintForNestedCall(
|
||||||
@@ -157,7 +174,12 @@ class GenericCandidateResolver(private val argumentTypeResolver: ArgumentTypeRes
|
|||||||
val freshVariables = returnType.getNestedTypeParameters().map { conversion[it] }.filterNotNull()
|
val freshVariables = returnType.getNestedTypeParameters().map { conversion[it] }.filterNotNull()
|
||||||
builder.registerTypeVariables(resultingCall.call.toHandle(), freshVariables, external = true)
|
builder.registerTypeVariables(resultingCall.call.toHandle(), freshVariables, external = true)
|
||||||
|
|
||||||
builder.addSubtypeConstraint(candidateWithFreshVariables.returnType, effectiveExpectedType, constraintPosition)
|
builder.addSubtypeConstraint(
|
||||||
|
candidateWithFreshVariables.returnType,
|
||||||
|
builder.compositeSubstitutor().substitute(effectiveExpectedType, Variance.INVARIANT),
|
||||||
|
constraintPosition
|
||||||
|
)
|
||||||
|
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -222,6 +244,9 @@ class GenericCandidateResolver(private val argumentTypeResolver: ArgumentTypeRes
|
|||||||
val dataFlowInfoForArguments = context.candidateCall.dataFlowInfoForArguments
|
val dataFlowInfoForArguments = context.candidateCall.dataFlowInfoForArguments
|
||||||
val dataFlowInfoForArgument = dataFlowInfoForArguments.getInfo(valueArgument)
|
val dataFlowInfoForArgument = dataFlowInfoForArguments.getInfo(valueArgument)
|
||||||
|
|
||||||
|
val effectiveExpectedTypeInSystem =
|
||||||
|
constraintSystem.typeVariableSubstitutors[context.call.toHandle()]?.substitute(effectiveExpectedType, Variance.INVARIANT)
|
||||||
|
|
||||||
//todo analyze function literal body once in 'dependent' mode, then complete it with respect to expected type
|
//todo analyze function literal body once in 'dependent' mode, then complete it with respect to expected type
|
||||||
val hasExpectedReturnType = !hasUnknownReturnType(expectedType)
|
val hasExpectedReturnType = !hasUnknownReturnType(expectedType)
|
||||||
val position = VALUE_PARAMETER_POSITION.position(valueParameterDescriptor.index)
|
val position = VALUE_PARAMETER_POSITION.position(valueParameterDescriptor.index)
|
||||||
@@ -239,7 +264,7 @@ class GenericCandidateResolver(private val argumentTypeResolver: ArgumentTypeRes
|
|||||||
val type = argumentTypeResolver.getFunctionLiteralTypeInfo(
|
val type = argumentTypeResolver.getFunctionLiteralTypeInfo(
|
||||||
argumentExpression, functionLiteral, newContext, RESOLVE_FUNCTION_ARGUMENTS).type
|
argumentExpression, functionLiteral, newContext, RESOLVE_FUNCTION_ARGUMENTS).type
|
||||||
if (!mismatch[0]) {
|
if (!mismatch[0]) {
|
||||||
constraintSystem.addSubtypeConstraint(type, effectiveExpectedType, position)
|
constraintSystem.addSubtypeConstraint(type, effectiveExpectedTypeInSystem, position)
|
||||||
temporaryToResolveFunctionLiteral.commit()
|
temporaryToResolveFunctionLiteral.commit()
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@@ -248,7 +273,7 @@ class GenericCandidateResolver(private val argumentTypeResolver: ArgumentTypeRes
|
|||||||
val newContext = context.replaceExpectedType(expectedTypeWithoutReturnType).replaceDataFlowInfo(dataFlowInfoForArgument)
|
val newContext = context.replaceExpectedType(expectedTypeWithoutReturnType).replaceDataFlowInfo(dataFlowInfoForArgument)
|
||||||
.replaceContextDependency(INDEPENDENT)
|
.replaceContextDependency(INDEPENDENT)
|
||||||
val type = argumentTypeResolver.getFunctionLiteralTypeInfo(argumentExpression, functionLiteral, newContext, RESOLVE_FUNCTION_ARGUMENTS).type
|
val type = argumentTypeResolver.getFunctionLiteralTypeInfo(argumentExpression, functionLiteral, newContext, RESOLVE_FUNCTION_ARGUMENTS).type
|
||||||
constraintSystem.addSubtypeConstraint(type, effectiveExpectedType, position)
|
constraintSystem.addSubtypeConstraint(type, effectiveExpectedTypeInSystem, position)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun <D : CallableDescriptor> addConstraintForCallableReference(
|
private fun <D : CallableDescriptor> addConstraintForCallableReference(
|
||||||
@@ -264,7 +289,11 @@ class GenericCandidateResolver(private val argumentTypeResolver: ArgumentTypeRes
|
|||||||
if (!ReflectionTypes.isCallableType(expectedType)) return
|
if (!ReflectionTypes.isCallableType(expectedType)) return
|
||||||
val resolvedType = getResolvedTypeForCallableReference(callableReference, context, expectedType, valueArgument)
|
val resolvedType = getResolvedTypeForCallableReference(callableReference, context, expectedType, valueArgument)
|
||||||
val position = VALUE_PARAMETER_POSITION.position(valueParameterDescriptor.index)
|
val position = VALUE_PARAMETER_POSITION.position(valueParameterDescriptor.index)
|
||||||
constraintSystem.addSubtypeConstraint(resolvedType, effectiveExpectedType, position)
|
constraintSystem.addSubtypeConstraint(
|
||||||
|
resolvedType,
|
||||||
|
constraintSystem.typeVariableSubstitutors[context.call.toHandle()]?.substitute(effectiveExpectedType, Variance.INVARIANT),
|
||||||
|
position
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun <D : CallableDescriptor> getExpectedTypeForCallableReference(
|
private fun <D : CallableDescriptor> getExpectedTypeForCallableReference(
|
||||||
|
|||||||
+1
-1
@@ -77,7 +77,7 @@ interface ConstraintSystem {
|
|||||||
* For example, for `fun <T> id(t: T) {}` to infer `T` in invocation `id(1)`
|
* For example, for `fun <T> id(t: T) {}` to infer `T` in invocation `id(1)`
|
||||||
* the constraint "Int is a subtype of T" should be generated where T is a subject type, and Int is a constraining type.
|
* the constraint "Int is a subtype of T" should be generated where T is a subject type, and Int is a constraining type.
|
||||||
*/
|
*/
|
||||||
fun addSubtypeConstraint(constrainingType: KotlinType?, subjectType: KotlinType, constraintPosition: ConstraintPosition)
|
fun addSubtypeConstraint(constrainingType: KotlinType?, subjectType: KotlinType?, constraintPosition: ConstraintPosition)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Adds a constraint that the constraining type is a supertype of the subject type.
|
* Adds a constraint that the constraining type is a supertype of the subject type.
|
||||||
|
|||||||
+3
-19
@@ -51,21 +51,9 @@ class ConstraintSystemBuilderImpl : ConstraintSystem.Builder {
|
|||||||
internal val usedInBounds = HashMap<TypeVariable, MutableList<TypeBounds.Bound>>()
|
internal val usedInBounds = HashMap<TypeVariable, MutableList<TypeBounds.Bound>>()
|
||||||
internal val errors = ArrayList<ConstraintError>()
|
internal val errors = ArrayList<ConstraintError>()
|
||||||
internal val initialConstraints = ArrayList<Constraint>()
|
internal val initialConstraints = ArrayList<Constraint>()
|
||||||
internal val descriptorToVariable = LinkedHashMap<TypeParameterDescriptor, TypeVariable>()
|
|
||||||
|
|
||||||
override val typeVariableSubstitutors = LinkedHashMap<CallHandle, TypeSubstitutor>()
|
override val typeVariableSubstitutors = LinkedHashMap<CallHandle, TypeSubstitutor>()
|
||||||
|
|
||||||
private val descriptorToVariableSubstitutor: TypeSubstitutor by lazy {
|
|
||||||
TypeSubstitutor.create(object : TypeConstructorSubstitution() {
|
|
||||||
override fun get(key: TypeConstructor): TypeProjection? {
|
|
||||||
val descriptor = key.declarationDescriptor
|
|
||||||
if (descriptor !is TypeParameterDescriptor) return null
|
|
||||||
val typeVariable = descriptorToVariable[descriptor] ?: return null
|
|
||||||
return TypeProjectionImpl(typeVariable.type)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun storeSubstitutor(call: CallHandle, substitutor: TypeSubstitutor): TypeSubstitutor {
|
private fun storeSubstitutor(call: CallHandle, substitutor: TypeSubstitutor): TypeSubstitutor {
|
||||||
if (typeVariableSubstitutors.containsKey(call)) {
|
if (typeVariableSubstitutors.containsKey(call)) {
|
||||||
throw IllegalStateException("Type variables for the same call can be registered only once: $call")
|
throw IllegalStateException("Type variables for the same call can be registered only once: $call")
|
||||||
@@ -97,7 +85,6 @@ class ConstraintSystemBuilderImpl : ConstraintSystem.Builder {
|
|||||||
|
|
||||||
for ((descriptor, typeVariable) in typeParameters.zip(typeVariables)) {
|
for ((descriptor, typeVariable) in typeParameters.zip(typeVariables)) {
|
||||||
allTypeParameterBounds.put(typeVariable, TypeBoundsImpl(typeVariable))
|
allTypeParameterBounds.put(typeVariable, TypeBoundsImpl(typeVariable))
|
||||||
descriptorToVariable[descriptor] = typeVariable
|
|
||||||
}
|
}
|
||||||
|
|
||||||
for ((typeVariable, typeBounds) in allTypeParameterBounds) {
|
for ((typeVariable, typeBounds) in allTypeParameterBounds) {
|
||||||
@@ -124,9 +111,8 @@ class ConstraintSystemBuilderImpl : ConstraintSystem.Builder {
|
|||||||
addConstraint(SUB_TYPE, subjectType, constrainingType, ConstraintContext(constraintPosition, initial = true))
|
addConstraint(SUB_TYPE, subjectType, constrainingType, ConstraintContext(constraintPosition, initial = true))
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun addSubtypeConstraint(constrainingType: KotlinType?, subjectType: KotlinType, constraintPosition: ConstraintPosition) {
|
override fun addSubtypeConstraint(constrainingType: KotlinType?, subjectType: KotlinType?, constraintPosition: ConstraintPosition) {
|
||||||
val newSubjectType = descriptorToVariableSubstitutor.substitute(subjectType, Variance.INVARIANT)
|
addConstraint(SUB_TYPE, constrainingType, subjectType, ConstraintContext(constraintPosition, initial = true))
|
||||||
addConstraint(SUB_TYPE, constrainingType, newSubjectType, ConstraintContext(constraintPosition, initial = true))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fun addConstraint(
|
fun addConstraint(
|
||||||
@@ -387,9 +373,7 @@ class ConstraintSystemBuilderImpl : ConstraintSystem.Builder {
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun build(): ConstraintSystem {
|
override fun build(): ConstraintSystem {
|
||||||
return ConstraintSystemImpl(
|
return ConstraintSystemImpl(allTypeParameterBounds, usedInBounds, errors, initialConstraints, typeVariableSubstitutors)
|
||||||
allTypeParameterBounds, usedInBounds, errors, initialConstraints, descriptorToVariable, typeVariableSubstitutors
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+4
-4
@@ -38,7 +38,6 @@ internal class ConstraintSystemImpl(
|
|||||||
private val usedInBounds: Map<TypeVariable, MutableList<TypeBounds.Bound>>,
|
private val usedInBounds: Map<TypeVariable, MutableList<TypeBounds.Bound>>,
|
||||||
private val errors: List<ConstraintError>,
|
private val errors: List<ConstraintError>,
|
||||||
private val initialConstraints: List<ConstraintSystemBuilderImpl.Constraint>,
|
private val initialConstraints: List<ConstraintSystemBuilderImpl.Constraint>,
|
||||||
private val descriptorToVariable: Map<TypeParameterDescriptor, TypeVariable>,
|
|
||||||
private val typeVariableSubstitutors: Map<CallHandle, TypeSubstitutor>
|
private val typeVariableSubstitutors: Map<CallHandle, TypeSubstitutor>
|
||||||
) : ConstraintSystem {
|
) : ConstraintSystem {
|
||||||
private val localTypeParameterBounds: Map<TypeVariable, TypeBoundsImpl>
|
private val localTypeParameterBounds: Map<TypeVariable, TypeBoundsImpl>
|
||||||
@@ -107,13 +106,15 @@ internal class ConstraintSystemImpl(
|
|||||||
}
|
}
|
||||||
|
|
||||||
override val typeParameterDescriptors: Set<TypeParameterDescriptor>
|
override val typeParameterDescriptors: Set<TypeParameterDescriptor>
|
||||||
get() = descriptorToVariable.keys
|
get() = typeVariables.map { it.originalTypeParameter }.toSet()
|
||||||
|
|
||||||
override val typeVariables: Set<TypeVariable>
|
override val typeVariables: Set<TypeVariable>
|
||||||
get() = allTypeParameterBounds.keys
|
get() = allTypeParameterBounds.keys
|
||||||
|
|
||||||
override fun descriptorToVariable(call: CallHandle, descriptor: TypeParameterDescriptor): TypeVariable =
|
override fun descriptorToVariable(call: CallHandle, descriptor: TypeParameterDescriptor): TypeVariable =
|
||||||
descriptorToVariable[descriptor] ?: throw IllegalArgumentException("Unknown descriptor: $descriptor, call: $call")
|
typeVariables.firstOrNull {
|
||||||
|
it.call == call && it.originalTypeParameter == descriptor
|
||||||
|
} ?: throw IllegalArgumentException("Unknown descriptor: $descriptor, call: $call")
|
||||||
|
|
||||||
override fun getTypeBounds(typeVariable: TypeVariable): TypeBoundsImpl {
|
override fun getTypeBounds(typeVariable: TypeVariable): TypeBoundsImpl {
|
||||||
return allTypeParameterBounds[typeVariable] ?:
|
return allTypeParameterBounds[typeVariable] ?:
|
||||||
@@ -167,7 +168,6 @@ internal class ConstraintSystemImpl(
|
|||||||
result.errors.addAll(errors.filter { filterConstraintPosition(it.constraintPosition) })
|
result.errors.addAll(errors.filter { filterConstraintPosition(it.constraintPosition) })
|
||||||
|
|
||||||
result.initialConstraints.addAll(initialConstraints.filter { filterConstraintPosition(it.position) })
|
result.initialConstraints.addAll(initialConstraints.filter { filterConstraintPosition(it.position) })
|
||||||
result.descriptorToVariable.putAll(descriptorToVariable)
|
|
||||||
result.typeVariableSubstitutors.putAll(typeVariableSubstitutors)
|
result.typeVariableSubstitutors.putAll(typeVariableSubstitutors)
|
||||||
|
|
||||||
return result
|
return result
|
||||||
|
|||||||
@@ -186,8 +186,8 @@ public class TypeIntersector {
|
|||||||
processAllTypeParameters(withParameters, Variance.INVARIANT, processor);
|
processAllTypeParameters(withParameters, Variance.INVARIANT, processor);
|
||||||
processAllTypeParameters(expected, Variance.INVARIANT, processor);
|
processAllTypeParameters(expected, Variance.INVARIANT, processor);
|
||||||
ConstraintSystem.Builder constraintSystem = new ConstraintSystemBuilderImpl();
|
ConstraintSystem.Builder constraintSystem = new ConstraintSystemBuilderImpl();
|
||||||
constraintSystem.registerTypeVariables(CallHandle.NONE.INSTANCE, parameters.keySet(), false);
|
TypeSubstitutor substitutor = constraintSystem.registerTypeVariables(CallHandle.NONE.INSTANCE, parameters.keySet(), false);
|
||||||
constraintSystem.addSubtypeConstraint(withParameters, expected, SPECIAL.position());
|
constraintSystem.addSubtypeConstraint(withParameters, substitutor.substitute(expected, Variance.INVARIANT), SPECIAL.position());
|
||||||
|
|
||||||
return constraintSystem.build().getStatus().isSuccessful();
|
return constraintSystem.build().getStatus().isSuccessful();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -118,17 +118,14 @@ class FuzzyType(
|
|||||||
val builder = ConstraintSystemBuilderImpl()
|
val builder = ConstraintSystemBuilderImpl()
|
||||||
val typeVariableSubstitutor = builder.registerTypeVariables(CallHandle.NONE, freeParameters + otherType.freeParameters)
|
val typeVariableSubstitutor = builder.registerTypeVariables(CallHandle.NONE, freeParameters + otherType.freeParameters)
|
||||||
|
|
||||||
|
val typeInSystem = typeVariableSubstitutor.substitute(type, Variance.INVARIANT)
|
||||||
|
val otherTypeInSystem = typeVariableSubstitutor.substitute(otherType.type, Variance.INVARIANT)
|
||||||
|
|
||||||
when (matchKind) {
|
when (matchKind) {
|
||||||
MatchKind.IS_SUBTYPE -> builder.addSubtypeConstraint(
|
MatchKind.IS_SUBTYPE ->
|
||||||
typeVariableSubstitutor.substitute(type, Variance.INVARIANT),
|
builder.addSubtypeConstraint(typeInSystem, otherTypeInSystem, ConstraintPositionKind.RECEIVER_POSITION.position())
|
||||||
otherType.type,
|
MatchKind.IS_SUPERTYPE ->
|
||||||
ConstraintPositionKind.RECEIVER_POSITION.position()
|
builder.addSubtypeConstraint(otherTypeInSystem, typeInSystem, ConstraintPositionKind.RECEIVER_POSITION.position())
|
||||||
)
|
|
||||||
MatchKind.IS_SUPERTYPE -> builder.addSubtypeConstraint(
|
|
||||||
typeVariableSubstitutor.substitute(otherType.type, Variance.INVARIANT),
|
|
||||||
type,
|
|
||||||
ConstraintPositionKind.RECEIVER_POSITION.position()
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
builder.fixVariables()
|
builder.fixVariables()
|
||||||
|
|||||||
Reference in New Issue
Block a user