[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, builtIns,
specificityComparator, specificityComparator,
{ {
(it as? VariableAsFunctionKotlinResolutionCandidate)?.invokeCandidate?.descriptorWithFreshTypes ?: // todo investigate
(it as SimpleKotlinResolutionCandidate).descriptorWithFreshTypes (it as? VariableAsFunctionKotlinResolutionCandidate)?.invokeCandidate?.candidateDescriptor ?:
(it as SimpleKotlinResolutionCandidate).candidateDescriptor
}, },
{ SimpleConstraintSystemImpl(constraintInjector, typeResolver) }, { SimpleConstraintSystemImpl(constraintInjector, typeResolver) },
Companion::createFlatSignature, Companion::createFlatSignature,
@@ -72,7 +73,6 @@ class NewOverloadingConflictResolver(
return FlatSignature.create(candidate, return FlatSignature.create(candidate,
originalDescriptor, originalDescriptor,
numDefaults, numDefaults,
listOfNotNull(originalDescriptor.extensionReceiverParameter?.type) +
simpleCandidate.kotlinCall.argumentsInParenthesis.map { valueArgumentToParameterType[it] } + simpleCandidate.kotlinCall.argumentsInParenthesis.map { valueArgumentToParameterType[it] } +
listOfNotNull(simpleCandidate.kotlinCall.externalArgument?.let { 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.descriptors.TypeParameterDescriptor
import org.jetbrains.kotlin.name.Name 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.ConstraintSystemBuilder
import org.jetbrains.kotlin.resolve.calls.inference.model.NewConstraintSystemImpl 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.SimpleConstraintSystemConstraintPosition
import org.jetbrains.kotlin.resolve.calls.inference.model.TypeVariableFromCallableDescriptor import org.jetbrains.kotlin.resolve.calls.inference.model.TypeVariableFromCallableDescriptor
import org.jetbrains.kotlin.resolve.calls.model.KotlinCall import org.jetbrains.kotlin.resolve.calls.inference.substitute
import org.jetbrains.kotlin.resolve.calls.model.KotlinCallArgument import org.jetbrains.kotlin.resolve.calls.model.*
import org.jetbrains.kotlin.resolve.calls.model.ReceiverKotlinCallArgument
import org.jetbrains.kotlin.resolve.calls.model.TypeArgument
import org.jetbrains.kotlin.resolve.calls.results.SimpleConstraintSystem import org.jetbrains.kotlin.resolve.calls.results.SimpleConstraintSystem
import org.jetbrains.kotlin.types.TypeConstructorSubstitution import org.jetbrains.kotlin.types.TypeConstructorSubstitution
import org.jetbrains.kotlin.types.TypeSubstitutor import org.jetbrains.kotlin.types.TypeSubstitutor
@@ -45,7 +42,13 @@ class SimpleConstraintSystemImpl(constraintInjector: ConstraintInjector, resultT
it.defaultType.constructor to variable.defaultType.asTypeProjection() 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) { override fun addSubtypeConstraint(subType: UnwrappedType, superType: UnwrappedType) {
@@ -53,6 +56,7 @@ class SimpleConstraintSystemImpl(constraintInjector: ConstraintInjector, resultT
} }
override fun hasContradiction() = csBuilder.hasContradiction override fun hasContradiction() = csBuilder.hasContradiction
override val captureFromArgument get() = true
private object ThrowableKotlinCall : KotlinCall { private object ThrowableKotlinCall : KotlinCall {
override val callKind: KotlinCallKind get() = throw UnsupportedOperationException() 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.resolve.descriptorUtil.hasDefaultValue
import org.jetbrains.kotlin.types.* import org.jetbrains.kotlin.types.*
import org.jetbrains.kotlin.types.checker.KotlinTypeChecker import org.jetbrains.kotlin.types.checker.KotlinTypeChecker
import org.jetbrains.kotlin.types.checker.captureFromExpression
interface SpecificityComparisonCallbacks { interface SpecificityComparisonCallbacks {
fun isNonSubtypeNotLessSpecific(specific: KotlinType, general: KotlinType): Boolean fun isNonSubtypeNotLessSpecific(specific: KotlinType, general: KotlinType): Boolean
@@ -95,6 +96,9 @@ interface SimpleConstraintSystem {
fun registerTypeVariables(typeParameters: Collection<TypeParameterDescriptor>): TypeSubstitutor fun registerTypeVariables(typeParameters: Collection<TypeParameterDescriptor>): TypeSubstitutor
fun addSubtypeConstraint(subType: UnwrappedType, superType: UnwrappedType) fun addSubtypeConstraint(subType: UnwrappedType, superType: UnwrappedType)
fun hasContradiction(): Boolean fun hasContradiction(): Boolean
// todo hack for migration
val captureFromArgument get() = false
} }
fun <T> SimpleConstraintSystem.isSignatureNotLessSpecific( fun <T> SimpleConstraintSystem.isSignatureNotLessSpecific(
@@ -125,7 +129,16 @@ fun <T> SimpleConstraintSystem.isSignatureNotLessSpecific(
} }
else { else {
val substitutedGeneralType = typeSubstitutor.safeSubstitute(generalType, Variance.INVARIANT) 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())
} }
} }