Introduce frontend independent constraint positions

This commit is contained in:
Dmitriy Novozhilov
2020-08-25 17:30:18 +03:00
parent e5e3d7cab1
commit fae21d4db3
23 changed files with 151 additions and 99 deletions
@@ -17,7 +17,7 @@ import org.jetbrains.kotlin.fir.symbols.impl.FirTypeParameterSymbol
import org.jetbrains.kotlin.fir.types.*
import org.jetbrains.kotlin.fir.types.impl.FirTypePlaceholderProjection
import org.jetbrains.kotlin.resolve.calls.inference.ConstraintSystemOperation
import org.jetbrains.kotlin.resolve.calls.inference.model.FirDeclaredUpperBoundConstraintPosition
import org.jetbrains.kotlin.fir.resolve.inference.model.FirDeclaredUpperBoundConstraintPosition
import org.jetbrains.kotlin.resolve.calls.inference.model.SimpleConstraintSystemConstraintPosition
internal object CreateFreshTypeVariableSubstitutorStage : ResolutionStage() {
@@ -190,7 +190,7 @@ class FirBuilderInferenceSession(
for ((variableConstructor, type) in storage.fixedTypeVariables) {
val typeVariable = storage.allTypeVariables.getValue(variableConstructor)
commonSystem.registerVariable(typeVariable)
commonSystem.addEqualityConstraint((typeVariable as ConeTypeVariable).defaultType, type, CoroutinePosition())
commonSystem.addEqualityConstraint((typeVariable as ConeTypeVariable).defaultType, type, CoroutinePosition)
introducedConstraint = true
}
}
@@ -142,7 +142,7 @@ class PostponedArgumentsAnalyzer(
val variable = variableWithConstraints.typeVariable as ConeTypeVariable
c.getBuilder().unmarkPostponedVariable(variable)
c.getBuilder().addEqualityConstraint(variable.defaultType, resultType, CoroutinePosition())
c.getBuilder().addEqualityConstraint(variable.defaultType, resultType, CoroutinePosition)
}
}
}
@@ -0,0 +1,10 @@
/*
* Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/
package org.jetbrains.kotlin.fir.resolve.inference.model
import org.jetbrains.kotlin.resolve.calls.inference.model.DeclaredUpperBoundConstraintPosition
class FirDeclaredUpperBoundConstraintPosition : DeclaredUpperBoundConstraintPosition<Nothing?>(null)
@@ -14,7 +14,7 @@ import org.jetbrains.kotlin.resolve.calls.inference.ConstraintSystemBuilder
import org.jetbrains.kotlin.resolve.calls.inference.NewConstraintSystem
import org.jetbrains.kotlin.resolve.calls.inference.components.KotlinConstraintSystemCompleter
import org.jetbrains.kotlin.resolve.calls.inference.model.ConstraintStorage
import org.jetbrains.kotlin.resolve.calls.inference.model.DelegatedPropertyConstraintPosition
import org.jetbrains.kotlin.resolve.calls.inference.model.DelegatedPropertyConstraintPositionImpl
import org.jetbrains.kotlin.resolve.calls.model.*
import org.jetbrains.kotlin.resolve.calls.tower.ManyCandidatesResolver
import org.jetbrains.kotlin.resolve.calls.tower.PSICallResolver
@@ -54,7 +54,7 @@ class DelegatedPropertyInferenceSession(
val valueParameterForThis = descriptor.valueParameters.getOrNull(0) ?: return
val substitutedType = freshVariablesSubstitutor.safeSubstitute(valueParameterForThis.type.unwrap())
commonSystem.addSubtypeConstraint(typeOfThis.unwrap(), substitutedType, DelegatedPropertyConstraintPosition(atom))
commonSystem.addSubtypeConstraint(typeOfThis.unwrap(), substitutedType, DelegatedPropertyConstraintPositionImpl(atom))
}
private fun ResolvedCallAtom.addConstraintsForGetValueMethod(commonSystem: ConstraintSystemBuilder) {
@@ -62,7 +62,7 @@ class DelegatedPropertyInferenceSession(
val unsubstitutedReturnType = candidateDescriptor.returnType?.unwrap() ?: return
val substitutedReturnType = freshVariablesSubstitutor.safeSubstitute(unsubstitutedReturnType)
commonSystem.addSubtypeConstraint(substitutedReturnType, expectedType, DelegatedPropertyConstraintPosition(atom))
commonSystem.addSubtypeConstraint(substitutedReturnType, expectedType, DelegatedPropertyConstraintPositionImpl(atom))
}
addConstraintForThis(candidateDescriptor, commonSystem)
@@ -73,7 +73,7 @@ class DelegatedPropertyInferenceSession(
val unsubstitutedParameterType = candidateDescriptor.valueParameters.getOrNull(2)?.type?.unwrap() ?: return
val substitutedParameterType = freshVariablesSubstitutor.safeSubstitute(unsubstitutedParameterType)
commonSystem.addSubtypeConstraint(expectedType, substitutedParameterType, DelegatedPropertyConstraintPosition(atom))
commonSystem.addSubtypeConstraint(expectedType, substitutedParameterType, DelegatedPropertyConstraintPositionImpl(atom))
}
addConstraintForThis(candidateDescriptor, commonSystem)
@@ -347,10 +347,10 @@ class DiagnosticReporterByTrackingStrategy(
val position = constraintError.position.from
val argument =
when (position) {
is ArgumentConstraintPosition -> position.argument
is ReceiverConstraintPosition -> position.argument
is LHSArgumentConstraintPosition -> position.argument
is LambdaArgumentConstraintPosition -> position.lambda.atom
is ArgumentConstraintPositionImpl -> position.argument
is ReceiverConstraintPositionImpl -> position.argument
is LHSArgumentConstraintPositionImpl -> position.argument
is LambdaArgumentConstraintPositionImpl -> position.lambda.atom
else -> null
}
argument?.let {
@@ -385,7 +385,7 @@ class DiagnosticReporterByTrackingStrategy(
)
}
(position as? ExpectedTypeConstraintPosition)?.let {
(position as? ExpectedTypeConstraintPositionImpl)?.let {
val call = it.topLevelCall.psiKotlinCall.psiCall.callElement.safeAs<KtExpression>()
val inferredType =
if (!constraintError.lowerKotlinType.isNullableNothing()) constraintError.lowerKotlinType
@@ -401,7 +401,7 @@ class DiagnosticReporterByTrackingStrategy(
}
}
(position as? ExplicitTypeParameterConstraintPosition)?.let {
(position as? ExplicitTypeParameterConstraintPositionImpl)?.let {
val typeArgumentReference = (it.typeArgument as SimpleTypeArgumentImpl).typeReference
trace.report(
UPPER_BOUND_VIOLATED.on(
@@ -412,9 +412,9 @@ class DiagnosticReporterByTrackingStrategy(
)
}
(position as? FixVariableConstraintPosition)?.let {
(position as? FixVariableConstraintPositionImpl)?.let {
val morePreciseDiagnosticExists = allDiagnostics.any { other ->
other is NewConstraintError && other.position.from !is FixVariableConstraintPosition
other is NewConstraintError && other.position.from !is FixVariableConstraintPositionImpl
}
if (morePreciseDiagnosticExists) return
@@ -435,8 +435,8 @@ class DiagnosticReporterByTrackingStrategy(
val capturedError = diagnostic as CapturedTypeFromSubtyping
val position = capturedError.position
val argumentPosition =
position.safeAs<ArgumentConstraintPosition>()
?: position.safeAs<IncorporationConstraintPosition>()?.from.safeAs<ArgumentConstraintPosition>()
position.safeAs<ArgumentConstraintPositionImpl>()
?: position.safeAs<IncorporationConstraintPosition>()?.from.safeAs<ArgumentConstraintPositionImpl>()
argumentPosition?.let {
val expression = it.argument.psiExpression ?: return
@@ -450,7 +450,7 @@ class DiagnosticReporterByTrackingStrategy(
}
NotEnoughInformationForTypeParameter::class.java -> {
val error = diagnostic as NotEnoughInformationForTypeParameter
val error = diagnostic as NotEnoughInformationForTypeParameterImpl
if (allDiagnostics.any {
(it is ConstrainingTypeIsError && it.typeVariable == error.typeVariable)
|| it is NewConstraintError || it is WrongCountOfTypeArguments
@@ -248,7 +248,7 @@ class CoroutineInferenceSession(
for ((variableConstructor, type) in storage.fixedTypeVariables) {
val typeVariable = storage.allTypeVariables.getValue(variableConstructor)
commonSystem.registerVariable(typeVariable)
commonSystem.addEqualityConstraint((typeVariable as NewTypeVariable).defaultType, type, CoroutinePosition())
commonSystem.addEqualityConstraint((typeVariable as NewTypeVariable).defaultType, type, CoroutinePosition)
introducedConstraint = true
}
}
@@ -909,7 +909,7 @@ class NewResolvedCallImpl<D : CallableDescriptor>(
is CapturedTypeFromSubtyping -> it.position.originalPosition()
is ConstrainingTypeIsError -> it.position.originalPosition()
else -> null
} as? ArgumentConstraintPosition ?: return@forEach
} as? ArgumentConstraintPositionImpl ?: return@forEach
val argument = position.argument.safeAs<PSIKotlinCallArgument>()?.valueArgument ?: return@forEach
result += argument to it
@@ -13,7 +13,7 @@ import org.jetbrains.kotlin.descriptors.annotations.Annotations
import org.jetbrains.kotlin.resolve.calls.components.CreateFreshVariablesSubstitutor.createToFreshVariableSubstitutorAndAddInitialConstraints
import org.jetbrains.kotlin.resolve.calls.inference.ConstraintSystemOperation
import org.jetbrains.kotlin.resolve.calls.inference.components.FreshVariableNewTypeSubstitutor
import org.jetbrains.kotlin.resolve.calls.inference.model.ArgumentConstraintPosition
import org.jetbrains.kotlin.resolve.calls.inference.model.ArgumentConstraintPositionImpl
import org.jetbrains.kotlin.resolve.calls.model.*
import org.jetbrains.kotlin.resolve.calls.tasks.ExplicitReceiverKind
import org.jetbrains.kotlin.resolve.calls.tasks.ExplicitReceiverKind.DISPATCH_RECEIVER
@@ -140,7 +140,7 @@ fun ConstraintSystemOperation.checkCallableReference(
expectedType: UnwrappedType?,
ownerDescriptor: DeclarationDescriptor
): Pair<FreshVariableNewTypeSubstitutor, KotlinCallDiagnostic?> {
val position = ArgumentConstraintPosition(argument)
val position = ArgumentConstraintPositionImpl(argument)
val toFreshSubstitutor = createToFreshVariableSubstitutorAndAddInitialConstraints(candidateDescriptor, this)
@@ -165,7 +165,7 @@ private fun ConstraintSystemOperation.addReceiverConstraint(
toFreshSubstitutor: FreshVariableNewTypeSubstitutor,
receiverArgument: CallableReceiver?,
receiverParameter: ReceiverParameterDescriptor?,
position: ArgumentConstraintPosition
position: ArgumentConstraintPositionImpl
) {
if (receiverArgument == null || receiverParameter == null) {
assert(receiverArgument == null) { "Receiver argument should be null if parameter is: $receiverArgument" }
@@ -15,7 +15,7 @@ import org.jetbrains.kotlin.resolve.calls.inference.components.KotlinConstraintS
import org.jetbrains.kotlin.resolve.calls.inference.components.KotlinConstraintSystemCompleter.ConstraintSystemCompletionMode
import org.jetbrains.kotlin.resolve.calls.inference.components.TrivialConstraintTypeInferenceOracle
import org.jetbrains.kotlin.resolve.calls.inference.model.ConstraintStorage.Empty.hasContradiction
import org.jetbrains.kotlin.resolve.calls.inference.model.ExpectedTypeConstraintPosition
import org.jetbrains.kotlin.resolve.calls.inference.model.ExpectedTypeConstraintPositionImpl
import org.jetbrains.kotlin.resolve.calls.model.*
import org.jetbrains.kotlin.resolve.calls.tower.forceResolution
import org.jetbrains.kotlin.types.ErrorUtils
@@ -286,11 +286,11 @@ class KotlinCallCompleter(
expectedType === TypeUtils.UNIT_EXPECTED_TYPE ->
csBuilder.addEqualityConstraintIfCompatible(
returnType, csBuilder.builtIns.unitType, ExpectedTypeConstraintPosition(resolvedCall.atom)
returnType, csBuilder.builtIns.unitType, ExpectedTypeConstraintPositionImpl(resolvedCall.atom)
)
else ->
csBuilder.addSubtypeConstraint(returnType, expectedType, ExpectedTypeConstraintPosition(resolvedCall.atom))
csBuilder.addSubtypeConstraint(returnType, expectedType, ExpectedTypeConstraintPositionImpl(resolvedCall.atom))
}
}
@@ -301,7 +301,7 @@ class KotlinCallCompleter(
if (!callComponents.languageVersionSettings.supportsFeature(LanguageFeature.ExpectedTypeFromCast)) return
if (returnType == null) return
val expectedType = resolutionCallbacks.getExpectedTypeFromAsExpressionAndRecordItInTrace(resolvedCall) ?: return
csBuilder.addSubtypeConstraint(returnType, expectedType, ExpectedTypeConstraintPosition(resolvedCall.atom))
csBuilder.addSubtypeConstraint(returnType, expectedType, ExpectedTypeConstraintPositionImpl(resolvedCall.atom))
}
fun KotlinResolutionCandidate.asCallResolutionResult(
@@ -22,7 +22,10 @@ import org.jetbrains.kotlin.resolve.calls.inference.ConstraintSystemBuilder
import org.jetbrains.kotlin.resolve.calls.inference.components.NewTypeSubstitutor
import org.jetbrains.kotlin.resolve.calls.inference.model.*
import org.jetbrains.kotlin.resolve.calls.model.*
import org.jetbrains.kotlin.types.*
import org.jetbrains.kotlin.types.AbstractTypeChecker
import org.jetbrains.kotlin.types.ErrorUtils
import org.jetbrains.kotlin.types.KotlinType
import org.jetbrains.kotlin.types.UnwrappedType
import org.jetbrains.kotlin.types.checker.convertVariance
import org.jetbrains.kotlin.types.model.TypeVariance
import org.jetbrains.kotlin.types.typeUtil.builtIns
@@ -69,7 +72,7 @@ private fun preprocessLambdaArgument(
if (expectedTypeVariableWithConstraints != null) {
val explicitTypeArgument = expectedTypeVariableWithConstraints.constraints.find {
it.kind == ConstraintKind.EQUALITY && it.position.from is ExplicitTypeParameterConstraintPosition
it.kind == ConstraintKind.EQUALITY && it.position.from is ExplicitTypeParameterConstraintPosition<*>
}?.type as? KotlinType
if (explicitTypeArgument == null || explicitTypeArgument.arguments.isNotEmpty()) {
@@ -86,7 +89,7 @@ private fun preprocessLambdaArgument(
csBuilder.builtIns, Annotations.EMPTY, resolvedArgument.receiver,
resolvedArgument.parameters, null, resolvedArgument.returnType, resolvedArgument.isSuspend
)
csBuilder.addSubtypeConstraint(lambdaType, expectedType, ArgumentConstraintPosition(argument))
csBuilder.addSubtypeConstraint(lambdaType, expectedType, ArgumentConstraintPositionImpl(argument))
}
return resolvedArgument
@@ -278,7 +281,7 @@ private fun ConstraintSystemBuilder.addConstraintFromLHS(
val lhsType = lhsResult.unboundDetailedReceiver.stableType
val expectedTypeProjectionForLHS = expectedType.arguments.first()
val expectedTypeForLHS = expectedTypeProjectionForLHS.type
val constraintPosition = LHSArgumentConstraintPosition(argument, lhsResult.qualifier ?: lhsResult.unboundDetailedReceiver)
val constraintPosition = LHSArgumentConstraintPositionImpl(argument, lhsResult.qualifier ?: lhsResult.unboundDetailedReceiver)
val expectedTypeVariance = expectedTypeProjectionForLHS.projectionKind.convertVariance()
val effectiveVariance = AbstractTypeChecker.effectiveVariance(
expectedType.constructor.parameters.first().variance.convertVariance(),
@@ -14,10 +14,9 @@ import org.jetbrains.kotlin.descriptors.annotations.FilteredAnnotations
import org.jetbrains.kotlin.resolve.calls.inference.ConstraintSystemBuilder
import org.jetbrains.kotlin.resolve.calls.inference.addSubsystemFromArgument
import org.jetbrains.kotlin.resolve.calls.inference.components.KotlinConstraintSystemCompleter
import org.jetbrains.kotlin.resolve.calls.inference.components.NewTypeSubstitutorByConstructorMap
import org.jetbrains.kotlin.resolve.calls.inference.model.ConstraintStorage
import org.jetbrains.kotlin.resolve.calls.inference.model.CoroutinePosition
import org.jetbrains.kotlin.resolve.calls.inference.model.LambdaArgumentConstraintPosition
import org.jetbrains.kotlin.resolve.calls.inference.model.LambdaArgumentConstraintPositionImpl
import org.jetbrains.kotlin.resolve.calls.model.*
import org.jetbrains.kotlin.types.KotlinType
import org.jetbrains.kotlin.types.UnwrappedType
@@ -191,7 +190,7 @@ class PostponedArgumentsAnalyzer(
if (!returnArgumentsInfo.returnArgumentsExist) {
val unitType = lambda.returnType.builtIns.unitType
val lambdaReturnType = lambda.returnType.let(substitute)
c.getBuilder().addSubtypeConstraint(unitType, lambdaReturnType, LambdaArgumentConstraintPosition(lambda))
c.getBuilder().addSubtypeConstraint(unitType, lambdaReturnType, LambdaArgumentConstraintPositionImpl(lambda))
}
lambda.setAnalyzedResults(returnArgumentsInfo, subResolvedKtPrimitives)
@@ -215,7 +214,7 @@ class PostponedArgumentsAnalyzer(
val variable = variableWithConstraints.typeVariable
c.getBuilder().unmarkPostponedVariable(variable)
c.getBuilder().addEqualityConstraint(variable.defaultType(c), resultType, CoroutinePosition())
c.getBuilder().addEqualityConstraint(variable.defaultType(c), resultType, CoroutinePosition)
}
}
}
@@ -142,7 +142,7 @@ internal object CreateFreshVariablesSubstitutor : ResolutionPart() {
csBuilder.addEqualityConstraint(
freshVariable.defaultType,
getTypePreservingFlexibilityWrtTypeVariable(knownTypeArgument.unwrap(), freshVariable),
KnownTypeParameterConstraintPosition(knownTypeArgument)
KnownTypeParameterConstraintPositionImpl(knownTypeArgument)
)
continue
}
@@ -153,7 +153,7 @@ internal object CreateFreshVariablesSubstitutor : ResolutionPart() {
csBuilder.addEqualityConstraint(
freshVariable.defaultType,
getTypePreservingFlexibilityWrtTypeVariable(typeArgument.type, freshVariable),
ExplicitTypeParameterConstraintPosition(typeArgument)
ExplicitTypeParameterConstraintPositionImpl(typeArgument)
)
} else {
assert(typeArgument == TypeArgumentPlaceholder) {
@@ -192,7 +192,7 @@ internal object CreateFreshVariablesSubstitutor : ResolutionPart() {
fun TypeVariableFromCallableDescriptor.addSubtypeConstraint(
upperBound: KotlinType,
position: DeclaredUpperBoundConstraintPosition
position: DeclaredUpperBoundConstraintPositionImpl
) {
csBuilder.addSubtypeConstraint(defaultType, toFreshVariables.safeSubstitute(upperBound.unwrap()), position)
}
@@ -363,7 +363,7 @@ internal object CollectionTypeVariableUsagesInfo : ResolutionPart() {
val dependentTypeParameters = getBuilder().currentStorage().notFixedTypeVariables.asSequence()
.flatMap { (typeConstructor, constraints) ->
val upperBounds = constraints.constraints.filter {
it.position.from is DeclaredUpperBoundConstraintPosition && it.kind == ConstraintKind.UPPER
it.position.from is DeclaredUpperBoundConstraintPositionImpl && it.kind == ConstraintKind.UPPER
}
upperBounds.mapNotNull { constraint ->
@@ -403,7 +403,7 @@ internal object CollectionTypeVariableUsagesInfo : ResolutionPart() {
private fun NewConstraintSystem.getDependingOnTypeParameter(variable: TypeConstructor) =
getBuilder().currentStorage().notFixedTypeVariables[variable]?.constraints?.mapNotNull {
if (it.position.from is DeclaredUpperBoundConstraintPosition && it.kind == ConstraintKind.UPPER) {
if (it.position.from is DeclaredUpperBoundConstraintPositionImpl && it.kind == ConstraintKind.UPPER) {
it.type.typeConstructor(asConstraintSystemCompleterContext())
} else null
} ?: emptyList()
@@ -561,7 +561,7 @@ private fun KotlinResolutionCandidate.shouldRunConversionForConstants(expectedTy
val variableWithConstraints = csBuilder.currentStorage().notFixedTypeVariables[expectedType.constructor] ?: return false
return variableWithConstraints.constraints.any {
it.kind == ConstraintKind.EQUALITY &&
it.position.from is ExplicitTypeParameterConstraintPosition &&
it.position.from is ExplicitTypeParameterConstraintPositionImpl &&
UnsignedTypes.isUnsignedType(it.type as UnwrappedType)
}
@@ -728,4 +728,4 @@ internal object ErrorDescriptorResolutionPart : ResolutionPart() {
resolveKotlinArgument(it, null, ReceiverInfo.notReceiver)
}
}
}
}
@@ -21,9 +21,9 @@ import org.jetbrains.kotlin.descriptors.TypeParameterDescriptor
import org.jetbrains.kotlin.resolve.calls.inference.ConstraintSystemBuilder
import org.jetbrains.kotlin.resolve.calls.inference.addSubtypeConstraintIfCompatible
import org.jetbrains.kotlin.resolve.calls.inference.components.NewTypeSubstitutor
import org.jetbrains.kotlin.resolve.calls.inference.model.ArgumentConstraintPosition
import org.jetbrains.kotlin.resolve.calls.inference.model.ArgumentConstraintPositionImpl
import org.jetbrains.kotlin.resolve.calls.inference.model.ConstraintPosition
import org.jetbrains.kotlin.resolve.calls.inference.model.ReceiverConstraintPosition
import org.jetbrains.kotlin.resolve.calls.inference.model.ReceiverConstraintPositionImpl
import org.jetbrains.kotlin.resolve.calls.model.*
import org.jetbrains.kotlin.types.*
import org.jetbrains.kotlin.types.checker.captureFromExpression
@@ -93,7 +93,7 @@ private fun checkExpressionArgument(
return null
}
val position = if (isReceiver) ReceiverConstraintPosition(expressionArgument) else ArgumentConstraintPosition(expressionArgument)
val position = if (isReceiver) ReceiverConstraintPositionImpl(expressionArgument) else ArgumentConstraintPositionImpl(expressionArgument)
// Used only for arguments with @NotNull annotation
if (expectedType is NotNullTypeVariable && argumentType.isMarkedNullable) {
@@ -188,7 +188,7 @@ private fun checkSubCallArgument(
if (expectedType == null) return subCallResult
val expectedNullableType = expectedType.makeNullableAsSpecified(true)
val position = if (receiverInfo.isReceiver) ReceiverConstraintPosition(subCallArgument) else ArgumentConstraintPosition(subCallArgument)
val position = if (receiverInfo.isReceiver) ReceiverConstraintPositionImpl(subCallArgument) else ArgumentConstraintPositionImpl(subCallArgument)
// subArgument cannot has stable smartcast
// return type can contains fixed type variables
@@ -82,7 +82,7 @@ class ConstraintIncorporator(
getConstraintsForVariable(typeVariable).forEach {
if (it.kind != ConstraintKind.LOWER) {
val isFromDeclaredUpperBound =
it.position.from is DeclaredUpperBoundConstraintPosition && it.type.typeConstructor() !is TypeVariableTypeConstructor
it.position.from is DeclaredUpperBoundConstraintPosition<*> && it.type.typeConstructor() !is TypeVariableTypeConstructor
addNewIncorporatedConstraint(
constraint.type,
@@ -227,8 +227,8 @@ class ConstraintIncorporator(
val isUsefulForNullabilityConstraint =
isPotentialUsefulNullabilityConstraint(newConstraint, otherConstraint.type, otherConstraint.kind)
val isFromVariableFixation = baseConstraint.position.from is FixVariableConstraintPosition
|| otherConstraint.position.from is FixVariableConstraintPosition
val isFromVariableFixation = baseConstraint.position.from is FixVariableConstraintPosition<*>
|| otherConstraint.position.from is FixVariableConstraintPosition<*>
if (!otherConstraint.kind.isEqual() &&
!isUsefulForNullabilityConstraint &&
@@ -124,7 +124,7 @@ class ConstraintInjector(
return true // T <: T(?!)
}
if (constraint.position.from is DeclaredUpperBoundConstraintPosition &&
if (constraint.position.from is DeclaredUpperBoundConstraintPosition<*> &&
constraint.kind == UPPER && constraintType.isNullableAny()
) {
return true // T <: Any?
@@ -17,7 +17,6 @@ import org.jetbrains.kotlin.types.model.safeSubstitute
import org.jetbrains.kotlin.types.typeUtil.asTypeProjection
import org.jetbrains.kotlin.utils.addIfNotNull
import org.jetbrains.kotlin.utils.addToStdlib.safeAs
import kotlin.collections.LinkedHashSet
class KotlinConstraintSystemCompleter(
private val resultTypeResolver: ResultTypeResolver,
@@ -235,7 +234,7 @@ class KotlinConstraintSystemCompleter(
csBuilder.addSubtypeConstraint(
expectedType,
functionalType,
ArgumentConstraintPosition(atom.atom)
ArgumentConstraintPositionImpl(atom.atom)
)
return atom.transformToResolvedLambda(csBuilder, diagnosticsHolder, expectedType, returnVariable)
}
@@ -314,7 +313,7 @@ class KotlinConstraintSystemCompleter(
val resolvedAtom = findResolvedAtomBy(typeVariable, topLevelAtoms) ?: topLevelAtoms.firstOrNull()
if (resolvedAtom != null) {
c.addError(NotEnoughInformationForTypeParameter(typeVariable, resolvedAtom))
c.addError(NotEnoughInformationForTypeParameterImpl(typeVariable, resolvedAtom))
}
val resultErrorType = when {
@@ -6,13 +6,13 @@
package org.jetbrains.kotlin.resolve.calls.inference.components
import org.jetbrains.kotlin.builtins.*
import org.jetbrains.kotlin.descriptors.annotations.Annotations
import org.jetbrains.kotlin.resolve.calls.components.transformToResolvedLambda
import org.jetbrains.kotlin.resolve.calls.inference.model.*
import org.jetbrains.kotlin.resolve.calls.model.*
import org.jetbrains.kotlin.types.*
import org.jetbrains.kotlin.types.typeUtil.asTypeProjection
import org.jetbrains.kotlin.types.typeUtil.builtIns
import org.jetbrains.kotlin.descriptors.annotations.Annotations
import org.jetbrains.kotlin.utils.SmartSet
import org.jetbrains.kotlin.utils.addToStdlib.safeAs
@@ -205,13 +205,13 @@ class PostponedArgumentInputTypesResolver(
if (typeWithKind == null) continue
when (typeWithKind.direction) {
ConstraintKind.EQUALITY -> csBuilder.addEqualityConstraint(
parameterTypeVariable.defaultType, typeWithKind.type, ArgumentConstraintPosition(atom)
parameterTypeVariable.defaultType, typeWithKind.type, ArgumentConstraintPositionImpl(atom)
)
ConstraintKind.UPPER -> csBuilder.addSubtypeConstraint(
parameterTypeVariable.defaultType, typeWithKind.type, ArgumentConstraintPosition(atom)
parameterTypeVariable.defaultType, typeWithKind.type, ArgumentConstraintPositionImpl(atom)
)
ConstraintKind.LOWER -> csBuilder.addSubtypeConstraint(
typeWithKind.type, parameterTypeVariable.defaultType, ArgumentConstraintPosition(atom)
typeWithKind.type, parameterTypeVariable.defaultType, ArgumentConstraintPositionImpl(atom)
)
}
}
@@ -330,7 +330,7 @@ class PostponedArgumentInputTypesResolver(
getBuilder().addSubtypeConstraint(
newExpectedType,
expectedType,
ArgumentConstraintPosition(argument.atom)
ArgumentConstraintPositionImpl(argument.atom)
)
return newExpectedType
@@ -486,4 +486,4 @@ class PostponedArgumentInputTypesResolver(
private const val TYPE_VARIABLE_NAME_PREFIX_FOR_CR_PARAMETER_TYPE = "_QP"
private const val TYPE_VARIABLE_NAME_FOR_CR_RETURN_TYPE = "_Q"
}
}
}
@@ -139,7 +139,7 @@ class VariableFixationFinder(
private fun Context.isProperArgumentConstraint(c: Constraint) =
isProperType(c.type)
&& c.position.initialConstraint.position !is DeclaredUpperBoundConstraintPosition
&& c.position.initialConstraint.position !is DeclaredUpperBoundConstraintPosition<*>
&& !c.isNullabilityConstraint
private fun Context.isProperType(type: KotlinTypeMarker): Boolean =
@@ -162,4 +162,4 @@ inline fun TypeSystemInferenceExtensionContext.isProperTypeForFixation(
}
return true
}
}
@@ -16,69 +16,62 @@
package org.jetbrains.kotlin.resolve.calls.inference.model
import org.jetbrains.kotlin.descriptors.TypeParameterDescriptor
import org.jetbrains.kotlin.resolve.calls.model.*
import org.jetbrains.kotlin.resolve.calls.model.DiagnosticReporter
import org.jetbrains.kotlin.resolve.calls.model.KotlinCallDiagnostic
import org.jetbrains.kotlin.resolve.calls.tower.ResolutionCandidateApplicability
import org.jetbrains.kotlin.resolve.calls.tower.ResolutionCandidateApplicability.*
import org.jetbrains.kotlin.resolve.scopes.receivers.DetailedReceiver
import org.jetbrains.kotlin.types.KotlinType
import org.jetbrains.kotlin.types.model.KotlinTypeMarker
import org.jetbrains.kotlin.types.model.TypeVariableMarker
interface OnlyInputTypeConstraintPosition
sealed class ConstraintPosition
class ExplicitTypeParameterConstraintPosition(val typeArgument: SimpleTypeArgument) : ConstraintPosition(), OnlyInputTypeConstraintPosition {
override fun toString() = "TypeParameter $typeArgument"
abstract class ExplicitTypeParameterConstraintPosition<T>(val typeArgument: T) : ConstraintPosition(), OnlyInputTypeConstraintPosition {
override fun toString(): String = "TypeParameter $typeArgument"
}
class ExpectedTypeConstraintPosition(val topLevelCall: KotlinCall) : ConstraintPosition(), OnlyInputTypeConstraintPosition {
override fun toString() = "ExpectedType for call $topLevelCall"
abstract class ExpectedTypeConstraintPosition<T>(val topLevelCall: T) : ConstraintPosition(), OnlyInputTypeConstraintPosition {
override fun toString(): String = "ExpectedType for call $topLevelCall"
}
sealed class DeclaredUpperBoundConstraintPosition : ConstraintPosition()
class DeclaredUpperBoundConstraintPositionImpl(val typeParameterDescriptor: TypeParameterDescriptor) : DeclaredUpperBoundConstraintPosition() {
override fun toString() = "DeclaredUpperBound ${typeParameterDescriptor.name} from ${typeParameterDescriptor.containingDeclaration}"
abstract class DeclaredUpperBoundConstraintPosition<T>(val typeParameter: T) : ConstraintPosition() {
override fun toString(): String = "DeclaredUpperBound $typeParameter"
}
class FirDeclaredUpperBoundConstraintPosition : DeclaredUpperBoundConstraintPosition()
interface OnlyInputTypeConstraintPosition
class ArgumentConstraintPosition(val argument: KotlinCallArgument) : ConstraintPosition(), OnlyInputTypeConstraintPosition {
override fun toString() = "Argument $argument"
abstract class ArgumentConstraintPosition<T>(val argument: T) : ConstraintPosition(), OnlyInputTypeConstraintPosition {
override fun toString(): String = "Argument $argument"
}
class ReceiverConstraintPosition(val argument: KotlinCallArgument) : ConstraintPosition(), OnlyInputTypeConstraintPosition {
override fun toString() = "Receiver $argument"
abstract class ReceiverConstraintPosition<T>(val argument: T) : ConstraintPosition(), OnlyInputTypeConstraintPosition {
override fun toString(): String = "Receiver $argument"
}
class FixVariableConstraintPosition(val variable: TypeVariableMarker, val resolvedAtom: ResolvedAtom?) : ConstraintPosition() {
override fun toString() = "Fix variable $variable"
abstract class FixVariableConstraintPosition<T>(val variable: TypeVariableMarker, val resolvedAtom: T) : ConstraintPosition() {
override fun toString(): String = "Fix variable $variable"
}
class KnownTypeParameterConstraintPosition(val typeArgument: KotlinType) : ConstraintPosition() {
override fun toString() = "TypeArgument $typeArgument"
abstract class KnownTypeParameterConstraintPosition<T : KotlinTypeMarker>(val typeArgument: T) : ConstraintPosition() {
override fun toString(): String = "TypeArgument $typeArgument"
}
class LHSArgumentConstraintPosition(
val argument: CallableReferenceKotlinCallArgument,
val receiver: DetailedReceiver
abstract class LHSArgumentConstraintPosition<T, R>(
val argument: T,
val receiver: R
) : ConstraintPosition() {
override fun toString(): String {
return "LHS receiver $receiver"
}
}
class LambdaArgumentConstraintPosition(val lambda: ResolvedLambdaAtom) : ConstraintPosition() {
abstract class LambdaArgumentConstraintPosition<T>(val lambda: T) : ConstraintPosition() {
override fun toString(): String {
return "LambdaArgument $lambda"
}
}
class DelegatedPropertyConstraintPosition(val topLevelCall: KotlinCall) : ConstraintPosition() {
override fun toString() = "Constraint from call $topLevelCall for delegated property"
abstract class DelegatedPropertyConstraintPosition<T>(val topLevelCall: T) : ConstraintPosition() {
override fun toString(): String = "Constraint from call $topLevelCall for delegated property"
}
data class IncorporationConstraintPosition(
@@ -86,11 +79,10 @@ data class IncorporationConstraintPosition(
val initialConstraint: InitialConstraint,
var isFromDeclaredUpperBound: Boolean = false
) : ConstraintPosition() {
override fun toString() =
"Incorporate $initialConstraint from position $from"
override fun toString(): String = "Incorporate $initialConstraint from position $from"
}
class CoroutinePosition() : ConstraintPosition() {
object CoroutinePosition : ConstraintPosition() {
override fun toString(): String = "for coroutine call"
}
@@ -105,7 +97,7 @@ class NewConstraintError(
val lowerType: KotlinTypeMarker,
val upperType: KotlinTypeMarker,
val position: IncorporationConstraintPosition
) : ConstraintSystemCallDiagnostic(if (position.from is ReceiverConstraintPosition) INAPPLICABLE_WRONG_RECEIVER else INAPPLICABLE)
) : ConstraintSystemCallDiagnostic(if (position.from is ReceiverConstraintPosition<*>) INAPPLICABLE_WRONG_RECEIVER else INAPPLICABLE)
class CapturedTypeFromSubtyping(
val typeVariable: TypeVariableMarker,
@@ -113,9 +105,9 @@ class CapturedTypeFromSubtyping(
val position: ConstraintPosition
) : ConstraintSystemCallDiagnostic(INAPPLICABLE)
class NotEnoughInformationForTypeParameter(
abstract class NotEnoughInformationForTypeParameter<T>(
val typeVariable: TypeVariableMarker,
val resolvedAtom: ResolvedAtom
val resolvedAtom: T
) : ConstraintSystemCallDiagnostic(INAPPLICABLE)
class ConstrainingTypeIsError(
@@ -0,0 +1,49 @@
/*
* Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/
package org.jetbrains.kotlin.resolve.calls.inference.model
import org.jetbrains.kotlin.descriptors.TypeParameterDescriptor
import org.jetbrains.kotlin.resolve.calls.model.*
import org.jetbrains.kotlin.resolve.scopes.receivers.DetailedReceiver
import org.jetbrains.kotlin.types.KotlinType
import org.jetbrains.kotlin.types.model.TypeVariableMarker
class ExplicitTypeParameterConstraintPositionImpl(
typeArgument: SimpleTypeArgument
) : ExplicitTypeParameterConstraintPosition<SimpleTypeArgument>(typeArgument)
class ExpectedTypeConstraintPositionImpl(topLevelCall: KotlinCall) : ExpectedTypeConstraintPosition<KotlinCall>(topLevelCall)
class DeclaredUpperBoundConstraintPositionImpl(
typeParameter: TypeParameterDescriptor
) : DeclaredUpperBoundConstraintPosition<TypeParameterDescriptor>(typeParameter) {
override fun toString() = "DeclaredUpperBound ${typeParameter.name} from ${typeParameter.containingDeclaration}"
}
class ArgumentConstraintPositionImpl(argument: KotlinCallArgument) : ArgumentConstraintPosition<KotlinCallArgument>(argument)
class ReceiverConstraintPositionImpl(argument: KotlinCallArgument) : ReceiverConstraintPosition<KotlinCallArgument>(argument)
class FixVariableConstraintPositionImpl(
variable: TypeVariableMarker,
resolvedAtom: ResolvedAtom?
) : FixVariableConstraintPosition<ResolvedAtom?>(variable, resolvedAtom)
class KnownTypeParameterConstraintPositionImpl(typeArgument: KotlinType) : KnownTypeParameterConstraintPosition<KotlinType>(typeArgument)
class LHSArgumentConstraintPositionImpl(
argument: CallableReferenceKotlinCallArgument,
receiver: DetailedReceiver
) : LHSArgumentConstraintPosition<CallableReferenceKotlinCallArgument, DetailedReceiver>(argument, receiver)
class LambdaArgumentConstraintPositionImpl(lambda: ResolvedLambdaAtom) : LambdaArgumentConstraintPosition<ResolvedLambdaAtom>(lambda)
class DelegatedPropertyConstraintPositionImpl(topLevelCall: KotlinCall) : DelegatedPropertyConstraintPosition<KotlinCall>(topLevelCall)
class NotEnoughInformationForTypeParameterImpl(
typeVariable: TypeVariableMarker,
resolvedAtom: ResolvedAtom
) : NotEnoughInformationForTypeParameter<ResolvedAtom>(typeVariable, resolvedAtom)
@@ -115,7 +115,7 @@ class MutableVariableWithConstraints private constructor(
private fun newConstraintIsUseless(old: Constraint, new: Constraint): Boolean {
// Constraints from declared upper bound are quite special -- they aren't considered as a proper ones
// In other words, user-defined constraints have "higher" priority and here we're trying not to loose them
if (old.position.from is DeclaredUpperBoundConstraintPosition && new.position.from !is DeclaredUpperBoundConstraintPosition)
if (old.position.from is DeclaredUpperBoundConstraintPosition<*> && new.position.from !is DeclaredUpperBoundConstraintPosition<*>)
return false
return when (old.kind) {
@@ -302,7 +302,7 @@ class NewConstraintSystemImpl(
checkState(State.BUILDING, State.COMPLETION)
constraintInjector.addInitialEqualityConstraint(
this, variable.defaultType(), resultType, FixVariableConstraintPosition(variable, atom)
this, variable.defaultType(), resultType, FixVariableConstraintPositionImpl(variable, atom)
)
val freshTypeConstructor = variable.freshTypeConstructor()