Inference for type alias constructor type arguments: better error reporting.
This commit is contained in:
@@ -40,14 +40,11 @@ import org.jetbrains.kotlin.resolve.calls.inference.TypeBounds.BoundKind.LOWER_B
|
||||
import org.jetbrains.kotlin.resolve.calls.inference.TypeBounds.BoundKind.UPPER_BOUND
|
||||
import org.jetbrains.kotlin.resolve.calls.inference.constraintPosition.ConstraintPosition
|
||||
import org.jetbrains.kotlin.resolve.calls.inference.constraintPosition.ConstraintPositionKind
|
||||
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.*
|
||||
import org.jetbrains.kotlin.resolve.calls.inference.constraintPosition.derivedFrom
|
||||
import org.jetbrains.kotlin.resolve.calls.inference.constraintPosition.getValidityConstraintForConstituentType
|
||||
import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall
|
||||
import org.jetbrains.kotlin.types.KotlinType
|
||||
import org.jetbrains.kotlin.types.TypeIntersector
|
||||
import org.jetbrains.kotlin.types.TypeUtils
|
||||
import org.jetbrains.kotlin.types.Variance
|
||||
import org.jetbrains.kotlin.types.*
|
||||
import org.jetbrains.kotlin.types.checker.KotlinTypeChecker
|
||||
import org.jetbrains.kotlin.utils.addToStdlib.firstIsInstanceOrNull
|
||||
import java.io.PrintWriter
|
||||
@@ -270,14 +267,16 @@ object Renderers {
|
||||
LOG.assertTrue(status.hasViolatedUpperBound(),
|
||||
debugMessage("Upper bound violated renderer is applied for incorrect status", inferenceErrorData))
|
||||
|
||||
val systemWithoutWeakConstraints = constraintSystem.filterConstraintsOut(ConstraintPositionKind.TYPE_BOUND_POSITION)
|
||||
val systemWithoutWeakConstraints = constraintSystem.filterConstraintsOut(TYPE_BOUND_POSITION)
|
||||
val typeParameterDescriptor = inferenceErrorData.descriptor.typeParameters.firstOrNull {
|
||||
!ConstraintsUtil.checkUpperBoundIsSatisfied(systemWithoutWeakConstraints, it, inferenceErrorData.call, true)
|
||||
}
|
||||
|
||||
if (typeParameterDescriptor == null) {
|
||||
if (inferenceErrorData.descriptor is TypeAliasConstructorDescriptor) {
|
||||
renderUpperBoundViolatedInferenceErrorForTypeAliasConstructor(inferenceErrorData, result, systemWithoutWeakConstraints)?.let {
|
||||
renderUpperBoundViolatedInferenceErrorForTypeAliasConstructor(
|
||||
inferenceErrorData, result, systemWithoutWeakConstraints
|
||||
)?.let {
|
||||
return it
|
||||
}
|
||||
}
|
||||
@@ -342,11 +341,20 @@ object Renderers {
|
||||
return result
|
||||
}
|
||||
|
||||
val inferredTypeSubstitutor = systemWithoutWeakConstraints.resultingSubstitutor
|
||||
val inferredTypesForTypeParameters = descriptor.typeParameters.map {
|
||||
val typeVariable = systemWithoutWeakConstraints.descriptorToVariable(inferenceErrorData.call.toHandle(), it)
|
||||
systemWithoutWeakConstraints.getTypeBounds(typeVariable).value
|
||||
}
|
||||
val inferredTypeSubstitutor = TypeSubstitutor.create(object : TypeConstructorSubstitution() {
|
||||
override fun get(key: TypeConstructor): TypeProjection? {
|
||||
val typeDescriptor = key.declarationDescriptor as? TypeParameterDescriptor ?: return null
|
||||
if (typeDescriptor.containingDeclaration != descriptor.typeAliasDescriptor) return null
|
||||
return inferredTypesForTypeParameters[typeDescriptor.index]?.let { TypeProjectionImpl(it) }
|
||||
}
|
||||
})
|
||||
|
||||
for (constraintError in inferenceErrorData.constraintSystem.status.constraintErrors) {
|
||||
val constraintInfo = constraintError.constraintPosition.getValidityConstraintForConstituentType() ?: continue
|
||||
if (constraintInfo.typeParameter.variance == Variance.IN_VARIANCE) continue
|
||||
|
||||
val violatedUpperBound = inferredTypeSubstitutor.safeSubstitute(constraintInfo.bound, Variance.INVARIANT)
|
||||
val violatingInferredType = inferredTypeSubstitutor.safeSubstitute(constraintInfo.typeArgument, Variance.INVARIANT)
|
||||
|
||||
+10
-7
@@ -18,7 +18,9 @@ package org.jetbrains.kotlin.resolve.calls
|
||||
|
||||
import org.jetbrains.kotlin.builtins.ReflectionTypes
|
||||
import org.jetbrains.kotlin.builtins.isFunctionTypeOrSubtype
|
||||
import org.jetbrains.kotlin.descriptors.*
|
||||
import org.jetbrains.kotlin.descriptors.CallableDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.TypeParameterDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.ValueParameterDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.impl.TypeAliasConstructorDescriptor
|
||||
import org.jetbrains.kotlin.psi.*
|
||||
import org.jetbrains.kotlin.resolve.FunctionDescriptorUtil
|
||||
@@ -33,11 +35,10 @@ 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.*
|
||||
import org.jetbrains.kotlin.resolve.calls.inference.constraintPosition.ValidityConstraintForConstituentType
|
||||
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.TYPE_BOUND_POSITION
|
||||
import org.jetbrains.kotlin.resolve.calls.inference.constraintPosition.ConstraintPositionKind.VALUE_PARAMETER_POSITION
|
||||
import org.jetbrains.kotlin.resolve.calls.inference.constraintPosition.ValidityConstraintForConstituentType
|
||||
import org.jetbrains.kotlin.resolve.calls.resolvedCallUtil.makeNullableTypeIfSafeReceiver
|
||||
import org.jetbrains.kotlin.resolve.calls.results.ResolutionStatus
|
||||
import org.jetbrains.kotlin.resolve.calls.results.ResolutionStatus.INCOMPLETE_TYPE_INFERENCE
|
||||
@@ -122,20 +123,22 @@ class GenericCandidateResolver(private val argumentTypeResolver: ArgumentTypeRes
|
||||
|
||||
val typeParameter = typeConstructor.parameters[i]
|
||||
addValidityConstraintsForTypeArgument(builder, typeProjection, typeParameter, boundsSubstitutor)
|
||||
|
||||
addValidityConstraintsForConstituentTypes(builder, typeProjection.type)
|
||||
}
|
||||
}
|
||||
|
||||
private fun addValidityConstraintsForTypeArgument(
|
||||
builder: ConstraintSystem.Builder,
|
||||
typeProjection: TypeProjection,
|
||||
substitutedArgument: TypeProjection,
|
||||
typeParameter: TypeParameterDescriptor,
|
||||
boundsSubstitutor: TypeSubstitutor
|
||||
) {
|
||||
val typeArgument = typeProjection.type
|
||||
val substitutedType = substitutedArgument.type
|
||||
for (upperBound in typeParameter.upperBounds) {
|
||||
val substitutedUpperBound = boundsSubstitutor.safeSubstitute(upperBound, Variance.INVARIANT)
|
||||
val constraintPosition = ValidityConstraintForConstituentType(typeArgument, typeParameter, substitutedUpperBound)
|
||||
builder.addSubtypeConstraint(typeArgument, substitutedUpperBound, constraintPosition)
|
||||
val constraintPosition = ValidityConstraintForConstituentType(substitutedType, typeParameter, substitutedUpperBound)
|
||||
builder.addSubtypeConstraint(substitutedType, substitutedUpperBound, constraintPosition)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user