Extract FE 1.0 related parts from NewConstraintSystem

This commit is contained in:
Dmitriy Novozhilov
2020-08-25 17:00:29 +03:00
parent be1033a4a7
commit e5e3d7cab1
7 changed files with 119 additions and 107 deletions
@@ -16,19 +16,13 @@
package org.jetbrains.kotlin.resolve.calls.inference
import org.jetbrains.kotlin.resolve.calls.components.PostponedArgumentsAnalyzer
import org.jetbrains.kotlin.resolve.calls.inference.model.ConstraintKind
import org.jetbrains.kotlin.resolve.calls.inference.model.ConstraintPosition
import org.jetbrains.kotlin.resolve.calls.inference.model.ConstraintStorage
import org.jetbrains.kotlin.resolve.calls.model.CallableReferenceKotlinCallArgument
import org.jetbrains.kotlin.resolve.calls.model.KotlinCallArgument
import org.jetbrains.kotlin.resolve.calls.model.LHSResult
import org.jetbrains.kotlin.resolve.calls.model.SubKotlinCallArgument
import org.jetbrains.kotlin.types.model.KotlinTypeMarker
import org.jetbrains.kotlin.types.model.TypeConstructorMarker
import org.jetbrains.kotlin.types.model.TypeSubstitutorMarker
import org.jetbrains.kotlin.types.model.TypeVariableMarker
import org.jetbrains.kotlin.utils.addToStdlib.safeAs
interface ConstraintSystemOperation {
val hasContradiction: Boolean
@@ -50,7 +44,6 @@ interface ConstraintSystemOperation {
}
interface ConstraintSystemBuilder : ConstraintSystemOperation {
//val builtIns: KotlinBuiltIns
// if runOperations return true, then this operation will be applied, and function return true
fun runTransaction(runOperations: ConstraintSystemOperation.() -> Boolean): Boolean
@@ -63,45 +56,26 @@ fun ConstraintSystemBuilder.addSubtypeConstraintIfCompatible(
lowerType: KotlinTypeMarker,
upperType: KotlinTypeMarker,
position: ConstraintPosition
): Boolean =
addConstraintIfCompatible(lowerType, upperType, position, ConstraintKind.LOWER)
): Boolean = addConstraintIfCompatible(lowerType, upperType, position, ConstraintKind.LOWER)
fun ConstraintSystemBuilder.addEqualityConstraintIfCompatible(
lowerType: KotlinTypeMarker,
upperType: KotlinTypeMarker,
position: ConstraintPosition
): Boolean =
addConstraintIfCompatible(lowerType, upperType, position, ConstraintKind.EQUALITY)
): Boolean = addConstraintIfCompatible(lowerType, upperType, position, ConstraintKind.EQUALITY)
private fun ConstraintSystemBuilder.addConstraintIfCompatible(
lowerType: KotlinTypeMarker,
upperType: KotlinTypeMarker,
position: ConstraintPosition,
kind: ConstraintKind
) =
runTransaction {
if (!hasContradiction) {
when (kind) {
ConstraintKind.LOWER -> addSubtypeConstraint(lowerType, upperType, position)
ConstraintKind.UPPER -> addSubtypeConstraint(upperType, lowerType, position)
ConstraintKind.EQUALITY -> addEqualityConstraint(lowerType, upperType, position)
}
): Boolean = runTransaction {
if (!hasContradiction) {
when (kind) {
ConstraintKind.LOWER -> addSubtypeConstraint(lowerType, upperType, position)
ConstraintKind.UPPER -> addSubtypeConstraint(upperType, lowerType, position)
ConstraintKind.EQUALITY -> addEqualityConstraint(lowerType, upperType, position)
}
!hasContradiction
}
fun PostponedArgumentsAnalyzer.Context.addSubsystemFromArgument(argument: KotlinCallArgument?): Boolean {
return when (argument) {
is SubKotlinCallArgument -> {
addOtherSystem(argument.callResult.constraintSystem)
true
}
is CallableReferenceKotlinCallArgument -> {
addSubsystemFromArgument(argument.lhsResult.safeAs<LHSResult.Expression>()?.lshCallArgument)
}
else -> false
}
!hasContradiction
}
@@ -0,0 +1,77 @@
/*
* 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
import org.jetbrains.kotlin.descriptors.CallableDescriptor
import org.jetbrains.kotlin.resolve.calls.components.PostponedArgumentsAnalyzer
import org.jetbrains.kotlin.resolve.calls.inference.components.NewTypeSubstitutor
import org.jetbrains.kotlin.resolve.calls.inference.model.ConstraintStorage
import org.jetbrains.kotlin.resolve.calls.model.CallableReferenceKotlinCallArgument
import org.jetbrains.kotlin.resolve.calls.model.KotlinCallArgument
import org.jetbrains.kotlin.resolve.calls.model.LHSResult
import org.jetbrains.kotlin.resolve.calls.model.SubKotlinCallArgument
import org.jetbrains.kotlin.resolve.descriptorUtil.builtIns
import org.jetbrains.kotlin.types.*
import org.jetbrains.kotlin.types.model.TypeSystemInferenceExtensionContext
import org.jetbrains.kotlin.utils.addToStdlib.safeAs
fun ConstraintStorage.buildResultingSubstitutor(
context: TypeSystemInferenceExtensionContext,
transformTypeVariablesToErrorTypes: Boolean = true
): NewTypeSubstitutor {
return buildAbstractResultingSubstitutor(context, transformTypeVariablesToErrorTypes) as NewTypeSubstitutor
}
val CallableDescriptor.returnTypeOrNothing: UnwrappedType
get() {
returnType?.let { return it.unwrap() }
return builtIns.nothingType
}
fun TypeSubstitutor.substitute(type: UnwrappedType): UnwrappedType = safeSubstitute(type, Variance.INVARIANT).unwrap()
fun CallableDescriptor.substitute(substitutor: NewTypeSubstitutor): CallableDescriptor {
val wrappedSubstitution = object : TypeSubstitution() {
override fun get(key: KotlinType): TypeProjection? = null
override fun prepareTopLevelType(topLevelType: KotlinType, position: Variance) = substitutor.safeSubstitute(topLevelType.unwrap())
}
return substitute(TypeSubstitutor.create(wrappedSubstitution))
}
fun CallableDescriptor.substituteAndApproximateTypes(
substitutor: NewTypeSubstitutor,
typeApproximator: TypeApproximator?
): CallableDescriptor {
val wrappedSubstitution = object : TypeSubstitution() {
override fun get(key: KotlinType): TypeProjection? = null
override fun prepareTopLevelType(topLevelType: KotlinType, position: Variance) =
substitutor.safeSubstitute(topLevelType.unwrap()).let { substitutedType ->
typeApproximator?.approximateToSuperType(
substitutedType,
TypeApproximatorConfiguration.FinalApproximationAfterResolutionAndInference
) ?: substitutedType
}
}
return substitute(TypeSubstitutor.create(wrappedSubstitution)) ?: this
}
fun PostponedArgumentsAnalyzer.Context.addSubsystemFromArgument(argument: KotlinCallArgument?): Boolean {
return when (argument) {
is SubKotlinCallArgument -> {
addOtherSystem(argument.callResult.constraintSystem)
true
}
is CallableReferenceKotlinCallArgument -> {
addSubsystemFromArgument(argument.lhsResult.safeAs<LHSResult.Expression>()?.lshCallArgument)
}
else -> false
}
}
@@ -16,11 +16,7 @@
package org.jetbrains.kotlin.resolve.calls.inference
import org.jetbrains.kotlin.descriptors.CallableDescriptor
import org.jetbrains.kotlin.resolve.calls.inference.components.NewTypeSubstitutor
import org.jetbrains.kotlin.resolve.calls.inference.model.ConstraintStorage
import org.jetbrains.kotlin.resolve.descriptorUtil.builtIns
import org.jetbrains.kotlin.types.*
import org.jetbrains.kotlin.types.model.*
fun ConstraintStorage.buildCurrentSubstitutor(
@@ -30,71 +26,34 @@ fun ConstraintStorage.buildCurrentSubstitutor(
return context.typeSubstitutorByTypeConstructor(fixedTypeVariables.entries.associate { it.key to it.value } + additionalBindings)
}
fun ConstraintStorage.buildAbstractResultingSubstitutor(context: TypeSystemInferenceExtensionContext, transformTypeVariablesToErrorTypes: Boolean = true): TypeSubstitutorMarker =
with(context) {
if (allTypeVariables.isEmpty()) return createEmptySubstitutor()
fun ConstraintStorage.buildAbstractResultingSubstitutor(
context: TypeSystemInferenceExtensionContext,
transformTypeVariablesToErrorTypes: Boolean = true
): TypeSubstitutorMarker = with(context) {
if (allTypeVariables.isEmpty()) return createEmptySubstitutor()
val currentSubstitutorMap = fixedTypeVariables.entries.associate {
it.key to it.value
}
val uninferredSubstitutorMap = if (transformTypeVariablesToErrorTypes) {
notFixedTypeVariables.entries.associate { (freshTypeConstructor, typeVariable) ->
freshTypeConstructor to context.createErrorTypeWithCustomConstructor(
"Uninferred type",
(typeVariable.typeVariable).freshTypeConstructor()
)
}
} else {
notFixedTypeVariables.entries.associate { (freshTypeConstructor, typeVariable) ->
freshTypeConstructor to typeVariable.typeVariable.defaultType(this)
}
}
return context.typeSubstitutorByTypeConstructor(currentSubstitutorMap + uninferredSubstitutorMap)
val currentSubstitutorMap = fixedTypeVariables.entries.associate {
it.key to it.value
}
val uninferredSubstitutorMap = if (transformTypeVariablesToErrorTypes) {
notFixedTypeVariables.entries.associate { (freshTypeConstructor, typeVariable) ->
freshTypeConstructor to context.createErrorTypeWithCustomConstructor(
"Uninferred type",
(typeVariable.typeVariable).freshTypeConstructor()
)
}
} else {
notFixedTypeVariables.entries.associate { (freshTypeConstructor, typeVariable) ->
freshTypeConstructor to typeVariable.typeVariable.defaultType(this)
}
}
return context.typeSubstitutorByTypeConstructor(currentSubstitutorMap + uninferredSubstitutorMap)
}
fun ConstraintStorage.buildNotFixedVariablesToNonSubtypableTypesSubstitutor(context: TypeSystemInferenceExtensionContext) =
context.typeSubstitutorByTypeConstructor(
fun ConstraintStorage.buildNotFixedVariablesToNonSubtypableTypesSubstitutor(
context: TypeSystemInferenceExtensionContext
): TypeSubstitutorMarker {
return context.typeSubstitutorByTypeConstructor(
notFixedTypeVariables.mapValues { context.createStubType(it.value.typeVariable) }
)
fun ConstraintStorage.buildResultingSubstitutor(context: TypeSystemInferenceExtensionContext, transformTypeVariablesToErrorTypes: Boolean = true): NewTypeSubstitutor {
return buildAbstractResultingSubstitutor(context, transformTypeVariablesToErrorTypes) as NewTypeSubstitutor
}
val CallableDescriptor.returnTypeOrNothing: UnwrappedType
get() {
returnType?.let { return it.unwrap() }
return builtIns.nothingType
}
fun TypeSubstitutor.substitute(type: UnwrappedType): UnwrappedType = safeSubstitute(type, Variance.INVARIANT).unwrap()
fun CallableDescriptor.substitute(substitutor: NewTypeSubstitutor): CallableDescriptor {
val wrappedSubstitution = object : TypeSubstitution() {
override fun get(key: KotlinType): TypeProjection? = null
override fun prepareTopLevelType(topLevelType: KotlinType, position: Variance) = substitutor.safeSubstitute(topLevelType.unwrap())
}
return substitute(TypeSubstitutor.create(wrappedSubstitution))
}
fun CallableDescriptor.substituteAndApproximateTypes(
substitutor: NewTypeSubstitutor,
typeApproximator: TypeApproximator?
): CallableDescriptor {
val wrappedSubstitution = object : TypeSubstitution() {
override fun get(key: KotlinType): TypeProjection? = null
override fun prepareTopLevelType(topLevelType: KotlinType, position: Variance) =
substitutor.safeSubstitute(topLevelType.unwrap()).let { substitutedType ->
typeApproximator?.approximateToSuperType(
substitutedType,
TypeApproximatorConfiguration.FinalApproximationAfterResolutionAndInference
) ?: substitutedType
}
}
return substitute(TypeSubstitutor.create(wrappedSubstitution)) ?: this
}
internal fun <E> MutableList<E>.trimToSize(newSize: Int) = subList(newSize, size).clear()
@@ -16,8 +16,6 @@
package org.jetbrains.kotlin.resolve.calls.inference
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
import org.jetbrains.kotlin.resolve.calls.components.KotlinCallCompleter
import org.jetbrains.kotlin.resolve.calls.components.PostponedArgumentsAnalyzer
import org.jetbrains.kotlin.resolve.calls.inference.components.KotlinConstraintSystemCompleter
import org.jetbrains.kotlin.resolve.calls.inference.components.PostponedArgumentInputTypesResolver
@@ -25,7 +23,6 @@ import org.jetbrains.kotlin.resolve.calls.inference.model.ConstraintStorage
import org.jetbrains.kotlin.resolve.calls.model.KotlinCallDiagnostic
interface NewConstraintSystem {
// val builtIns: KotlinBuiltIns
val hasContradiction: Boolean
val diagnostics: List<KotlinCallDiagnostic>
@@ -37,4 +34,4 @@ interface NewConstraintSystem {
fun asConstraintSystemCompleterContext(): KotlinConstraintSystemCompleter.Context
fun asPostponedArgumentsAnalyzerContext(): PostponedArgumentsAnalyzer.Context
fun asPostponedArgumentInputTypesResolverContext(): PostponedArgumentInputTypesResolver.Context
}
}
@@ -5,7 +5,6 @@
package org.jetbrains.kotlin.resolve.calls.inference.model
import org.jetbrains.kotlin.resolve.calls.inference.trimToSize
import org.jetbrains.kotlin.resolve.calls.model.KotlinCallDiagnostic
import org.jetbrains.kotlin.resolve.calls.tower.isSuccess
import org.jetbrains.kotlin.types.*
@@ -14,6 +13,7 @@ import org.jetbrains.kotlin.types.model.TypeConstructorMarker
import org.jetbrains.kotlin.types.model.TypeVariableMarker
import org.jetbrains.kotlin.types.typeUtil.unCapture
import org.jetbrains.kotlin.utils.SmartList
import org.jetbrains.kotlin.utils.addToStdlib.trimToSize
class MutableVariableWithConstraints private constructor(
@@ -20,6 +20,7 @@ import org.jetbrains.kotlin.types.model.*
import org.jetbrains.kotlin.utils.SmartList
import org.jetbrains.kotlin.utils.SmartSet
import org.jetbrains.kotlin.utils.addToStdlib.safeAs
import org.jetbrains.kotlin.utils.addToStdlib.trimToSize
import kotlin.math.max
class NewConstraintSystemImpl(
@@ -172,4 +172,8 @@ inline fun <T, R> Collection<T>.foldMap(transform: (T) -> R, operation: (R, R) -
result = operation(result, transform(iterator.next()))
}
return result
}
}
fun <E> MutableList<E>.trimToSize(newSize: Int) {
subList(newSize, size).clear()
}