From bf4a68158934063590f16f638e38f8ed57e7a043 Mon Sep 17 00:00:00 2001 From: Alexander Udalov Date: Thu, 15 Oct 2015 13:05:55 +0300 Subject: [PATCH] Deduce receiver type of callable reference from LHS, not from descriptor --- .../CallableReferencesResolutionUtils.kt | 19 +++++++++++++------ .../resolve/calls/ArgumentTypeResolver.java | 2 +- .../BasicExpressionTypingVisitor.java | 4 +++- .../function/extensionToSupertype.kt | 18 ++++++++++++++++++ .../function/extensionToSupertype.txt | 18 ++++++++++++++++++ .../checkers/JetDiagnosticsTestGenerated.java | 6 ++++++ 6 files changed, 59 insertions(+), 8 deletions(-) create mode 100644 compiler/testData/diagnostics/tests/callableReference/function/extensionToSupertype.kt create mode 100644 compiler/testData/diagnostics/tests/callableReference/function/extensionToSupertype.txt diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/callableReferences/CallableReferencesResolutionUtils.kt b/compiler/frontend/src/org/jetbrains/kotlin/resolve/callableReferences/CallableReferencesResolutionUtils.kt index 6d720f734c1..341072fc9fc 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/callableReferences/CallableReferencesResolutionUtils.kt +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/callableReferences/CallableReferencesResolutionUtils.kt @@ -201,6 +201,7 @@ private fun bindPropertyReference(expression: JetCallableReferenceExpression, re private fun createReflectionTypeForCallableDescriptor( descriptor: CallableDescriptor, + lhsType: JetType?, reflectionTypes: ReflectionTypes, trace: BindingTrace?, reportOn: JetExpression? @@ -220,7 +221,10 @@ private fun createReflectionTypeForCallableDescriptor( return null } - val receiverType = extensionReceiver?.getType() ?: dispatchReceiver?.getType() + val receiverType = + if (extensionReceiver != null || dispatchReceiver != null) + lhsType ?: extensionReceiver?.type ?: dispatchReceiver?.type + else null return when (descriptor) { is FunctionDescriptor -> @@ -242,16 +246,18 @@ public fun getReflectionTypeForCandidateDescriptor( descriptor: CallableDescriptor, reflectionTypes: ReflectionTypes ): JetType? = - createReflectionTypeForCallableDescriptor(descriptor, reflectionTypes, null, null) + createReflectionTypeForCallableDescriptor(descriptor, null, reflectionTypes, null, null) public fun createReflectionTypeForResolvedCallableReference( reference: JetCallableReferenceExpression, + lhsType: JetType?, descriptor: CallableDescriptor, context: ResolutionContext<*>, reflectionTypes: ReflectionTypes ): JetType? { - val type = createReflectionTypeForCallableDescriptor(descriptor, reflectionTypes, context.trace, reference.getCallableReference()) - ?: return null + val type = createReflectionTypeForCallableDescriptor( + descriptor, lhsType, reflectionTypes, context.trace, reference.getCallableReference() + ) ?: return null when (descriptor) { is FunctionDescriptor -> { bindFunctionReference(reference, type, context) @@ -265,6 +271,7 @@ public fun createReflectionTypeForResolvedCallableReference( public fun getResolvedCallableReferenceShapeType( reference: JetCallableReferenceExpression, + lhsType: JetType?, overloadResolutionResults: OverloadResolutionResults?, context: ResolutionContext<*>, expectedTypeUnknown: Boolean, @@ -275,9 +282,9 @@ public fun getResolvedCallableReferenceShapeType( when { overloadResolutionResults == null -> null - overloadResolutionResults.isSingleResult() -> + overloadResolutionResults.isSingleResult -> OverloadResolutionResultsUtil.getResultingCall(overloadResolutionResults, context.contextDependency)?.let { call -> - createReflectionTypeForCallableDescriptor(call.getResultingDescriptor(), reflectionTypes, context.trace, reference) + createReflectionTypeForCallableDescriptor(call.resultingDescriptor, lhsType, reflectionTypes, context.trace, reference) } expectedTypeUnknown /* && overload resolution was ambiguous */ -> functionPlaceholders.createFunctionPlaceholderType(emptyList(), false) diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/ArgumentTypeResolver.java b/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/ArgumentTypeResolver.java index 061dcb129ea..fdb35ed910d 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/ArgumentTypeResolver.java +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/ArgumentTypeResolver.java @@ -250,7 +250,7 @@ public class ArgumentTypeResolver { callableReferenceExpression, receiverType, context, ResolveArgumentsMode.SHAPE_FUNCTION_ARGUMENTS, callResolver); return CallableReferencesResolutionUtilsKt.getResolvedCallableReferenceShapeType( - callableReferenceExpression, overloadResolutionResults, context, expectedTypeIsUnknown, + callableReferenceExpression, receiverType, overloadResolutionResults, context, expectedTypeIsUnknown, reflectionTypes, builtIns, functionPlaceholders); } diff --git a/compiler/frontend/src/org/jetbrains/kotlin/types/expressions/BasicExpressionTypingVisitor.java b/compiler/frontend/src/org/jetbrains/kotlin/types/expressions/BasicExpressionTypingVisitor.java index 0a8b0ca8f44..3e25cfb6088 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/types/expressions/BasicExpressionTypingVisitor.java +++ b/compiler/frontend/src/org/jetbrains/kotlin/types/expressions/BasicExpressionTypingVisitor.java @@ -700,7 +700,9 @@ public class BasicExpressionTypingVisitor extends ExpressionTypingVisitor { context.trace.report(CALLABLE_REFERENCE_TO_OBJECT_MEMBER.on(reference)); } - return CallableReferencesResolutionUtilsKt.createReflectionTypeForResolvedCallableReference(expression, descriptor, context, components.reflectionTypes); + return CallableReferencesResolutionUtilsKt.createReflectionTypeForResolvedCallableReference( + expression, lhsType, descriptor, context, components.reflectionTypes + ); } @Override diff --git a/compiler/testData/diagnostics/tests/callableReference/function/extensionToSupertype.kt b/compiler/testData/diagnostics/tests/callableReference/function/extensionToSupertype.kt new file mode 100644 index 00000000000..806d960ee23 --- /dev/null +++ b/compiler/testData/diagnostics/tests/callableReference/function/extensionToSupertype.kt @@ -0,0 +1,18 @@ +// !CHECK_TYPE +// !DIAGNOSTICS: -UNUSED_PARAMETER + +import kotlin.reflect.* + +interface A +interface B : A + +fun A.foo() {} + +fun take(f: (A) -> Unit) {} +fun take(f: () -> Unit) {} + +fun test() { + B::foo checkType { _>() } + + take(B::foo) +} diff --git a/compiler/testData/diagnostics/tests/callableReference/function/extensionToSupertype.txt b/compiler/testData/diagnostics/tests/callableReference/function/extensionToSupertype.txt new file mode 100644 index 00000000000..e5b735ecf31 --- /dev/null +++ b/compiler/testData/diagnostics/tests/callableReference/function/extensionToSupertype.txt @@ -0,0 +1,18 @@ +package + +public fun take(/*0*/ f: () -> kotlin.Unit): kotlin.Unit +public fun take(/*0*/ f: (A) -> kotlin.Unit): kotlin.Unit +public fun test(): kotlin.Unit +public fun A.foo(): kotlin.Unit + +public interface A { + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String +} + +public interface B : A { + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String +} diff --git a/compiler/tests/org/jetbrains/kotlin/checkers/JetDiagnosticsTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/checkers/JetDiagnosticsTestGenerated.java index 3b3066b3770..5ddc064964d 100644 --- a/compiler/tests/org/jetbrains/kotlin/checkers/JetDiagnosticsTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/checkers/JetDiagnosticsTestGenerated.java @@ -1721,6 +1721,12 @@ public class JetDiagnosticsTestGenerated extends AbstractJetDiagnosticsTest { doTest(fileName); } + @TestMetadata("extensionToSupertype.kt") + public void testExtensionToSupertype() throws Exception { + String fileName = JetTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/callableReference/function/extensionToSupertype.kt"); + doTest(fileName); + } + @TestMetadata("fakeOverrideType.kt") public void testFakeOverrideType() throws Exception { String fileName = JetTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/callableReference/function/fakeOverrideType.kt");