Drop "substitute with upper bounds" mode for calls with mapped arguments

(we don't need it since we build constraint system for generic types).
Cleanup tests.
This commit is contained in:
Dmitry Petrov
2015-12-29 18:07:15 +03:00
parent 4b3290dd8c
commit 74c13906ed
5 changed files with 26 additions and 36 deletions
@@ -49,29 +49,16 @@ class CandidateCallWithArgumentMapping<D : CallableDescriptor, K> private constr
val isGeneric: Boolean = resolvedCall.resultingDescriptor.original.typeParameters.isNotEmpty()
private val upperBoundsSubstitutor =
BoundsSubstitutor.createUpperBoundsSubstitutor(resolvedCall.resultingDescriptor)
fun getExtensionReceiverType(substituteUpperBounds: Boolean): KotlinType? =
resultingDescriptor.extensionReceiverParameter?.type?.let {
extensionReceiverType ->
if (substituteUpperBounds)
upperBoundsSubstitutor.substitute(extensionReceiverType, Variance.INVARIANT)
else
extensionReceiverType
}
val extensionReceiverType: KotlinType?
get() = resultingDescriptor.extensionReceiverParameter?.type
/**
* Returns the type of a value that can be used in place of the corresponding parameter.
*/
fun getValueParameterType(argumentKey: K, substituteUpperBounds: Boolean): KotlinType? =
fun getValueParameterType(argumentKey: K): KotlinType? =
argumentsToParameters[argumentKey]?.let {
valueParameterDescriptor ->
val valueParameterType = valueParameterDescriptor.varargElementType ?: valueParameterDescriptor.type
if (substituteUpperBounds)
upperBoundsSubstitutor.substitute(valueParameterType, Variance.INVARIANT)
else
valueParameterType
valueParameterDescriptor.varargElementType ?: valueParameterDescriptor.type
}
companion object {
@@ -74,7 +74,10 @@ class OverloadingConflictResolver(private val builtIns: KotlinBuiltIns) {
}
}
private fun <D : CallableDescriptor> findMaximallySpecificCall(candidates: Set<MutableResolvedCall<D>>, discriminateGenerics: Boolean): MutableResolvedCall<D>? {
private fun <D : CallableDescriptor> findMaximallySpecificCall(
candidates: Set<MutableResolvedCall<D>>,
discriminateGenerics: Boolean
): MutableResolvedCall<D>? {
val filteredCandidates = uniquifyCandidatesSet(candidates)
if (filteredCandidates.size <= 1) return filteredCandidates.singleOrNull()
@@ -180,8 +183,8 @@ class OverloadingConflictResolver(private val builtIns: KotlinBuiltIns) {
return true
}
val extensionReceiverType1 = call1.getExtensionReceiverType(false)
val extensionReceiverType2 = call2.getExtensionReceiverType(false)
val extensionReceiverType1 = call1.extensionReceiverType
val extensionReceiverType2 = call2.extensionReceiverType
if (!compareTypesAndUpdateConstraints(extensionReceiverType1, extensionReceiverType2, RECEIVER_POSITION.position())) {
return false
}
@@ -190,12 +193,13 @@ class OverloadingConflictResolver(private val builtIns: KotlinBuiltIns) {
"$call1 and $call2 have different number of explicit arguments"
}
var index = 0
for (argumentKey in call1.argumentKeys) {
val type1 = call1.getValueParameterType(argumentKey, false)
val type2 = call2.getValueParameterType(argumentKey, false)
val type1 = call1.getValueParameterType(argumentKey)
val type2 = call2.getValueParameterType(argumentKey)
if (!compareTypesAndUpdateConstraints(type1, type2, VALUE_PARAMETER_POSITION.position(index++))) {
// We use this constraint system for subtyping relation check only,
// so exact value parameter position doesn't matter.
if (!compareTypesAndUpdateConstraints(type1, type2, VALUE_PARAMETER_POSITION.position(0))) {
return false
}
}
@@ -16,11 +16,11 @@ fun discriminateGeneric(a: Int, b: String = "") = ""
fun <T: CharSequence> withDefaultGeneric(t: T, d: T? = null) = 1
fun <T: Any> withDefaultGeneric(t: T, d: T? = null, a: Int = 1) = ""
fun wrongTwoDefault(a: Any = 2) = 1
fun wrongTwoDefault(a: Int = 2, b: String = "") = ""
fun withDefaults(a: Any = 2) = 1
fun withDefaults(a: Int = 2, b: String = "") = ""
fun <T: Any> wrongWithDefaultGeneric(t: T, d: T? = null) = 1
fun <T: CharSequence> wrongWithDefaultGeneric(t: T, d: T? = null, a: Int = 1) = ""
fun <T: Any> withGenericDefaults(t: T, d: T? = null) = 1
fun <T: CharSequence> withGenericDefaults(t: T, d: T? = null, a: Int = 1) = ""
fun wrong(a: Int = 1) {}
fun wrong(a: String = "", b: Int = 1) {}
@@ -50,10 +50,9 @@ fun test() {
val h = withDefaultGeneric("")
h checkType { _<Int>() }
withDefaults(1)
wrongTwoDefault(1)
wrongWithDefaultGeneric("")
withGenericDefaults("")
<!UNREACHABLE_CODE!><!OVERLOAD_RESOLUTION_AMBIGUITY!>wrong<!>(<!>null!!<!UNREACHABLE_CODE!>)<!>
}
@@ -9,11 +9,11 @@ public fun twoDefault(/*0*/ a: kotlin.Any = ..., /*1*/ b: kotlin.String = ...):
public fun twoDefault(/*0*/ a: kotlin.Int = ...): kotlin.Int
public fun </*0*/ T : kotlin.CharSequence> withDefaultGeneric(/*0*/ t: T, /*1*/ d: T? = ...): kotlin.Int
public fun </*0*/ T : kotlin.Any> withDefaultGeneric(/*0*/ t: T, /*1*/ d: T? = ..., /*2*/ a: kotlin.Int = ...): kotlin.String
public fun withDefaults(/*0*/ a: kotlin.Any = ...): kotlin.Int
public fun withDefaults(/*0*/ a: kotlin.Int = ..., /*1*/ b: kotlin.String = ...): kotlin.String
public fun </*0*/ T> withGeneric(/*0*/ a: T): kotlin.Int
public fun </*0*/ T> withGeneric(/*0*/ a: T, /*1*/ b: kotlin.Int = ...): kotlin.String
public fun </*0*/ T : kotlin.Any> withGenericDefaults(/*0*/ t: T, /*1*/ d: T? = ...): kotlin.Int
public fun </*0*/ T : kotlin.CharSequence> withGenericDefaults(/*0*/ t: T, /*1*/ d: T? = ..., /*2*/ a: kotlin.Int = ...): kotlin.String
public fun wrong(/*0*/ a: kotlin.Int = ...): kotlin.Unit
public fun wrong(/*0*/ a: kotlin.String = ..., /*1*/ b: kotlin.Int = ...): kotlin.Unit
public fun wrongTwoDefault(/*0*/ a: kotlin.Any = ...): kotlin.Int
public fun wrongTwoDefault(/*0*/ a: kotlin.Int = ..., /*1*/ b: kotlin.String = ...): kotlin.String
public fun </*0*/ T : kotlin.Any> wrongWithDefaultGeneric(/*0*/ t: T, /*1*/ d: T? = ...): kotlin.Int
public fun </*0*/ T : kotlin.CharSequence> wrongWithDefaultGeneric(/*0*/ t: T, /*1*/ d: T? = ..., /*2*/ a: kotlin.Int = ...): kotlin.String
@@ -6,4 +6,4 @@ class A<T>
fun <T1> A<T1>.foo() = X1
fun <T2> A<out T2>.foo() = X2
fun <T> A<out T>.test() = <!CANNOT_COMPLETE_RESOLVE!>foo<!>()
fun <T> A<out T>.test() = <!CANNOT_COMPLETE_RESOLVE!>foo<!>() // TODO fix constraint system