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
This commit is contained in:
@@ -251,7 +251,7 @@ public object Renderers {
|
|||||||
|
|
||||||
val systemWithoutWeakConstraints = constraintSystem.filterConstraintsOut(ConstraintPositionKind.TYPE_BOUND_POSITION)
|
val systemWithoutWeakConstraints = constraintSystem.filterConstraintsOut(ConstraintPositionKind.TYPE_BOUND_POSITION)
|
||||||
val typeParameterDescriptor = inferenceErrorData.descriptor.typeParameters.firstOrNull {
|
val typeParameterDescriptor = inferenceErrorData.descriptor.typeParameters.firstOrNull {
|
||||||
!ConstraintsUtil.checkUpperBoundIsSatisfied(systemWithoutWeakConstraints, it, true)
|
!ConstraintsUtil.checkUpperBoundIsSatisfied(systemWithoutWeakConstraints, it, inferenceErrorData.call, true)
|
||||||
}
|
}
|
||||||
if (typeParameterDescriptor == null && status.hasConflictingConstraints()) {
|
if (typeParameterDescriptor == null && status.hasConflictingConstraints()) {
|
||||||
return renderConflictingSubstitutionsInferenceError(inferenceErrorData, result)
|
return renderConflictingSubstitutionsInferenceError(inferenceErrorData, result)
|
||||||
@@ -261,8 +261,8 @@ public object Renderers {
|
|||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
val inferredValueForTypeParameter =
|
val typeVariable = systemWithoutWeakConstraints.descriptorToVariable(inferenceErrorData.call.toHandle(), typeParameterDescriptor)
|
||||||
systemWithoutWeakConstraints.getTypeBounds(systemWithoutWeakConstraints.descriptorToVariable(typeParameterDescriptor)).value
|
val inferredValueForTypeParameter = systemWithoutWeakConstraints.getTypeBounds(typeVariable).value
|
||||||
if (inferredValueForTypeParameter == null) {
|
if (inferredValueForTypeParameter == null) {
|
||||||
LOG.error(renderDebugMessage("System without weak constraints is not successful, there is no value for type parameter " +
|
LOG.error(renderDebugMessage("System without weak constraints is not successful, there is no value for type parameter " +
|
||||||
typeParameterDescriptor.getName() + "\n: " + systemWithoutWeakConstraints, inferenceErrorData))
|
typeParameterDescriptor.getName() + "\n: " + systemWithoutWeakConstraints, inferenceErrorData))
|
||||||
|
|||||||
@@ -204,7 +204,8 @@ public class CallCompleter(
|
|||||||
|
|
||||||
val errorData = InferenceErrorData.create(
|
val errorData = InferenceErrorData.create(
|
||||||
getCandidateDescriptor(), getConstraintSystem()!!, valueArgumentsCheckingResult.argumentTypes,
|
getCandidateDescriptor(), getConstraintSystem()!!, valueArgumentsCheckingResult.argumentTypes,
|
||||||
receiverType, context.expectedType)
|
receiverType, context.expectedType, context.call
|
||||||
|
)
|
||||||
tracing.typeInferenceFailed(context.trace, errorData)
|
tracing.typeInferenceFailed(context.trace, errorData)
|
||||||
|
|
||||||
addStatus(ResolutionStatus.OTHER_ERROR)
|
addStatus(ResolutionStatus.OTHER_ERROR)
|
||||||
|
|||||||
+3
-6
@@ -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.ResolutionContext
|
||||||
import org.jetbrains.kotlin.resolve.calls.context.ResolutionResultsCache
|
import org.jetbrains.kotlin.resolve.calls.context.ResolutionResultsCache
|
||||||
import org.jetbrains.kotlin.resolve.calls.context.TemporaryTraceAndCache
|
import org.jetbrains.kotlin.resolve.calls.context.TemporaryTraceAndCache
|
||||||
import org.jetbrains.kotlin.resolve.calls.inference.ConstraintSystem
|
import org.jetbrains.kotlin.resolve.calls.inference.*
|
||||||
import org.jetbrains.kotlin.resolve.calls.inference.ConstraintSystemBuilderImpl
|
|
||||||
import org.jetbrains.kotlin.resolve.calls.inference.constraintPosition.ConstraintPosition
|
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.RECEIVER_POSITION
|
||||||
import org.jetbrains.kotlin.resolve.calls.inference.constraintPosition.ConstraintPositionKind.VALUE_PARAMETER_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
|
||||||
import org.jetbrains.kotlin.resolve.calls.results.ResolutionStatus.INCOMPLETE_TYPE_INFERENCE
|
import org.jetbrains.kotlin.resolve.calls.results.ResolutionStatus.INCOMPLETE_TYPE_INFERENCE
|
||||||
import org.jetbrains.kotlin.resolve.calls.results.ResolutionStatus.OTHER_ERROR
|
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 candidate = candidateCall.candidateDescriptor
|
||||||
|
|
||||||
val builder = ConstraintSystemBuilderImpl()
|
val builder = ConstraintSystemBuilderImpl()
|
||||||
builder.registerTypeVariables(candidate.typeParameters)
|
builder.registerTypeVariables(candidateCall.call.toHandle(), candidate.typeParameters)
|
||||||
|
|
||||||
val substituteDontCare = makeConstantSubstitutor(candidate.typeParameters, DONT_CARE)
|
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 conversion = candidateDescriptor.typeParameters.zip(candidateWithFreshVariables.typeParameters).toMap()
|
||||||
|
|
||||||
val freshVariables = returnType.getNestedTypeParameters().map { conversion[it] }.filterNotNull()
|
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)
|
builder.addSubtypeConstraint(candidateWithFreshVariables.returnType, effectiveExpectedType, constraintPosition)
|
||||||
return true
|
return true
|
||||||
|
|||||||
+4
-2
@@ -34,7 +34,7 @@ interface ConstraintSystem {
|
|||||||
*/
|
*/
|
||||||
val typeVariables: Set<TypeVariable>
|
val typeVariables: Set<TypeVariable>
|
||||||
|
|
||||||
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.
|
* 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
|
* 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
|
* to the corresponding type variables of the system. Use that substitutor to provide constraints to the system
|
||||||
*/
|
*/
|
||||||
fun registerTypeVariables(typeParameters: Collection<TypeParameterDescriptor>, external: Boolean = false): TypeSubstitutor
|
fun registerTypeVariables(
|
||||||
|
call: CallHandle, typeParameters: Collection<TypeParameterDescriptor>, external: Boolean = false
|
||||||
|
): TypeSubstitutor
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Adds a constraint that the constraining type is a subtype of the subject type.
|
* Adds a constraint that the constraining type is a subtype of the subject type.
|
||||||
|
|||||||
+14
-8
@@ -64,19 +64,25 @@ class ConstraintSystemBuilderImpl : ConstraintSystem.Builder {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun registerTypeVariables(typeParameters: Collection<TypeParameterDescriptor>, external: Boolean): TypeSubstitutor {
|
override fun registerTypeVariables(
|
||||||
|
call: CallHandle, typeParameters: Collection<TypeParameterDescriptor>, external: Boolean
|
||||||
|
): TypeSubstitutor {
|
||||||
if (typeParameters.isEmpty()) return TypeSubstitutor.EMPTY
|
if (typeParameters.isEmpty()) return TypeSubstitutor.EMPTY
|
||||||
|
|
||||||
val typeVariables = (if (external) {
|
val typeVariables = if (external) {
|
||||||
typeParameters.toList()
|
typeParameters.map {
|
||||||
|
TypeVariable(call, it, it, true)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else ArrayList<TypeParameterDescriptor>(typeParameters.size).apply {
|
else {
|
||||||
|
val freshTypeParameters = ArrayList<TypeParameterDescriptor>(typeParameters.size)
|
||||||
DescriptorSubstitutor.substituteTypeParameters(
|
DescriptorSubstitutor.substituteTypeParameters(
|
||||||
typeParameters.toList(), TypeSubstitution.EMPTY, typeParameters.first().containingDeclaration, this
|
typeParameters.toList(), TypeSubstitution.EMPTY, typeParameters.first().containingDeclaration, freshTypeParameters
|
||||||
)
|
)
|
||||||
}).zip(typeParameters).map {
|
freshTypeParameters.zip(typeParameters).map {
|
||||||
val (fresh, original) = it
|
val (fresh, original) = it
|
||||||
TypeVariable(fresh, original, external)
|
TypeVariable(call, fresh, original, external)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for ((descriptor, typeVariable) in typeParameters.zip(typeVariables)) {
|
for ((descriptor, typeVariable) in typeParameters.zip(typeVariables)) {
|
||||||
|
|||||||
+2
-2
@@ -111,8 +111,8 @@ internal class ConstraintSystemImpl(
|
|||||||
override val typeVariables: Set<TypeVariable>
|
override val typeVariables: Set<TypeVariable>
|
||||||
get() = allTypeParameterBounds.keys
|
get() = allTypeParameterBounds.keys
|
||||||
|
|
||||||
override fun descriptorToVariable(descriptor: TypeParameterDescriptor): TypeVariable =
|
override fun descriptorToVariable(call: CallHandle, descriptor: TypeParameterDescriptor): TypeVariable =
|
||||||
descriptorToVariable[descriptor] ?: throw IllegalArgumentException("Unknown descriptor: $descriptor")
|
descriptorToVariable[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] ?:
|
||||||
|
|||||||
+4
-1
@@ -21,6 +21,7 @@ import com.google.common.collect.Maps;
|
|||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
import org.jetbrains.kotlin.descriptors.TypeParameterDescriptor;
|
import org.jetbrains.kotlin.descriptors.TypeParameterDescriptor;
|
||||||
|
import org.jetbrains.kotlin.psi.Call;
|
||||||
import org.jetbrains.kotlin.types.*;
|
import org.jetbrains.kotlin.types.*;
|
||||||
import org.jetbrains.kotlin.types.checker.KotlinTypeChecker;
|
import org.jetbrains.kotlin.types.checker.KotlinTypeChecker;
|
||||||
|
|
||||||
@@ -84,9 +85,11 @@ public class ConstraintsUtil {
|
|||||||
public static boolean checkUpperBoundIsSatisfied(
|
public static boolean checkUpperBoundIsSatisfied(
|
||||||
@NotNull ConstraintSystem constraintSystem,
|
@NotNull ConstraintSystem constraintSystem,
|
||||||
@NotNull TypeParameterDescriptor typeParameter,
|
@NotNull TypeParameterDescriptor typeParameter,
|
||||||
|
@NotNull Call call,
|
||||||
boolean substituteOtherTypeParametersInBound
|
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;
|
if (type == null) return true;
|
||||||
for (KotlinType upperBound : typeParameter.getUpperBounds()) {
|
for (KotlinType upperBound : typeParameter.getUpperBounds()) {
|
||||||
if (!substituteOtherTypeParametersInBound &&
|
if (!substituteOtherTypeParametersInBound &&
|
||||||
|
|||||||
+19
-6
@@ -19,6 +19,7 @@ package org.jetbrains.kotlin.resolve.calls.inference;
|
|||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
import org.jetbrains.kotlin.descriptors.CallableDescriptor;
|
import org.jetbrains.kotlin.descriptors.CallableDescriptor;
|
||||||
|
import org.jetbrains.kotlin.psi.Call;
|
||||||
import org.jetbrains.kotlin.types.KotlinType;
|
import org.jetbrains.kotlin.types.KotlinType;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
@@ -34,22 +35,34 @@ public class InferenceErrorData {
|
|||||||
public final KotlinType expectedType;
|
public final KotlinType expectedType;
|
||||||
@NotNull
|
@NotNull
|
||||||
public final List<KotlinType> valueArgumentsTypes;
|
public final List<KotlinType> valueArgumentsTypes;
|
||||||
|
@NotNull
|
||||||
|
public final Call call;
|
||||||
|
|
||||||
private InferenceErrorData(
|
private InferenceErrorData(
|
||||||
@NotNull CallableDescriptor descriptor, @NotNull ConstraintSystem constraintSystem,
|
@NotNull CallableDescriptor descriptor,
|
||||||
@NotNull List<KotlinType> valueArgumentsTypes, @Nullable KotlinType receiverArgumentType, @NotNull KotlinType expectedType
|
@NotNull ConstraintSystem constraintSystem,
|
||||||
|
@NotNull List<KotlinType> valueArgumentsTypes,
|
||||||
|
@Nullable KotlinType receiverArgumentType,
|
||||||
|
@NotNull KotlinType expectedType,
|
||||||
|
@NotNull Call call
|
||||||
) {
|
) {
|
||||||
this.descriptor = descriptor;
|
this.descriptor = descriptor;
|
||||||
this.constraintSystem = constraintSystem;
|
this.constraintSystem = constraintSystem;
|
||||||
this.receiverArgumentType = receiverArgumentType;
|
this.receiverArgumentType = receiverArgumentType;
|
||||||
this.valueArgumentsTypes = valueArgumentsTypes;
|
this.valueArgumentsTypes = valueArgumentsTypes;
|
||||||
this.expectedType = expectedType;
|
this.expectedType = expectedType;
|
||||||
|
this.call = call;
|
||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
public static InferenceErrorData create(@NotNull CallableDescriptor descriptor, @NotNull ConstraintSystem constraintSystem,
|
public static InferenceErrorData create(
|
||||||
@NotNull List<KotlinType> valueArgumentsTypes, @Nullable KotlinType receiverArgumentType, @NotNull KotlinType expectedType) {
|
@NotNull CallableDescriptor descriptor,
|
||||||
return new InferenceErrorData(descriptor, constraintSystem, valueArgumentsTypes, receiverArgumentType, expectedType);
|
@NotNull ConstraintSystem constraintSystem,
|
||||||
|
@NotNull List<KotlinType> valueArgumentsTypes,
|
||||||
|
@Nullable KotlinType receiverArgumentType,
|
||||||
|
@NotNull KotlinType expectedType,
|
||||||
|
@NotNull Call call
|
||||||
|
) {
|
||||||
|
return new InferenceErrorData(descriptor, constraintSystem, valueArgumentsTypes, receiverArgumentType, expectedType, call);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -19,13 +19,15 @@ package org.jetbrains.kotlin.resolve.calls.inference
|
|||||||
import org.jetbrains.kotlin.descriptors.TypeParameterDescriptor
|
import org.jetbrains.kotlin.descriptors.TypeParameterDescriptor
|
||||||
import org.jetbrains.kotlin.descriptors.annotations.Annotations
|
import org.jetbrains.kotlin.descriptors.annotations.Annotations
|
||||||
import org.jetbrains.kotlin.name.Name
|
import org.jetbrains.kotlin.name.Name
|
||||||
|
import org.jetbrains.kotlin.psi.Call
|
||||||
import org.jetbrains.kotlin.resolve.descriptorUtil.hasOnlyInputTypesAnnotation
|
import org.jetbrains.kotlin.resolve.descriptorUtil.hasOnlyInputTypesAnnotation
|
||||||
import org.jetbrains.kotlin.resolve.scopes.MemberScope
|
import org.jetbrains.kotlin.resolve.scopes.MemberScope
|
||||||
import org.jetbrains.kotlin.types.KotlinType
|
import org.jetbrains.kotlin.types.KotlinType
|
||||||
import org.jetbrains.kotlin.types.KotlinTypeImpl
|
import org.jetbrains.kotlin.types.KotlinTypeImpl
|
||||||
|
|
||||||
class TypeVariable(
|
class TypeVariable(
|
||||||
val freshTypeParameter: TypeParameterDescriptor,
|
val call: CallHandle,
|
||||||
|
internal val freshTypeParameter: TypeParameterDescriptor,
|
||||||
val originalTypeParameter: TypeParameterDescriptor,
|
val originalTypeParameter: TypeParameterDescriptor,
|
||||||
val isExternal: Boolean
|
val isExternal: Boolean
|
||||||
) {
|
) {
|
||||||
@@ -36,3 +38,20 @@ class TypeVariable(
|
|||||||
fun hasOnlyInputTypesAnnotation(): Boolean =
|
fun hasOnlyInputTypesAnnotation(): Boolean =
|
||||||
originalTypeParameter.hasOnlyInputTypesAnnotation()
|
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)
|
||||||
|
|||||||
+4
-2
@@ -24,8 +24,10 @@ import org.jetbrains.kotlin.types.TypeProjection
|
|||||||
import org.jetbrains.kotlin.types.TypeProjectionImpl
|
import org.jetbrains.kotlin.types.TypeProjectionImpl
|
||||||
import java.util.*
|
import java.util.*
|
||||||
|
|
||||||
fun ConstraintSystem.getNestedTypeVariables(type: KotlinType): List<TypeVariable> =
|
fun ConstraintSystem.getNestedTypeVariables(type: KotlinType): List<TypeVariable> {
|
||||||
type.getNestedTypeParameters().filter { it in typeParameterDescriptors }.map { descriptorToVariable(it) }
|
val nestedTypeParameters = type.getNestedTypeParameters().toSet()
|
||||||
|
return typeVariables.filter { it.originalTypeParameter in nestedTypeParameters }
|
||||||
|
}
|
||||||
|
|
||||||
fun ConstraintSystem.filterConstraintsOut(excludePositionKind: ConstraintPositionKind): ConstraintSystem {
|
fun ConstraintSystem.filterConstraintsOut(excludePositionKind: ConstraintPositionKind): ConstraintSystem {
|
||||||
return toBuilder { !it.derivedFrom(excludePositionKind) }.build()
|
return toBuilder { !it.derivedFrom(excludePositionKind) }.build()
|
||||||
|
|||||||
@@ -24,6 +24,7 @@ import org.jetbrains.kotlin.builtins.KotlinBuiltIns;
|
|||||||
import org.jetbrains.kotlin.descriptors.ClassifierDescriptor;
|
import org.jetbrains.kotlin.descriptors.ClassifierDescriptor;
|
||||||
import org.jetbrains.kotlin.descriptors.TypeParameterDescriptor;
|
import org.jetbrains.kotlin.descriptors.TypeParameterDescriptor;
|
||||||
import org.jetbrains.kotlin.descriptors.annotations.Annotations;
|
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.ConstraintSystem;
|
||||||
import org.jetbrains.kotlin.resolve.calls.inference.ConstraintSystemBuilderImpl;
|
import org.jetbrains.kotlin.resolve.calls.inference.ConstraintSystemBuilderImpl;
|
||||||
import org.jetbrains.kotlin.resolve.scopes.ChainedScope;
|
import org.jetbrains.kotlin.resolve.scopes.ChainedScope;
|
||||||
@@ -185,7 +186,7 @@ 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(parameters.keySet(), false);
|
constraintSystem.registerTypeVariables(CallHandle.NONE.INSTANCE, parameters.keySet(), false);
|
||||||
constraintSystem.addSubtypeConstraint(withParameters, expected, SPECIAL.position());
|
constraintSystem.addSubtypeConstraint(withParameters, expected, SPECIAL.position());
|
||||||
|
|
||||||
return constraintSystem.build().getStatus().isSuccessful();
|
return constraintSystem.build().getStatus().isSuccessful();
|
||||||
|
|||||||
+2
-1
@@ -20,6 +20,7 @@ import org.jetbrains.kotlin.cli.jvm.compiler.KotlinCoreEnvironment
|
|||||||
import org.jetbrains.kotlin.diagnostics.rendering.Renderers
|
import org.jetbrains.kotlin.diagnostics.rendering.Renderers
|
||||||
import org.jetbrains.kotlin.renderer.DescriptorRenderer
|
import org.jetbrains.kotlin.renderer.DescriptorRenderer
|
||||||
import org.jetbrains.kotlin.resolve.TypeResolver
|
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.ConstraintContext
|
||||||
import org.jetbrains.kotlin.resolve.calls.inference.ConstraintSystemBuilderImpl
|
import org.jetbrains.kotlin.resolve.calls.inference.ConstraintSystemBuilderImpl
|
||||||
import org.jetbrains.kotlin.resolve.calls.inference.constraintPosition.ConstraintPositionKind.SPECIAL
|
import org.jetbrains.kotlin.resolve.calls.inference.constraintPosition.ConstraintPositionKind.SPECIAL
|
||||||
@@ -81,7 +82,7 @@ abstract public class AbstractConstraintSystemTest() : KotlinLiteFixture() {
|
|||||||
val variables = parseVariables(constraintsFileText)
|
val variables = parseVariables(constraintsFileText)
|
||||||
val fixVariables = constraintsFileText.contains("FIX_VARIABLES")
|
val fixVariables = constraintsFileText.contains("FIX_VARIABLES")
|
||||||
val typeParameterDescriptors = variables.map { testDeclarations.getParameterDescriptor(it) }
|
val typeParameterDescriptors = variables.map { testDeclarations.getParameterDescriptor(it) }
|
||||||
val substitutor = builder.registerTypeVariables(typeParameterDescriptors)
|
val substitutor = builder.registerTypeVariables(CallHandle.NONE, typeParameterDescriptors)
|
||||||
|
|
||||||
val constraints = parseConstraints(constraintsFileText)
|
val constraints = parseConstraints(constraintsFileText)
|
||||||
|
|
||||||
|
|||||||
@@ -20,6 +20,7 @@ package org.jetbrains.kotlin.idea.util
|
|||||||
|
|
||||||
import org.jetbrains.kotlin.descriptors.CallableDescriptor
|
import org.jetbrains.kotlin.descriptors.CallableDescriptor
|
||||||
import org.jetbrains.kotlin.descriptors.TypeParameterDescriptor
|
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.ConstraintSystemBuilderImpl
|
||||||
import org.jetbrains.kotlin.resolve.calls.inference.constraintPosition.ConstraintPositionKind
|
import org.jetbrains.kotlin.resolve.calls.inference.constraintPosition.ConstraintPositionKind
|
||||||
import org.jetbrains.kotlin.types.*
|
import org.jetbrains.kotlin.types.*
|
||||||
@@ -115,7 +116,7 @@ class FuzzyType(
|
|||||||
}
|
}
|
||||||
|
|
||||||
val builder = ConstraintSystemBuilderImpl()
|
val builder = ConstraintSystemBuilderImpl()
|
||||||
val typeVariableSubstitutor = builder.registerTypeVariables(freeParameters + otherType.freeParameters)
|
val typeVariableSubstitutor = builder.registerTypeVariables(CallHandle.NONE, freeParameters + otherType.freeParameters)
|
||||||
|
|
||||||
when (matchKind) {
|
when (matchKind) {
|
||||||
MatchKind.IS_SUBTYPE -> builder.addSubtypeConstraint(
|
MatchKind.IS_SUBTYPE -> builder.addSubtypeConstraint(
|
||||||
|
|||||||
@@ -87,7 +87,8 @@ public class AddGenericUpperBoundFix(
|
|||||||
typeParameterDescriptor ->
|
typeParameterDescriptor ->
|
||||||
|
|
||||||
if (ConstraintsUtil.checkUpperBoundIsSatisfied(
|
if (ConstraintsUtil.checkUpperBoundIsSatisfied(
|
||||||
successfulConstraintSystem, typeParameterDescriptor, /* substituteOtherTypeParametersInBound */ true
|
successfulConstraintSystem, typeParameterDescriptor, inferenceData.call,
|
||||||
|
/* substituteOtherTypeParametersInBound */ true
|
||||||
)) return@factory null
|
)) return@factory null
|
||||||
|
|
||||||
val upperBound = typeParameterDescriptor.upperBounds.singleOrNull() ?: return@factory null
|
val upperBound = typeParameterDescriptor.upperBounds.singleOrNull() ?: return@factory null
|
||||||
|
|||||||
Reference in New Issue
Block a user