[NI] Fix ambiguity for extension functions with exact transient receiver

This commit is contained in:
Mikhail Zarechenskiy
2019-10-25 13:01:10 +03:00
parent eb3f50dce7
commit 588218658c
7 changed files with 54 additions and 7 deletions
@@ -2518,6 +2518,11 @@ public class FirDiagnosticsSmokeTestGenerated extends AbstractFirDiagnosticsSmok
runTest("compiler/testData/diagnostics/tests/callableReference/resolve/chooseCallableReferenceDependingOnInferredReceiver.kt");
}
@TestMetadata("chooseMostSpecificCandidateUsingCandidateDescriptorNotReflectionType.kt")
public void testChooseMostSpecificCandidateUsingCandidateDescriptorNotReflectionType() throws Exception {
runTest("compiler/testData/diagnostics/tests/callableReference/resolve/chooseMostSpecificCandidateUsingCandidateDescriptorNotReflectionType.kt");
}
@TestMetadata("chooseOuterCallBySingleCallableReference.kt")
public void testChooseOuterCallBySingleCallableReference() throws Exception {
runTest("compiler/testData/diagnostics/tests/callableReference/resolve/chooseOuterCallBySingleCallableReference.kt");
@@ -16,7 +16,7 @@
package org.jetbrains.kotlin.resolve.calls.results
import org.jetbrains.kotlin.builtins.getAllParameterProjectionsFromCallableReflectionType
import org.jetbrains.kotlin.builtins.getValueParameterTypesFromCallableReflectionType
import org.jetbrains.kotlin.container.DefaultImplementation
import org.jetbrains.kotlin.container.PlatformSpecificExtension
import org.jetbrains.kotlin.descriptors.CallableDescriptor
@@ -24,7 +24,9 @@ import org.jetbrains.kotlin.descriptors.MemberDescriptor
import org.jetbrains.kotlin.descriptors.ValueParameterDescriptor
import org.jetbrains.kotlin.descriptors.synthetic.SyntheticMemberDescriptor
import org.jetbrains.kotlin.resolve.calls.components.hasDefaultValue
import org.jetbrains.kotlin.types.*
import org.jetbrains.kotlin.types.AbstractTypeChecker
import org.jetbrains.kotlin.types.KotlinType
import org.jetbrains.kotlin.types.UnwrappedType
import org.jetbrains.kotlin.types.model.*
interface SpecificityComparisonCallbacks {
@@ -59,11 +61,18 @@ class FlatSignature<out T> constructor(
numDefaults: Int,
reflectionType: UnwrappedType
): FlatSignature<T> {
// Note that receiver is taking over descriptor, not reflection type
// This is correct as extension receiver can't have any defaults/varargs/coercions, so there is no need to use reflection type
// Plus, currently, receiver for reflection type is taking from *candidate*, see buildReflectionType, this candidate can
// have transient receiver which is not the same in its signature
val receiver = descriptor.extensionReceiverParameter?.type
val parameters = reflectionType.getValueParameterTypesFromCallableReflectionType(receiver == null).map { it.type }
return FlatSignature(
origin,
descriptor.typeParameters,
reflectionType.getAllParameterProjectionsFromCallableReflectionType().map { it.type },
hasExtensionReceiver = false,
listOfNotNull(receiver) + parameters,
hasExtensionReceiver = receiver != null,
hasVarargs = descriptor.valueParameters.any { it.varargElementType != null },
numDefaults = numDefaults,
isExpect = descriptor is MemberDescriptor && descriptor.isExpect,
@@ -0,0 +1,14 @@
// !DIAGNOSTICS: -UNUSED_PARAMETER
fun test() {
foo(String::extensionReceiver)
foo(::valueParameter)
}
fun CharSequence.extensionReceiver(): CharSequence = TODO()
fun String.extensionReceiver(): String = TODO()
fun valueParameter(c: CharSequence): CharSequence = TODO()
fun valueParameter(s: String): CharSequence = TODO()
fun <R> foo(f: (String) -> R) {}
@@ -0,0 +1,8 @@
package
public fun </*0*/ R> foo(/*0*/ f: (kotlin.String) -> R): kotlin.Unit
public fun test(): kotlin.Unit
public fun valueParameter(/*0*/ c: kotlin.CharSequence): kotlin.CharSequence
public fun valueParameter(/*0*/ s: kotlin.String): kotlin.CharSequence
public fun kotlin.CharSequence.extensionReceiver(): kotlin.CharSequence
public fun kotlin.String.extensionReceiver(): kotlin.String
@@ -2525,6 +2525,11 @@ public class DiagnosticsTestGenerated extends AbstractDiagnosticsTest {
runTest("compiler/testData/diagnostics/tests/callableReference/resolve/chooseCallableReferenceDependingOnInferredReceiver.kt");
}
@TestMetadata("chooseMostSpecificCandidateUsingCandidateDescriptorNotReflectionType.kt")
public void testChooseMostSpecificCandidateUsingCandidateDescriptorNotReflectionType() throws Exception {
runTest("compiler/testData/diagnostics/tests/callableReference/resolve/chooseMostSpecificCandidateUsingCandidateDescriptorNotReflectionType.kt");
}
@TestMetadata("chooseOuterCallBySingleCallableReference.kt")
public void testChooseOuterCallBySingleCallableReference() throws Exception {
runTest("compiler/testData/diagnostics/tests/callableReference/resolve/chooseOuterCallBySingleCallableReference.kt");
@@ -2520,6 +2520,11 @@ public class DiagnosticsUsingJavacTestGenerated extends AbstractDiagnosticsUsing
runTest("compiler/testData/diagnostics/tests/callableReference/resolve/chooseCallableReferenceDependingOnInferredReceiver.kt");
}
@TestMetadata("chooseMostSpecificCandidateUsingCandidateDescriptorNotReflectionType.kt")
public void testChooseMostSpecificCandidateUsingCandidateDescriptorNotReflectionType() throws Exception {
runTest("compiler/testData/diagnostics/tests/callableReference/resolve/chooseMostSpecificCandidateUsingCandidateDescriptorNotReflectionType.kt");
}
@TestMetadata("chooseOuterCallBySingleCallableReference.kt")
public void testChooseOuterCallBySingleCallableReference() throws Exception {
runTest("compiler/testData/diagnostics/tests/callableReference/resolve/chooseOuterCallBySingleCallableReference.kt");
@@ -140,12 +140,13 @@ fun KotlinType.getValueParameterTypesFromFunctionType(): List<TypeProjection> {
return arguments.subList(first, last)
}
fun KotlinType.getAllParameterProjectionsFromCallableReflectionType(): List<TypeProjection> {
fun KotlinType.getValueParameterTypesFromCallableReflectionType(withReceiver: Boolean): List<TypeProjection> {
assert(ReflectionTypes.isKCallableType(this)) { "Not a callable reflection type: $this" }
val arguments = arguments
val first = if (withReceiver) 0 else 1
val last = arguments.size - 1
assert(last >= 0) { "Unexpected number of type arguments in type: $this" }
return arguments.subList(0, last)
assert(first <= last) { "Not an exact function type: $this" }
return arguments.subList(first, last)
}
fun KotlinType.extractParameterNameFromFunctionTypeArgument(): Name? {