From 74c13906ed7fd47c0d68b64a0db7c467c93d7379 Mon Sep 17 00:00:00 2001 From: Dmitry Petrov Date: Tue, 29 Dec 2015 18:07:15 +0300 Subject: [PATCH] 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. --- .../CandidateCallWithArgumentMapping.kt | 21 ++++--------------- .../results/OverloadingConflictResolver.kt | 18 +++++++++------- .../tests/overload/defaultParameters.kt | 13 ++++++------ .../tests/overload/defaultParameters.txt | 8 +++---- .../resolve/overloadConflicts/withVariance.kt | 2 +- 5 files changed, 26 insertions(+), 36 deletions(-) diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/results/CandidateCallWithArgumentMapping.kt b/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/results/CandidateCallWithArgumentMapping.kt index 75156c1d772..980e7f58bb5 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/results/CandidateCallWithArgumentMapping.kt +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/results/CandidateCallWithArgumentMapping.kt @@ -49,29 +49,16 @@ class CandidateCallWithArgumentMapping 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 { 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 39fd761f4bb..ca4f1e983e5 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 @@ -74,7 +74,10 @@ class OverloadingConflictResolver(private val builtIns: KotlinBuiltIns) { } } - private fun findMaximallySpecificCall(candidates: Set>, discriminateGenerics: Boolean): MutableResolvedCall? { + private fun findMaximallySpecificCall( + candidates: Set>, + discriminateGenerics: Boolean + ): MutableResolvedCall? { 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 } } diff --git a/compiler/testData/diagnostics/tests/overload/defaultParameters.kt b/compiler/testData/diagnostics/tests/overload/defaultParameters.kt index 47d88ad10d8..d1829c687f1 100644 --- a/compiler/testData/diagnostics/tests/overload/defaultParameters.kt +++ b/compiler/testData/diagnostics/tests/overload/defaultParameters.kt @@ -16,11 +16,11 @@ fun discriminateGeneric(a: Int, b: String = "") = "" fun withDefaultGeneric(t: T, d: T? = null) = 1 fun 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 wrongWithDefaultGeneric(t: T, d: T? = null) = 1 -fun wrongWithDefaultGeneric(t: T, d: T? = null, a: Int = 1) = "" +fun withGenericDefaults(t: T, d: T? = null) = 1 +fun 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 { _() } + withDefaults(1) - wrongTwoDefault(1) - - wrongWithDefaultGeneric("") + withGenericDefaults("") wrong(null!!) } \ No newline at end of file diff --git a/compiler/testData/diagnostics/tests/overload/defaultParameters.txt b/compiler/testData/diagnostics/tests/overload/defaultParameters.txt index 054629eb8b1..7f78657bdf2 100644 --- a/compiler/testData/diagnostics/tests/overload/defaultParameters.txt +++ b/compiler/testData/diagnostics/tests/overload/defaultParameters.txt @@ -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 withDefaultGeneric(/*0*/ t: T, /*1*/ d: T? = ...): kotlin.Int public fun 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 withGeneric(/*0*/ a: T): kotlin.Int public fun withGeneric(/*0*/ a: T, /*1*/ b: kotlin.Int = ...): kotlin.String +public fun withGenericDefaults(/*0*/ t: T, /*1*/ d: T? = ...): kotlin.Int +public fun 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 wrongWithDefaultGeneric(/*0*/ t: T, /*1*/ d: T? = ...): kotlin.Int -public fun wrongWithDefaultGeneric(/*0*/ t: T, /*1*/ d: T? = ..., /*2*/ a: kotlin.Int = ...): kotlin.String diff --git a/compiler/testData/diagnostics/tests/resolve/overloadConflicts/withVariance.kt b/compiler/testData/diagnostics/tests/resolve/overloadConflicts/withVariance.kt index b93ffd44660..c35e9d24789 100644 --- a/compiler/testData/diagnostics/tests/resolve/overloadConflicts/withVariance.kt +++ b/compiler/testData/diagnostics/tests/resolve/overloadConflicts/withVariance.kt @@ -6,4 +6,4 @@ class A fun A.foo() = X1 fun A.foo() = X2 -fun A.test() = foo() \ No newline at end of file +fun A.test() = foo() // TODO fix constraint system \ No newline at end of file