[NI] Fix find maximally specific for NI.

This commit is contained in:
Stanislav Erokhin
2017-04-06 14:04:19 +03:00
parent d67b51e91a
commit 78f8d29a4c
3 changed files with 27 additions and 10 deletions
@@ -38,8 +38,9 @@ class NewOverloadingConflictResolver(
builtIns,
specificityComparator,
{
(it as? VariableAsFunctionKotlinResolutionCandidate)?.invokeCandidate?.descriptorWithFreshTypes ?:
(it as SimpleKotlinResolutionCandidate).descriptorWithFreshTypes
// todo investigate
(it as? VariableAsFunctionKotlinResolutionCandidate)?.invokeCandidate?.candidateDescriptor ?:
(it as SimpleKotlinResolutionCandidate).candidateDescriptor
},
{ SimpleConstraintSystemImpl(constraintInjector, typeResolver) },
Companion::createFlatSignature,
@@ -72,7 +73,6 @@ class NewOverloadingConflictResolver(
return FlatSignature.create(candidate,
originalDescriptor,
numDefaults,
listOfNotNull(originalDescriptor.extensionReceiverParameter?.type) +
simpleCandidate.kotlinCall.argumentsInParenthesis.map { valueArgumentToParameterType[it] } +
listOfNotNull(simpleCandidate.kotlinCall.externalArgument?.let { valueArgumentToParameterType[it] })
)
@@ -18,15 +18,12 @@ package org.jetbrains.kotlin.resolve.calls.inference.components
import org.jetbrains.kotlin.descriptors.TypeParameterDescriptor
import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.resolve.calls.model.KotlinCallKind
import org.jetbrains.kotlin.resolve.calls.inference.ConstraintSystemBuilder
import org.jetbrains.kotlin.resolve.calls.inference.model.NewConstraintSystemImpl
import org.jetbrains.kotlin.resolve.calls.inference.model.SimpleConstraintSystemConstraintPosition
import org.jetbrains.kotlin.resolve.calls.inference.model.TypeVariableFromCallableDescriptor
import org.jetbrains.kotlin.resolve.calls.model.KotlinCall
import org.jetbrains.kotlin.resolve.calls.model.KotlinCallArgument
import org.jetbrains.kotlin.resolve.calls.model.ReceiverKotlinCallArgument
import org.jetbrains.kotlin.resolve.calls.model.TypeArgument
import org.jetbrains.kotlin.resolve.calls.inference.substitute
import org.jetbrains.kotlin.resolve.calls.model.*
import org.jetbrains.kotlin.resolve.calls.results.SimpleConstraintSystem
import org.jetbrains.kotlin.types.TypeConstructorSubstitution
import org.jetbrains.kotlin.types.TypeSubstitutor
@@ -45,7 +42,13 @@ class SimpleConstraintSystemImpl(constraintInjector: ConstraintInjector, resultT
it.defaultType.constructor to variable.defaultType.asTypeProjection()
}
return TypeConstructorSubstitution.createByConstructorsMap(substitutionMap).buildSubstitutor()
val substitutor = TypeConstructorSubstitution.createByConstructorsMap(substitutionMap).buildSubstitutor()
for (typeParameter in typeParameters) {
for (upperBound in typeParameter.upperBounds) {
addSubtypeConstraint(substitutor.substitute(typeParameter.defaultType), substitutor.substitute(upperBound.unwrap()))
}
}
return substitutor
}
override fun addSubtypeConstraint(subType: UnwrappedType, superType: UnwrappedType) {
@@ -53,6 +56,7 @@ class SimpleConstraintSystemImpl(constraintInjector: ConstraintInjector, resultT
}
override fun hasContradiction() = csBuilder.hasContradiction
override val captureFromArgument get() = true
private object ThrowableKotlinCall : KotlinCall {
override val callKind: KotlinCallKind get() = throw UnsupportedOperationException()
@@ -24,6 +24,7 @@ import org.jetbrains.kotlin.descriptors.synthetic.SyntheticMemberDescriptor
import org.jetbrains.kotlin.resolve.descriptorUtil.hasDefaultValue
import org.jetbrains.kotlin.types.*
import org.jetbrains.kotlin.types.checker.KotlinTypeChecker
import org.jetbrains.kotlin.types.checker.captureFromExpression
interface SpecificityComparisonCallbacks {
fun isNonSubtypeNotLessSpecific(specific: KotlinType, general: KotlinType): Boolean
@@ -95,6 +96,9 @@ interface SimpleConstraintSystem {
fun registerTypeVariables(typeParameters: Collection<TypeParameterDescriptor>): TypeSubstitutor
fun addSubtypeConstraint(subType: UnwrappedType, superType: UnwrappedType)
fun hasContradiction(): Boolean
// todo hack for migration
val captureFromArgument get() = false
}
fun <T> SimpleConstraintSystem.isSignatureNotLessSpecific(
@@ -125,7 +129,16 @@ fun <T> SimpleConstraintSystem.isSignatureNotLessSpecific(
}
else {
val substitutedGeneralType = typeSubstitutor.safeSubstitute(generalType, Variance.INVARIANT)
addSubtypeConstraint(specificType.unwrap(), substitutedGeneralType.unwrap())
/**
* Example:
* fun <X> Array<out X>.sort(): Unit {}
* fun <Y: Comparable<Y>> Array<out Y>.sort(): Unit {}
* Here, when we try solve this CS(Y is variables) then Array<out X> <: Array<out Y> and this system impossible to solve,
* so we capture types from receiver and value parameters.
*/
val specificCapturedType = specificType.unwrap().let { if (captureFromArgument) captureFromExpression(it) ?: it else it }
addSubtypeConstraint(specificCapturedType, substitutedGeneralType.unwrap())
}
}