From f31493f80f469100a1a81bb8b7f62b87acdad808 Mon Sep 17 00:00:00 2001 From: Stanislav Erokhin Date: Tue, 23 Aug 2016 18:31:10 +0300 Subject: [PATCH] Introduce SimpleConstraintSystem for OverloadChecker and OverloadingConflictResolver --- .../kotlin/resolve/OverloadChecker.kt | 10 +++++-- .../inference/ConstraintSystemBuilderImpl.kt | 18 +++++++++-- .../calls/results/FlatSignatureSpecificity.kt | 30 +++++++++---------- .../results/OverloadingConflictResolver.kt | 5 ++-- 4 files changed, 40 insertions(+), 23 deletions(-) diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/OverloadChecker.kt b/compiler/frontend/src/org/jetbrains/kotlin/resolve/OverloadChecker.kt index 760b9394b42..e25b17e04ce 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/OverloadChecker.kt +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/OverloadChecker.kt @@ -21,7 +21,11 @@ import org.jetbrains.kotlin.descriptors.* import org.jetbrains.kotlin.incremental.components.NoLookupLocation import org.jetbrains.kotlin.name.FqNameUnsafe import org.jetbrains.kotlin.name.Name -import org.jetbrains.kotlin.resolve.calls.results.* +import org.jetbrains.kotlin.resolve.calls.inference.ConstraintSystemBuilderImpl +import org.jetbrains.kotlin.resolve.calls.results.FlatSignature +import org.jetbrains.kotlin.resolve.calls.results.SpecificityComparisonCallbacks +import org.jetbrains.kotlin.resolve.calls.results.TypeSpecificityComparator +import org.jetbrains.kotlin.resolve.calls.results.isSignatureNotLessSpecific import org.jetbrains.kotlin.resolve.calls.tower.getTypeAliasConstructors import org.jetbrains.kotlin.resolve.descriptorUtil.hasLowPriorityInOverloadResolution import org.jetbrains.kotlin.resolve.descriptorUtil.varargParameterPosition @@ -63,8 +67,8 @@ class OverloadChecker(val specificityComparator: TypeSpecificityComparator) { val aSignature = FlatSignature.createFromCallableDescriptor(a) val bSignature = FlatSignature.createFromCallableDescriptor(b) - val aIsNotLessSpecificThanB = isSignatureNotLessSpecific(aSignature, bSignature, OverloadabilitySpecificityCallbacks, specificityComparator) - val bIsNotLessSpecificThanA = isSignatureNotLessSpecific(bSignature, aSignature, OverloadabilitySpecificityCallbacks, specificityComparator) + val aIsNotLessSpecificThanB = ConstraintSystemBuilderImpl.forSpecificity().isSignatureNotLessSpecific (aSignature, bSignature, OverloadabilitySpecificityCallbacks, specificityComparator) + val bIsNotLessSpecificThanA = ConstraintSystemBuilderImpl.forSpecificity().isSignatureNotLessSpecific(bSignature, aSignature, OverloadabilitySpecificityCallbacks, specificityComparator) return !(aIsNotLessSpecificThanB && bIsNotLessSpecificThanA) } diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/inference/ConstraintSystemBuilderImpl.kt b/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/inference/ConstraintSystemBuilderImpl.kt index 48d3910153e..27e9cdd04a9 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/inference/ConstraintSystemBuilderImpl.kt +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/inference/ConstraintSystemBuilderImpl.kt @@ -26,6 +26,7 @@ import org.jetbrains.kotlin.resolve.calls.inference.TypeBounds.BoundKind.* 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.TYPE_BOUND_POSITION +import org.jetbrains.kotlin.resolve.calls.results.SimpleConstraintSystem import org.jetbrains.kotlin.resolve.calls.util.createFunctionType import org.jetbrains.kotlin.resolve.descriptorUtil.hasExactAnnotation import org.jetbrains.kotlin.resolve.descriptorUtil.hasNoInferAnnotation @@ -38,7 +39,7 @@ import org.jetbrains.kotlin.types.typeUtil.defaultProjections import org.jetbrains.kotlin.types.typeUtil.isDefaultBound import java.util.* -class ConstraintSystemBuilderImpl(private val mode: Mode = ConstraintSystemBuilderImpl.Mode.INFERENCE) : ConstraintSystem.Builder { +open class ConstraintSystemBuilderImpl(private val mode: Mode = ConstraintSystemBuilderImpl.Mode.INFERENCE) : ConstraintSystem.Builder { enum class Mode { INFERENCE, SPECIFICITY @@ -409,7 +410,20 @@ class ConstraintSystemBuilderImpl(private val mode: Mode = ConstraintSystemBuild } companion object { - fun forSpecificity() = ConstraintSystemBuilderImpl(Mode.SPECIFICITY) + fun forSpecificity(): SimpleConstraintSystem = object : ConstraintSystemBuilderImpl(Mode.SPECIFICITY), SimpleConstraintSystem { + var counter = 0 + + override fun registerTypeVariables(typeParameters: Collection) = + registerTypeVariables(CallHandle.NONE, typeParameters) + + override fun addSubtypeConstraint(subType: UnwrappedType, superType: UnwrappedType) = + addSubtypeConstraint(subType, superType, ConstraintPositionKind.VALUE_PARAMETER_POSITION.position(counter++)) + + override fun hasContradiction(): Boolean { + fixVariables() + return build().status.hasContradiction() + } + } } } diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/results/FlatSignatureSpecificity.kt b/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/results/FlatSignatureSpecificity.kt index d983477120b..43a1d369560 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/results/FlatSignatureSpecificity.kt +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/results/FlatSignatureSpecificity.kt @@ -17,21 +17,17 @@ package org.jetbrains.kotlin.resolve.calls.results import org.jetbrains.kotlin.builtins.KotlinBuiltIns +import org.jetbrains.kotlin.descriptors.TypeParameterDescriptor import org.jetbrains.kotlin.psi.ValueArgument import org.jetbrains.kotlin.resolve.DescriptorToSourceUtils -import org.jetbrains.kotlin.resolve.calls.inference.CallHandle -import org.jetbrains.kotlin.resolve.calls.inference.ConstraintSystem import org.jetbrains.kotlin.resolve.calls.inference.ConstraintSystemBuilderImpl -import org.jetbrains.kotlin.resolve.calls.inference.constraintPosition.valueParameterPosition import org.jetbrains.kotlin.resolve.calls.model.DefaultValueArgument import org.jetbrains.kotlin.resolve.calls.model.MutableResolvedCall import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall import org.jetbrains.kotlin.resolve.calls.model.VariableAsFunctionResolvedCallImpl import org.jetbrains.kotlin.resolve.calls.results.FlatSignature.Companion.argumentValueType import org.jetbrains.kotlin.resolve.calls.results.FlatSignature.Companion.extensionReceiverTypeOrEmpty -import org.jetbrains.kotlin.types.KotlinType -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 java.util.* @@ -47,21 +43,24 @@ interface TypeSpecificityComparator { } } -fun isSignatureNotLessSpecific( +interface SimpleConstraintSystem { + fun registerTypeVariables(typeParameters: Collection): TypeSubstitutor + fun addSubtypeConstraint(subType: UnwrappedType, superType: UnwrappedType) + fun hasContradiction(): Boolean +} + +fun SimpleConstraintSystem.isSignatureNotLessSpecific( specific: FlatSignature, general: FlatSignature, callbacks: SpecificityComparisonCallbacks, - specificityComparator: TypeSpecificityComparator, - callHandle: CallHandle = CallHandle.NONE + specificityComparator: TypeSpecificityComparator ): Boolean { if (specific.hasExtensionReceiver != general.hasExtensionReceiver) return false if (specific.valueParameterTypes.size != general.valueParameterTypes.size) return false val typeParameters = general.typeParameters - val constraintSystemBuilder: ConstraintSystem.Builder = ConstraintSystemBuilderImpl.forSpecificity() - val typeSubstitutor = constraintSystemBuilder.registerTypeVariables(callHandle, typeParameters) + val typeSubstitutor = registerTypeVariables(typeParameters) - var numConstraints = 0 for ((specificType, generalType) in specific.valueParameterTypes.zip(general.valueParameterTypes)) { if (specificType == null || generalType == null) continue @@ -78,13 +77,11 @@ fun isSignatureNotLessSpecific( } else { val substitutedGeneralType = typeSubstitutor.safeSubstitute(generalType, Variance.INVARIANT) - constraintSystemBuilder.addSubtypeConstraint(specificType, substitutedGeneralType, valueParameterPosition(numConstraints++)) + addSubtypeConstraint(specificType.unwrap(), substitutedGeneralType.unwrap()) } } - constraintSystemBuilder.fixVariables() - val constraintSystem = constraintSystemBuilder.build() - return !constraintSystem.status.hasContradiction() + return !hasContradiction() } @@ -123,6 +120,7 @@ fun createOverloadingConflictResolver( builtIns, specificityComparator, MutableResolvedCall<*>::getResultingDescriptor, + ConstraintSystemBuilderImpl.Companion::forSpecificity, MutableResolvedCall<*>::createFlatSignature, { (it as? VariableAsFunctionResolvedCallImpl)?.variableCall }, { DescriptorToSourceUtils.descriptorToDeclaration(it) != null} diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/results/OverloadingConflictResolver.kt b/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/results/OverloadingConflictResolver.kt index f7f01ebb36f..bf842d0fa34 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/results/OverloadingConflictResolver.kt +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/results/OverloadingConflictResolver.kt @@ -34,6 +34,7 @@ class OverloadingConflictResolver( private val builtIns: KotlinBuiltIns, private val specificityComparator: TypeSpecificityComparator, private val getResultingDescriptor: (C) -> CallableDescriptor, + private val createEmptyConstraintSystem: () -> SimpleConstraintSystem, private val createFlatSignature: (C) -> FlatSignature, private val getVariableCandidates: (C) -> C?, // vor variable WithInvoke private val isFromSources: (CallableDescriptor) -> Boolean @@ -235,7 +236,7 @@ class OverloadingConflictResolver( if (isGeneric1 && isGeneric2) return false } - return isSignatureNotLessSpecific(call1, call2, SpecificityComparisonWithNumerics, specificityComparator) + return createEmptyConstraintSystem().isSignatureNotLessSpecific(call1, call2, SpecificityComparisonWithNumerics, specificityComparator) } private val SpecificityComparisonWithNumerics = object : SpecificityComparisonCallbacks { @@ -321,7 +322,7 @@ class OverloadingConflictResolver( val fSignature = FlatSignature.createFromCallableDescriptor(f) val gSignature = FlatSignature.createFromCallableDescriptor(g) - return isSignatureNotLessSpecific(fSignature, gSignature, SpecificityComparisonWithNumerics, specificityComparator) + return createEmptyConstraintSystem().isSignatureNotLessSpecific(fSignature, gSignature, SpecificityComparisonWithNumerics, specificityComparator) } private fun isNotLessSpecificCallableReference(f: CallableDescriptor, g: CallableDescriptor): Boolean =