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:
+4
-17
@@ -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 {
|
||||
|
||||
+11
-7
@@ -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
|
||||
|
||||
+1
-1
@@ -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
|
||||
Reference in New Issue
Block a user