Add more methods to interface ConstraintSystem
To minimize usages of ConstraintSystemImpl
This commit is contained in:
@@ -207,7 +207,7 @@ public object Renderers {
|
||||
public fun renderParameterConstraintError(
|
||||
inferenceErrorData: InferenceErrorData, renderer: TabledDescriptorRenderer
|
||||
): TabledDescriptorRenderer {
|
||||
val constraintErrors = (inferenceErrorData.constraintSystem as ConstraintSystemImpl).constraintErrors
|
||||
val constraintErrors = inferenceErrorData.constraintSystem.getStatus().constraintErrors
|
||||
val errorPositions = constraintErrors.filter { it is ParameterConstraintError }.map { it.constraintPosition }
|
||||
return renderer.table(
|
||||
TabledDescriptorRenderer
|
||||
@@ -308,8 +308,8 @@ public object Renderers {
|
||||
public fun renderCannotCaptureTypeParameterError(
|
||||
inferenceErrorData: InferenceErrorData, result: TabledDescriptorRenderer
|
||||
): TabledDescriptorRenderer {
|
||||
val constraintSystem = inferenceErrorData.constraintSystem as ConstraintSystemImpl
|
||||
val errors = constraintSystem.constraintErrors
|
||||
val constraintSystem = inferenceErrorData.constraintSystem
|
||||
val errors = constraintSystem.getStatus().constraintErrors
|
||||
val typeParameterWithCapturedConstraint = (errors.firstOrNull { it is CannotCapture } as? CannotCapture)?.typeVariable
|
||||
if (typeParameterWithCapturedConstraint == null) {
|
||||
LOG.error(renderDebugMessage("An error 'cannot capture type parameter' is not found in errors", inferenceErrorData))
|
||||
|
||||
@@ -31,7 +31,6 @@ import org.jetbrains.kotlin.resolve.calls.context.BasicCallResolutionContext
|
||||
import org.jetbrains.kotlin.resolve.calls.context.CallCandidateResolutionContext
|
||||
import org.jetbrains.kotlin.resolve.calls.context.CheckArgumentTypesMode
|
||||
import org.jetbrains.kotlin.resolve.calls.inference.ConstraintSystem
|
||||
import org.jetbrains.kotlin.resolve.calls.inference.ConstraintSystemImpl
|
||||
import org.jetbrains.kotlin.resolve.calls.inference.InferenceErrorData
|
||||
import org.jetbrains.kotlin.resolve.calls.inference.constraintPosition.ConstraintPositionKind.*
|
||||
import org.jetbrains.kotlin.resolve.calls.inference.filterConstraintsOut
|
||||
@@ -149,7 +148,7 @@ public class CallCompleter(
|
||||
|
||||
val returnType = getCandidateDescriptor().getReturnType()
|
||||
if (returnType != null) {
|
||||
getConstraintSystem()!!.addSupertypeConstraint(expectedType, returnType, EXPECTED_TYPE_POSITION.position())
|
||||
constraintSystem!!.addSupertypeConstraint(expectedType, returnType, EXPECTED_TYPE_POSITION.position())
|
||||
}
|
||||
|
||||
val constraintSystemCompleter = trace[CONSTRAINT_SYSTEM_COMPLETER, getCall().getCalleeExpression()]
|
||||
@@ -172,10 +171,9 @@ public class CallCompleter(
|
||||
}
|
||||
}
|
||||
|
||||
val constraintSystem = getConstraintSystem() as ConstraintSystemImpl
|
||||
constraintSystem.fixVariables()
|
||||
constraintSystem!!.fixVariables()
|
||||
|
||||
setResultingSubstitutor(getConstraintSystem()!!.getResultingSubstitutor())
|
||||
setResultingSubstitutor(constraintSystem!!.getResultingSubstitutor())
|
||||
}
|
||||
|
||||
private fun <D : CallableDescriptor> MutableResolvedCall<D>.updateResolutionStatusFromConstraintSystem(
|
||||
|
||||
@@ -27,7 +27,6 @@ import org.jetbrains.kotlin.name.Name
|
||||
import org.jetbrains.kotlin.psi.*
|
||||
import org.jetbrains.kotlin.resolve.calls.CallTransformer
|
||||
import org.jetbrains.kotlin.resolve.calls.inference.ConstraintSystem
|
||||
import org.jetbrains.kotlin.resolve.calls.inference.ConstraintSystemImpl
|
||||
import org.jetbrains.kotlin.resolve.calls.inference.constraintPosition.ConstraintPositionKind.EXPECTED_TYPE_POSITION
|
||||
import org.jetbrains.kotlin.resolve.scopes.receivers.ExpressionReceiver
|
||||
import org.jetbrains.kotlin.types.*
|
||||
@@ -70,11 +69,8 @@ private fun getReturnTypeForCallable(type: KotlinType) =
|
||||
type.getArguments().last().getType()
|
||||
|
||||
private fun CallableDescriptor.hasReturnTypeDependentOnUninferredParams(constraintSystem: ConstraintSystem): Boolean {
|
||||
val returnType = getReturnType() ?: return false
|
||||
|
||||
val nestedTypeVariables = with (constraintSystem as ConstraintSystemImpl) {
|
||||
returnType.getNestedTypeVariables()
|
||||
}
|
||||
val returnType = returnType ?: return false
|
||||
val nestedTypeVariables = constraintSystem.getNestedTypeVariables(returnType, original = true)
|
||||
return nestedTypeVariables.any { constraintSystem.getTypeBounds(it).value == null }
|
||||
}
|
||||
|
||||
|
||||
+3
-4
@@ -148,14 +148,13 @@ class GenericCandidateResolver(private val argumentTypeResolver: ArgumentTypeRes
|
||||
val resultingCall = resolutionResults.resultingCall
|
||||
if (resultingCall.isCompleted) return false
|
||||
|
||||
val argumentConstraintSystem = resultingCall.constraintSystem as ConstraintSystemImpl? ?: return false
|
||||
val argumentConstraintSystem = resultingCall.constraintSystem ?: return false
|
||||
|
||||
val candidateDescriptor = resultingCall.candidateDescriptor
|
||||
val returnType = candidateDescriptor.returnType ?: return false
|
||||
|
||||
val nestedTypeVariables = with (argumentConstraintSystem) {
|
||||
returnType.getNestedTypeVariables()
|
||||
}
|
||||
val nestedTypeVariables = argumentConstraintSystem.getNestedTypeVariables(returnType, original = true)
|
||||
|
||||
// we add an additional type variable only if no information is inferred for it.
|
||||
// otherwise we add currently inferred return type as before
|
||||
if (nestedTypeVariables.any { argumentConstraintSystem.getTypeBounds(it).bounds.isNotEmpty() }) return false
|
||||
|
||||
@@ -88,6 +88,10 @@ public interface ConstraintSystem {
|
||||
public fun getPartialSubstitutor(): TypeSubstitutor
|
||||
|
||||
public fun copy(filterConstraintPosition: (ConstraintPosition) -> Boolean = { true }): ConstraintSystem
|
||||
|
||||
public fun fixVariables()
|
||||
|
||||
public fun getNestedTypeVariables(type: KotlinType, original: Boolean): List<TypeParameterDescriptor>
|
||||
}
|
||||
|
||||
fun ConstraintSystem.filterConstraintsOut(excludePositionKind: ConstraintPositionKind): ConstraintSystem {
|
||||
|
||||
+10
-9
@@ -63,8 +63,6 @@ public class ConstraintSystemImpl : ConstraintSystem {
|
||||
private val usedInBounds = HashMap<TypeParameterDescriptor, MutableList<TypeBounds.Bound>>()
|
||||
|
||||
private val errors = ArrayList<ConstraintError>()
|
||||
public val constraintErrors: List<ConstraintError>
|
||||
get() = errors
|
||||
|
||||
private val initialConstraints = ArrayList<Constraint>()
|
||||
|
||||
@@ -106,6 +104,9 @@ public class ConstraintSystemImpl : ConstraintSystem {
|
||||
|
||||
override fun hasTypeParameterWithUnsatisfiedOnlyInputTypesError() =
|
||||
localTypeParameterBounds.values.any { it.typeVariable.hasOnlyInputTypesAnnotation() && it.value == null }
|
||||
|
||||
override val constraintErrors: List<ConstraintError>
|
||||
get() = errors
|
||||
}
|
||||
|
||||
private fun getParameterToInferredValueMap(
|
||||
@@ -171,10 +172,10 @@ public class ConstraintSystemImpl : ConstraintSystem {
|
||||
type -> type.getConstructor().getDeclarationDescriptor() in getAllTypeVariables()
|
||||
}
|
||||
|
||||
fun KotlinType.getNestedTypeVariables(original: Boolean = true): List<TypeParameterDescriptor> {
|
||||
return getNestedArguments().map { typeProjection ->
|
||||
typeProjection.getType().getConstructor().getDeclarationDescriptor() as? TypeParameterDescriptor
|
||||
}.filterNotNull().filter { if (original) it in originalToVariables.keySet() else it in getAllTypeVariables() }
|
||||
override fun getNestedTypeVariables(type: KotlinType, original: Boolean): List<TypeParameterDescriptor> {
|
||||
return type.getNestedArguments().map { typeProjection ->
|
||||
typeProjection.type.constructor.declarationDescriptor as? TypeParameterDescriptor
|
||||
}.filterNotNull().filter { if (original) it in originalToVariables.keys else it in getAllTypeVariables() }
|
||||
}
|
||||
|
||||
override fun copy(filterConstraintPosition: (ConstraintPosition) -> Boolean): ConstraintSystem {
|
||||
@@ -349,7 +350,7 @@ public class ConstraintSystemImpl : ConstraintSystem {
|
||||
typeBounds.addBound(bound)
|
||||
|
||||
if (!bound.isProper) {
|
||||
for (dependentTypeVariable in bound.constrainingType.getNestedTypeVariables(original = false)) {
|
||||
for (dependentTypeVariable in getNestedTypeVariables(bound.constrainingType, original = false)) {
|
||||
val dependentBounds = usedInBounds.getOrPut(dependentTypeVariable) { arrayListOf() }
|
||||
dependentBounds.add(bound)
|
||||
}
|
||||
@@ -489,7 +490,7 @@ public class ConstraintSystemImpl : ConstraintSystem {
|
||||
if (typeBounds.isFixed) return
|
||||
typeBounds.setFixed()
|
||||
|
||||
val nestedTypeVariables = typeBounds.bounds.flatMap { it.constrainingType.getNestedTypeVariables(original = false) }
|
||||
val nestedTypeVariables = typeBounds.bounds.flatMap { getNestedTypeVariables(it.constrainingType, original = false) }
|
||||
nestedTypeVariables.forEach { fixVariable(it) }
|
||||
|
||||
val value = typeBounds.value ?: return
|
||||
@@ -497,7 +498,7 @@ public class ConstraintSystemImpl : ConstraintSystem {
|
||||
addBound(typeVariable, value, TypeBounds.BoundKind.EXACT_BOUND, ConstraintContext(ConstraintPositionKind.FROM_COMPLETER.position()))
|
||||
}
|
||||
|
||||
fun fixVariables() {
|
||||
override fun fixVariables() {
|
||||
// todo variables should be fixed in the right order
|
||||
val (external, functionTypeParameters) = getAllTypeVariables().partition { externalTypeParameters.contains(it) }
|
||||
external.forEach { fixVariable(it) }
|
||||
|
||||
+2
@@ -91,4 +91,6 @@ public interface ConstraintSystemStatus {
|
||||
public fun hasTypeInferenceIncorporationError(): Boolean
|
||||
|
||||
public fun hasTypeParameterWithUnsatisfiedOnlyInputTypesError(): Boolean
|
||||
|
||||
public val constraintErrors: List<ConstraintError>
|
||||
}
|
||||
|
||||
+8
-6
@@ -21,12 +21,13 @@ import org.jetbrains.kotlin.resolve.calls.inference.ConstraintSystemImpl.Constra
|
||||
import org.jetbrains.kotlin.resolve.calls.inference.ConstraintSystemImpl.ConstraintKind.SUB_TYPE
|
||||
import org.jetbrains.kotlin.resolve.calls.inference.TypeBounds.Bound
|
||||
import org.jetbrains.kotlin.resolve.calls.inference.TypeBounds.BoundKind
|
||||
import org.jetbrains.kotlin.resolve.calls.inference.TypeBounds.BoundKind.EXACT_BOUND
|
||||
import org.jetbrains.kotlin.resolve.calls.inference.TypeBounds.BoundKind.LOWER_BOUND
|
||||
import org.jetbrains.kotlin.resolve.calls.inference.TypeBounds.BoundKind.UPPER_BOUND
|
||||
import org.jetbrains.kotlin.resolve.calls.inference.TypeBounds.BoundKind.*
|
||||
import org.jetbrains.kotlin.resolve.calls.inference.constraintPosition.CompoundConstraintPosition
|
||||
import org.jetbrains.kotlin.resolve.calls.inference.constraintPosition.ConstraintPosition
|
||||
import org.jetbrains.kotlin.types.*
|
||||
import org.jetbrains.kotlin.types.KotlinType
|
||||
import org.jetbrains.kotlin.types.TypeProjectionImpl
|
||||
import org.jetbrains.kotlin.types.TypeSubstitutor
|
||||
import org.jetbrains.kotlin.types.Variance
|
||||
import org.jetbrains.kotlin.types.Variance.INVARIANT
|
||||
import org.jetbrains.kotlin.types.typeUtil.getNestedArguments
|
||||
import org.jetbrains.kotlin.types.typesApproximation.approximateCapturedTypes
|
||||
@@ -57,7 +58,8 @@ fun ConstraintSystemImpl.incorporateBound(newBound: Bound) {
|
||||
addBound(getMyTypeVariable(constrainingType)!!, typeVariable.correspondingType, newBound.kind.reverse(), context)
|
||||
return
|
||||
}
|
||||
constrainingType.getNestedTypeVariables().forEach {
|
||||
|
||||
getNestedTypeVariables(constrainingType, original = true).forEach {
|
||||
val boundsForNestedVariable = getTypeBounds(it).bounds
|
||||
for (index in boundsForNestedVariable.indices) {
|
||||
generateNewBound(newBound, boundsForNestedVariable[index])
|
||||
@@ -98,7 +100,7 @@ private fun ConstraintSystemImpl.generateNewBound(bound: Bound, substitution: Bo
|
||||
|
||||
fun addNewBound(newConstrainingType: KotlinType, newBoundKind: BoundKind) {
|
||||
// We don't generate new recursive constraints
|
||||
val nestedTypeVariables = newConstrainingType.getNestedTypeVariables(original = false)
|
||||
val nestedTypeVariables = getNestedTypeVariables(newConstrainingType, original = false)
|
||||
if (nestedTypeVariables.contains(bound.typeVariable)) return
|
||||
|
||||
// We don't generate constraint if a type variable was substituted twice
|
||||
|
||||
Reference in New Issue
Block a user