From 20a7f387bf159e0fe1894ed87d2c2fa6b49aa6c3 Mon Sep 17 00:00:00 2001 From: Mikhail Zarechenskiy Date: Thu, 4 Apr 2019 03:02:53 +0300 Subject: [PATCH] [NI] Resolve callable reference eagerly if there is only one candidate #KT-30737 Fixed --- .../fir/FirDiagnosticsSmokeTestGenerated.java | 30 ++++++++++++++ .../components/CallableReferenceResolver.kt | 9 +++++ .../components/PostponeArgumentsChecks.kt | 5 +-- .../KotlinConstraintSystemCompleter.kt | 4 +- .../resolve/calls/model/ResolutionAtoms.kt | 19 ++++++++- .../generic/explicitTypeArguments.kt | 2 +- ...nNoApplicableCallableReferenceCandidate.kt | 11 ++++++ ...NoApplicableCallableReferenceCandidate.txt | 6 +++ ...icableCallableReferenceFromDistantScope.kt | 15 +++++++ ...cableCallableReferenceFromDistantScope.txt | 14 +++++++ ...bleReferenceDependingOnInferredReceiver.kt | 39 +++++++++++++++++++ ...leReferenceDependingOnInferredReceiver.txt | 24 ++++++++++++ ...rtypeFromReturnTypesOfCallableReference.kt | 16 ++++++++ ...typeFromReturnTypesOfCallableReference.txt | 24 ++++++++++++ .../eagerAndPostponedCallableReferences.kt | 35 +++++++++++++++++ .../eagerAndPostponedCallableReferences.txt | 20 ++++++++++ .../eagerResolveOfSingleCallableReference.kt | 15 +++++++ .../eagerResolveOfSingleCallableReference.txt | 32 +++++++++++++++ ...postponedResolveOfManyCallableReference.kt | 19 +++++++++ ...ostponedResolveOfManyCallableReference.txt | 19 +++++++++ .../nothingWithCallableReference.kt | 13 +++---- .../checkers/DiagnosticsTestGenerated.java | 35 +++++++++++++++++ .../DiagnosticsUsingJavacTestGenerated.java | 30 ++++++++++++++ 23 files changed, 420 insertions(+), 16 deletions(-) create mode 100644 compiler/testData/diagnostics/tests/callableReference/resolve/ambiguityWhenNoApplicableCallableReferenceCandidate.kt create mode 100644 compiler/testData/diagnostics/tests/callableReference/resolve/ambiguityWhenNoApplicableCallableReferenceCandidate.txt create mode 100644 compiler/testData/diagnostics/tests/callableReference/resolve/applicableCallableReferenceFromDistantScope.kt create mode 100644 compiler/testData/diagnostics/tests/callableReference/resolve/applicableCallableReferenceFromDistantScope.txt create mode 100644 compiler/testData/diagnostics/tests/callableReference/resolve/chooseCallableReferenceDependingOnInferredReceiver.kt create mode 100644 compiler/testData/diagnostics/tests/callableReference/resolve/chooseCallableReferenceDependingOnInferredReceiver.txt create mode 100644 compiler/testData/diagnostics/tests/callableReference/resolve/commonSupertypeFromReturnTypesOfCallableReference.kt create mode 100644 compiler/testData/diagnostics/tests/callableReference/resolve/commonSupertypeFromReturnTypesOfCallableReference.txt create mode 100644 compiler/testData/diagnostics/tests/callableReference/resolve/eagerAndPostponedCallableReferences.kt create mode 100644 compiler/testData/diagnostics/tests/callableReference/resolve/eagerAndPostponedCallableReferences.txt create mode 100644 compiler/testData/diagnostics/tests/callableReference/resolve/eagerResolveOfSingleCallableReference.kt create mode 100644 compiler/testData/diagnostics/tests/callableReference/resolve/eagerResolveOfSingleCallableReference.txt create mode 100644 compiler/testData/diagnostics/tests/callableReference/resolve/postponedResolveOfManyCallableReference.kt create mode 100644 compiler/testData/diagnostics/tests/callableReference/resolve/postponedResolveOfManyCallableReference.txt diff --git a/compiler/fir/resolve/tests/org/jetbrains/kotlin/fir/FirDiagnosticsSmokeTestGenerated.java b/compiler/fir/resolve/tests/org/jetbrains/kotlin/fir/FirDiagnosticsSmokeTestGenerated.java index e13a607b728..5b1dc7770bd 100644 --- a/compiler/fir/resolve/tests/org/jetbrains/kotlin/fir/FirDiagnosticsSmokeTestGenerated.java +++ b/compiler/fir/resolve/tests/org/jetbrains/kotlin/fir/FirDiagnosticsSmokeTestGenerated.java @@ -2298,11 +2298,21 @@ public class FirDiagnosticsSmokeTestGenerated extends AbstractFirDiagnosticsSmok KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/diagnostics/tests/callableReference/resolve"), Pattern.compile("^(.+)\\.kt$"), TargetBackend.ANY, true); } + @TestMetadata("ambiguityWhenNoApplicableCallableReferenceCandidate.kt") + public void testAmbiguityWhenNoApplicableCallableReferenceCandidate() throws Exception { + runTest("compiler/testData/diagnostics/tests/callableReference/resolve/ambiguityWhenNoApplicableCallableReferenceCandidate.kt"); + } + @TestMetadata("ambiguousWithVararg.kt") public void testAmbiguousWithVararg() throws Exception { runTest("compiler/testData/diagnostics/tests/callableReference/resolve/ambiguousWithVararg.kt"); } + @TestMetadata("applicableCallableReferenceFromDistantScope.kt") + public void testApplicableCallableReferenceFromDistantScope() throws Exception { + runTest("compiler/testData/diagnostics/tests/callableReference/resolve/applicableCallableReferenceFromDistantScope.kt"); + } + @TestMetadata("byArgType.kt") public void testByArgType() throws Exception { runTest("compiler/testData/diagnostics/tests/callableReference/resolve/byArgType.kt"); @@ -2318,11 +2328,26 @@ public class FirDiagnosticsSmokeTestGenerated extends AbstractFirDiagnosticsSmok runTest("compiler/testData/diagnostics/tests/callableReference/resolve/byValType.kt"); } + @TestMetadata("commonSupertypeFromReturnTypesOfCallableReference.kt") + public void testCommonSupertypeFromReturnTypesOfCallableReference() throws Exception { + runTest("compiler/testData/diagnostics/tests/callableReference/resolve/commonSupertypeFromReturnTypesOfCallableReference.kt"); + } + @TestMetadata("constructor.kt") public void testConstructor() throws Exception { runTest("compiler/testData/diagnostics/tests/callableReference/resolve/constructor.kt"); } + @TestMetadata("eagerAndPostponedCallableReferences.kt") + public void testEagerAndPostponedCallableReferences() throws Exception { + runTest("compiler/testData/diagnostics/tests/callableReference/resolve/eagerAndPostponedCallableReferences.kt"); + } + + @TestMetadata("eagerResolveOfSingleCallableReference.kt") + public void testEagerResolveOfSingleCallableReference() throws Exception { + runTest("compiler/testData/diagnostics/tests/callableReference/resolve/eagerResolveOfSingleCallableReference.kt"); + } + @TestMetadata("innerClassConstructorOnOuterClassInstance.kt") public void testInnerClassConstructorOnOuterClassInstance() throws Exception { runTest("compiler/testData/diagnostics/tests/callableReference/resolve/innerClassConstructorOnOuterClassInstance.kt"); @@ -2393,6 +2418,11 @@ public class FirDiagnosticsSmokeTestGenerated extends AbstractFirDiagnosticsSmok runTest("compiler/testData/diagnostics/tests/callableReference/resolve/overloadsMember.kt"); } + @TestMetadata("postponedResolveOfManyCallableReference.kt") + public void testPostponedResolveOfManyCallableReference() throws Exception { + runTest("compiler/testData/diagnostics/tests/callableReference/resolve/postponedResolveOfManyCallableReference.kt"); + } + @TestMetadata("resolveEqualsOperatorWithAnyExpectedType.kt") public void testResolveEqualsOperatorWithAnyExpectedType() throws Exception { runTest("compiler/testData/diagnostics/tests/callableReference/resolve/resolveEqualsOperatorWithAnyExpectedType.kt"); diff --git a/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/components/CallableReferenceResolver.kt b/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/components/CallableReferenceResolver.kt index 91743a1ba58..9c2f53206fa 100644 --- a/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/components/CallableReferenceResolver.kt +++ b/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/components/CallableReferenceResolver.kt @@ -74,6 +74,15 @@ class CallableReferenceResolver( val candidates = runRHSResolution(scopeTower, argument, expectedType) { checkCallableReference -> csBuilder.runTransaction { checkCallableReference(this); false } } + + if (candidates.size > 1 && resolvedAtom is EagerCallableReferenceAtom) { + resolvedAtom.setAnalyzedResults( + candidate = null, + subResolvedAtoms = listOf(resolvedAtom.transformToPostponed()) + ) + return + } + val chosenCandidate = candidates.singleOrNull() if (chosenCandidate != null) { val (toFreshSubstitutor, diagnostic) = with(chosenCandidate) { diff --git a/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/components/PostponeArgumentsChecks.kt b/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/components/PostponeArgumentsChecks.kt index d703c38b7eb..767a37795b2 100644 --- a/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/components/PostponeArgumentsChecks.kt +++ b/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/components/PostponeArgumentsChecks.kt @@ -19,13 +19,10 @@ package org.jetbrains.kotlin.resolve.calls.components import org.jetbrains.kotlin.builtins.* import org.jetbrains.kotlin.descriptors.annotations.Annotations import org.jetbrains.kotlin.resolve.calls.inference.ConstraintSystemBuilder -import org.jetbrains.kotlin.resolve.calls.inference.NewConstraintSystem import org.jetbrains.kotlin.resolve.calls.inference.model.ArgumentConstraintPosition -import org.jetbrains.kotlin.resolve.calls.inference.model.NewConstraintSystemImpl import org.jetbrains.kotlin.resolve.calls.inference.model.LHSArgumentConstraintPosition import org.jetbrains.kotlin.resolve.calls.inference.model.TypeVariableForLambdaReturnType import org.jetbrains.kotlin.resolve.calls.model.* -import org.jetbrains.kotlin.types.TypeConstructor import org.jetbrains.kotlin.types.UnwrappedType import org.jetbrains.kotlin.types.typeUtil.builtIns import org.jetbrains.kotlin.utils.addToStdlib.safeAs @@ -140,7 +137,7 @@ private fun preprocessCallableReference( expectedType: UnwrappedType?, diagnosticsHolder: KotlinDiagnosticsHolder ): ResolvedAtom { - val result = ResolvedCallableReferenceAtom(argument, expectedType) + val result = EagerCallableReferenceAtom(argument, expectedType) if (expectedType == null) return result val notCallableTypeConstructor = diff --git a/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/inference/components/KotlinConstraintSystemCompleter.kt b/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/inference/components/KotlinConstraintSystemCompleter.kt index af5300fb980..f897f484a39 100644 --- a/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/inference/components/KotlinConstraintSystemCompleter.kt +++ b/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/inference/components/KotlinConstraintSystemCompleter.kt @@ -5,7 +5,6 @@ package org.jetbrains.kotlin.resolve.calls.inference.components -import org.jetbrains.kotlin.resolve.calls.inference.model.NewTypeVariable import org.jetbrains.kotlin.resolve.calls.inference.model.NotEnoughInformationForTypeParameter import org.jetbrains.kotlin.resolve.calls.inference.model.VariableWithConstraints import org.jetbrains.kotlin.resolve.calls.model.* @@ -15,7 +14,6 @@ import org.jetbrains.kotlin.types.model.KotlinTypeMarker import org.jetbrains.kotlin.types.model.TypeConstructorMarker import org.jetbrains.kotlin.types.model.TypeVariableMarker import org.jetbrains.kotlin.utils.addIfNotNull -import org.jetbrains.kotlin.utils.addToStdlib.cast import org.jetbrains.kotlin.utils.addToStdlib.firstIsInstanceOrNull import org.jetbrains.kotlin.utils.addToStdlib.safeAs @@ -79,7 +77,7 @@ class KotlinConstraintSystemCompleter( ) ?: break if (shouldForceCallableReferenceOrLambdaResolution(completionMode, variableForFixation)) { - if (forcePostponedAtomResolution(topLevelAtoms, analyze)) continue + if (forcePostponedAtomResolution(topLevelAtoms, analyze)) continue if (forcePostponedAtomResolution(topLevelAtoms, analyze)) continue } diff --git a/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/model/ResolutionAtoms.kt b/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/model/ResolutionAtoms.kt index 693146103a6..43860b3b842 100644 --- a/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/model/ResolutionAtoms.kt +++ b/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/model/ResolutionAtoms.kt @@ -111,7 +111,7 @@ class ResolvedLambdaAtom( override val outputType: UnwrappedType get() = returnType } -class ResolvedCallableReferenceAtom( +abstract class ResolvedCallableReferenceAtom( override val atom: CallableReferenceKotlinCallArgument, val expectedType: UnwrappedType? ) : PostponedResolvedAtom() { @@ -126,6 +126,23 @@ class ResolvedCallableReferenceAtom( setAnalyzedResults(subResolvedAtoms) } +} + +class EagerCallableReferenceAtom( + atom: CallableReferenceKotlinCallArgument, + expectedType: UnwrappedType? +) : ResolvedCallableReferenceAtom(atom, expectedType) { + + override val inputTypes: Collection get() = emptyList() + override val outputType: UnwrappedType? get() = null + + fun transformToPostponed(): PostponedCallableReferenceAtom = PostponedCallableReferenceAtom(this) +} + +class PostponedCallableReferenceAtom( + eagerCallableReferenceAtom: EagerCallableReferenceAtom +) : ResolvedCallableReferenceAtom(eagerCallableReferenceAtom.atom, eagerCallableReferenceAtom.expectedType) { + override val inputTypes: Collection get() = extractInputOutputTypesFromCallableReferenceExpectedType(expectedType)?.inputTypes ?: listOfNotNull(expectedType) diff --git a/compiler/testData/diagnostics/tests/callableReference/generic/explicitTypeArguments.kt b/compiler/testData/diagnostics/tests/callableReference/generic/explicitTypeArguments.kt index 115cc5b6903..f9e1511590b 100644 --- a/compiler/testData/diagnostics/tests/callableReference/generic/explicitTypeArguments.kt +++ b/compiler/testData/diagnostics/tests/callableReference/generic/explicitTypeArguments.kt @@ -14,7 +14,7 @@ fun Wrapper.baz(transform: (T) -> Unit): T = TODO() fun test() { takeFun(::foo) - takeFun(::fooInt) + takeFun(::fooInt) callFun>(::createWrapper) callFun>(::createWrapper) diff --git a/compiler/testData/diagnostics/tests/callableReference/resolve/ambiguityWhenNoApplicableCallableReferenceCandidate.kt b/compiler/testData/diagnostics/tests/callableReference/resolve/ambiguityWhenNoApplicableCallableReferenceCandidate.kt new file mode 100644 index 00000000000..5c12daf7743 --- /dev/null +++ b/compiler/testData/diagnostics/tests/callableReference/resolve/ambiguityWhenNoApplicableCallableReferenceCandidate.kt @@ -0,0 +1,11 @@ +// !LANGUAGE: +NewInference +// !DIAGNOSTICS: -UNUSED_PARAMETER + +fun foo(x: Int) {} +fun foo(y: String) {} + +fun bar(f: (T) -> Unit) {} + +fun test() { + bar(::foo) +} \ No newline at end of file diff --git a/compiler/testData/diagnostics/tests/callableReference/resolve/ambiguityWhenNoApplicableCallableReferenceCandidate.txt b/compiler/testData/diagnostics/tests/callableReference/resolve/ambiguityWhenNoApplicableCallableReferenceCandidate.txt new file mode 100644 index 00000000000..3df703c6d84 --- /dev/null +++ b/compiler/testData/diagnostics/tests/callableReference/resolve/ambiguityWhenNoApplicableCallableReferenceCandidate.txt @@ -0,0 +1,6 @@ +package + +public fun bar(/*0*/ f: (T) -> kotlin.Unit): kotlin.Unit +public fun foo(/*0*/ x: kotlin.Int): kotlin.Unit +public fun foo(/*0*/ y: kotlin.String): kotlin.Unit +public fun test(): kotlin.Unit diff --git a/compiler/testData/diagnostics/tests/callableReference/resolve/applicableCallableReferenceFromDistantScope.kt b/compiler/testData/diagnostics/tests/callableReference/resolve/applicableCallableReferenceFromDistantScope.kt new file mode 100644 index 00000000000..55fa377705e --- /dev/null +++ b/compiler/testData/diagnostics/tests/callableReference/resolve/applicableCallableReferenceFromDistantScope.kt @@ -0,0 +1,15 @@ +// !LANGUAGE: +NewInference +// !DIAGNOSTICS: -UNUSED_PARAMETER -UNUSED_VARIABLE + +fun foo(s: String) {} + +object Scope { + fun foo(a: Int) {} + fun foo(b: Boolean) {} + + fun bar(f: (T) -> Unit): T = TODO() + + fun test() { + val s: String = bar(::foo) + } +} \ No newline at end of file diff --git a/compiler/testData/diagnostics/tests/callableReference/resolve/applicableCallableReferenceFromDistantScope.txt b/compiler/testData/diagnostics/tests/callableReference/resolve/applicableCallableReferenceFromDistantScope.txt new file mode 100644 index 00000000000..8532db7b637 --- /dev/null +++ b/compiler/testData/diagnostics/tests/callableReference/resolve/applicableCallableReferenceFromDistantScope.txt @@ -0,0 +1,14 @@ +package + +public fun foo(/*0*/ s: kotlin.String): kotlin.Unit + +public object Scope { + private constructor Scope() + public final fun bar(/*0*/ f: (T) -> kotlin.Unit): T + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + public final fun foo(/*0*/ b: kotlin.Boolean): kotlin.Unit + public final fun foo(/*0*/ a: kotlin.Int): kotlin.Unit + public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int + public final fun test(): kotlin.Unit + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String +} diff --git a/compiler/testData/diagnostics/tests/callableReference/resolve/chooseCallableReferenceDependingOnInferredReceiver.kt b/compiler/testData/diagnostics/tests/callableReference/resolve/chooseCallableReferenceDependingOnInferredReceiver.kt new file mode 100644 index 00000000000..ac9fca6cd1b --- /dev/null +++ b/compiler/testData/diagnostics/tests/callableReference/resolve/chooseCallableReferenceDependingOnInferredReceiver.kt @@ -0,0 +1,39 @@ +// !LANGUAGE: +NewInference +// !DIAGNOSTICS: -UNUSED_PARAMETER -UNUSED_VARIABLE -UNUSED_EXPRESSION + +class A { + fun foo(i: A) {} + + fun baz(i: A) {} +} + +class B { + fun foo(s: B) {} + fun foo(c: Char) {} + + fun baz(s: B) {} +} + +fun bar(f: (T) -> Unit): T = TODO() + +fun test() { + myWith(A()) { + val t1 = bar(::foo) + t1 + + val t2 = bar(::baz) + t2 + + myWith(B()) { + val a: A = bar(::foo) + val b: B = bar(::foo) + + val t3 = bar(::baz) + t3 + + bar(::foo) + } + } +} + +inline fun myWith(receiver: T, block: T.() -> R): R = TODO() \ No newline at end of file diff --git a/compiler/testData/diagnostics/tests/callableReference/resolve/chooseCallableReferenceDependingOnInferredReceiver.txt b/compiler/testData/diagnostics/tests/callableReference/resolve/chooseCallableReferenceDependingOnInferredReceiver.txt new file mode 100644 index 00000000000..f64cea2cf9b --- /dev/null +++ b/compiler/testData/diagnostics/tests/callableReference/resolve/chooseCallableReferenceDependingOnInferredReceiver.txt @@ -0,0 +1,24 @@ +package + +public fun bar(/*0*/ f: (T) -> kotlin.Unit): T +public inline fun myWith(/*0*/ receiver: T, /*1*/ block: T.() -> R): R +public fun test(): kotlin.Unit + +public final class A { + public constructor A() + public final fun baz(/*0*/ i: A): kotlin.Unit + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + public final fun foo(/*0*/ i: A): kotlin.Unit + public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String +} + +public final class B { + public constructor B() + public final fun baz(/*0*/ s: B): kotlin.Unit + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + public final fun foo(/*0*/ s: B): kotlin.Unit + public final fun foo(/*0*/ c: kotlin.Char): kotlin.Unit + public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String +} diff --git a/compiler/testData/diagnostics/tests/callableReference/resolve/commonSupertypeFromReturnTypesOfCallableReference.kt b/compiler/testData/diagnostics/tests/callableReference/resolve/commonSupertypeFromReturnTypesOfCallableReference.kt new file mode 100644 index 00000000000..ee42cd44b7a --- /dev/null +++ b/compiler/testData/diagnostics/tests/callableReference/resolve/commonSupertypeFromReturnTypesOfCallableReference.kt @@ -0,0 +1,16 @@ +// !LANGUAGE: +NewInference +// !DIAGNOSTICS: -UNUSED_PARAMETER -UNUSED_EXPRESSION + +interface Parent +interface Child1 : Parent +interface Child2 : Parent + +fun foo(): Child1 = TODO() +fun bar(): Child2 = TODO() + +fun select(x: K, y: K): K = TODO() + +fun test() { + val a = select(::foo, ::bar) + ")!>a +} \ No newline at end of file diff --git a/compiler/testData/diagnostics/tests/callableReference/resolve/commonSupertypeFromReturnTypesOfCallableReference.txt b/compiler/testData/diagnostics/tests/callableReference/resolve/commonSupertypeFromReturnTypesOfCallableReference.txt new file mode 100644 index 00000000000..7383e92ddea --- /dev/null +++ b/compiler/testData/diagnostics/tests/callableReference/resolve/commonSupertypeFromReturnTypesOfCallableReference.txt @@ -0,0 +1,24 @@ +package + +public fun bar(): Child2 +public fun foo(): Child1 +public fun select(/*0*/ x: K, /*1*/ y: K): K +public fun test(): kotlin.Unit + +public interface Child1 : Parent { + 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 Child2 : Parent { + 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 Parent { + 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/testData/diagnostics/tests/callableReference/resolve/eagerAndPostponedCallableReferences.kt b/compiler/testData/diagnostics/tests/callableReference/resolve/eagerAndPostponedCallableReferences.kt new file mode 100644 index 00000000000..dbf3b93e70b --- /dev/null +++ b/compiler/testData/diagnostics/tests/callableReference/resolve/eagerAndPostponedCallableReferences.kt @@ -0,0 +1,35 @@ +// !LANGUAGE: +NewInference +// !DIAGNOSTICS: -UNUSED_PARAMETER -UNUSED_VARIABLE -UNUSED_EXPRESSION + +interface A +interface B + +fun multiple(a: A) {} +fun multiple(b: B) {} + +fun singleA(a: A) {} +fun singleB(a: B) {} + +fun foo(f: (T) -> Unit, g: (T) -> Unit): T = TODO() + +fun test() { + val a1 = foo(::singleA, ::multiple) + a1 + + val a2 = foo(::singleB, ::multiple) + a2 + + val a3 = foo(::multiple, ::singleA) + a3 + + val a4 = foo(::multiple, ::singleB) + a4 + + val a5 = foo(::singleA, ::singleA) + a5 + + val a6 = foo(::singleA, ::singleB) + a6 + + foo(::multiple, ::multiple) +} \ No newline at end of file diff --git a/compiler/testData/diagnostics/tests/callableReference/resolve/eagerAndPostponedCallableReferences.txt b/compiler/testData/diagnostics/tests/callableReference/resolve/eagerAndPostponedCallableReferences.txt new file mode 100644 index 00000000000..5890c1b645a --- /dev/null +++ b/compiler/testData/diagnostics/tests/callableReference/resolve/eagerAndPostponedCallableReferences.txt @@ -0,0 +1,20 @@ +package + +public fun foo(/*0*/ f: (T) -> kotlin.Unit, /*1*/ g: (T) -> kotlin.Unit): T +public fun multiple(/*0*/ a: A): kotlin.Unit +public fun multiple(/*0*/ b: B): kotlin.Unit +public fun singleA(/*0*/ a: A): kotlin.Unit +public fun singleB(/*0*/ a: B): kotlin.Unit +public fun test(): 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 { + 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/testData/diagnostics/tests/callableReference/resolve/eagerResolveOfSingleCallableReference.kt b/compiler/testData/diagnostics/tests/callableReference/resolve/eagerResolveOfSingleCallableReference.kt new file mode 100644 index 00000000000..02cc0659099 --- /dev/null +++ b/compiler/testData/diagnostics/tests/callableReference/resolve/eagerResolveOfSingleCallableReference.kt @@ -0,0 +1,15 @@ +// !LANGUAGE: -NewInference +// !DIAGNOSTICS: -UNUSED_PARAMETER + +open class A +class B : A() + +class Or(left: A, right: A) : A() + +class Out + +fun test(ls: Out) { + ls.reduce(::Or) +} + +fun Out.reduce(operation: (S, T) -> S): S = TODO() \ No newline at end of file diff --git a/compiler/testData/diagnostics/tests/callableReference/resolve/eagerResolveOfSingleCallableReference.txt b/compiler/testData/diagnostics/tests/callableReference/resolve/eagerResolveOfSingleCallableReference.txt new file mode 100644 index 00000000000..ce2926feedb --- /dev/null +++ b/compiler/testData/diagnostics/tests/callableReference/resolve/eagerResolveOfSingleCallableReference.txt @@ -0,0 +1,32 @@ +package + +public fun test(/*0*/ ls: Out): kotlin.Unit +public fun Out.reduce(/*0*/ operation: (S, T) -> S): S + +public open class A { + public constructor 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 final class B : A { + public constructor B() + 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 final class Or : A { + public constructor Or(/*0*/ left: A, /*1*/ right: 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 final class Out { + public constructor Out() + 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/testData/diagnostics/tests/callableReference/resolve/postponedResolveOfManyCallableReference.kt b/compiler/testData/diagnostics/tests/callableReference/resolve/postponedResolveOfManyCallableReference.kt new file mode 100644 index 00000000000..d63b58549f1 --- /dev/null +++ b/compiler/testData/diagnostics/tests/callableReference/resolve/postponedResolveOfManyCallableReference.kt @@ -0,0 +1,19 @@ +// !LANGUAGE: +NewInference +// !DIAGNOSTICS: -UNUSED_PARAMETER -UNUSED_VARIABLE + +interface A +interface B + +fun foo(i: A) {} +fun foo(b: B) {} + +fun bar1(f: (T) -> Unit): T = TODO() +fun bar2(f: (T) -> Unit, e: T) {} + +fun test(a: A, b: B) { + val expectedType1: A = bar1(::foo) + val expectedType2: B = bar1(::foo) + + bar2(::foo, a) + bar2(::foo, b) +} \ No newline at end of file diff --git a/compiler/testData/diagnostics/tests/callableReference/resolve/postponedResolveOfManyCallableReference.txt b/compiler/testData/diagnostics/tests/callableReference/resolve/postponedResolveOfManyCallableReference.txt new file mode 100644 index 00000000000..1cae90fa611 --- /dev/null +++ b/compiler/testData/diagnostics/tests/callableReference/resolve/postponedResolveOfManyCallableReference.txt @@ -0,0 +1,19 @@ +package + +public fun bar1(/*0*/ f: (T) -> kotlin.Unit): T +public fun bar2(/*0*/ f: (T) -> kotlin.Unit, /*1*/ e: T): kotlin.Unit +public fun foo(/*0*/ i: A): kotlin.Unit +public fun foo(/*0*/ b: B): kotlin.Unit +public fun test(/*0*/ a: A, /*1*/ b: B): 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 { + 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/testData/diagnostics/tests/inference/nothingType/nothingWithCallableReference.kt b/compiler/testData/diagnostics/tests/inference/nothingType/nothingWithCallableReference.kt index 33e9f9ffc45..5f2cd7c5e9a 100644 --- a/compiler/testData/diagnostics/tests/inference/nothingType/nothingWithCallableReference.kt +++ b/compiler/testData/diagnostics/tests/inference/nothingType/nothingWithCallableReference.kt @@ -16,17 +16,16 @@ fun test(f1: (Int) -> Unit, f2: kotlin.Function1) { select3(null, f1, ::bar) select3(null, f2, ::bar) - select3(null, f1, ::foo) - select3(null, f2, ::foo) + select3(null, f1, ::foo) + select3(null, f2, ::foo) dependantSelect2(null, ::foo) dependantSelect3(null, ::foo, ::cloneFoo) dependantSelect3(null, f1, ::bar) dependantSelect3(null, ::bar, f1) - // These errors are actually can be fixed (and, probably, should) if we force resolution of callable reference - dependantSelect3(null, ::foo, ::bar) - dependantSelect3(null, ::bar, ::foo) - dependantSelect3(null, f1, ::foo) - dependantSelect3(null, ::foo, f1) + dependantSelect3(null, ::foo, ::bar) + dependantSelect3(null, ::bar, ::foo) + dependantSelect3(null, f1, ::foo) + dependantSelect3(null, ::foo, f1) } diff --git a/compiler/tests/org/jetbrains/kotlin/checkers/DiagnosticsTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/checkers/DiagnosticsTestGenerated.java index 982e9d64d8f..fb1de81678c 100644 --- a/compiler/tests/org/jetbrains/kotlin/checkers/DiagnosticsTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/checkers/DiagnosticsTestGenerated.java @@ -2305,11 +2305,21 @@ public class DiagnosticsTestGenerated extends AbstractDiagnosticsTest { KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/diagnostics/tests/callableReference/resolve"), Pattern.compile("^(.*)\\.kts?$"), TargetBackend.ANY, true); } + @TestMetadata("ambiguityWhenNoApplicableCallableReferenceCandidate.kt") + public void testAmbiguityWhenNoApplicableCallableReferenceCandidate() throws Exception { + runTest("compiler/testData/diagnostics/tests/callableReference/resolve/ambiguityWhenNoApplicableCallableReferenceCandidate.kt"); + } + @TestMetadata("ambiguousWithVararg.kt") public void testAmbiguousWithVararg() throws Exception { runTest("compiler/testData/diagnostics/tests/callableReference/resolve/ambiguousWithVararg.kt"); } + @TestMetadata("applicableCallableReferenceFromDistantScope.kt") + public void testApplicableCallableReferenceFromDistantScope() throws Exception { + runTest("compiler/testData/diagnostics/tests/callableReference/resolve/applicableCallableReferenceFromDistantScope.kt"); + } + @TestMetadata("byArgType.kt") public void testByArgType() throws Exception { runTest("compiler/testData/diagnostics/tests/callableReference/resolve/byArgType.kt"); @@ -2325,11 +2335,31 @@ public class DiagnosticsTestGenerated extends AbstractDiagnosticsTest { runTest("compiler/testData/diagnostics/tests/callableReference/resolve/byValType.kt"); } + @TestMetadata("chooseOuterCallBySingleCallableReference.kt") + public void testChooseOuterCallBySingleCallableReference() throws Exception { + runTest("compiler/testData/diagnostics/tests/callableReference/resolve/chooseOuterCallBySingleCallableReference.kt"); + } + + @TestMetadata("commonSupertypeFromReturnTypesOfCallableReference.kt") + public void testCommonSupertypeFromReturnTypesOfCallableReference() throws Exception { + runTest("compiler/testData/diagnostics/tests/callableReference/resolve/commonSupertypeFromReturnTypesOfCallableReference.kt"); + } + @TestMetadata("constructor.kt") public void testConstructor() throws Exception { runTest("compiler/testData/diagnostics/tests/callableReference/resolve/constructor.kt"); } + @TestMetadata("eagerAndPostponedCallableReferences.kt") + public void testEagerAndPostponedCallableReferences() throws Exception { + runTest("compiler/testData/diagnostics/tests/callableReference/resolve/eagerAndPostponedCallableReferences.kt"); + } + + @TestMetadata("eagerResolveOfSingleCallableReference.kt") + public void testEagerResolveOfSingleCallableReference() throws Exception { + runTest("compiler/testData/diagnostics/tests/callableReference/resolve/eagerResolveOfSingleCallableReference.kt"); + } + @TestMetadata("innerClassConstructorOnOuterClassInstance.kt") public void testInnerClassConstructorOnOuterClassInstance() throws Exception { runTest("compiler/testData/diagnostics/tests/callableReference/resolve/innerClassConstructorOnOuterClassInstance.kt"); @@ -2400,6 +2430,11 @@ public class DiagnosticsTestGenerated extends AbstractDiagnosticsTest { runTest("compiler/testData/diagnostics/tests/callableReference/resolve/overloadsMember.kt"); } + @TestMetadata("postponedResolveOfManyCallableReference.kt") + public void testPostponedResolveOfManyCallableReference() throws Exception { + runTest("compiler/testData/diagnostics/tests/callableReference/resolve/postponedResolveOfManyCallableReference.kt"); + } + @TestMetadata("resolveEqualsOperatorWithAnyExpectedType.kt") public void testResolveEqualsOperatorWithAnyExpectedType() throws Exception { runTest("compiler/testData/diagnostics/tests/callableReference/resolve/resolveEqualsOperatorWithAnyExpectedType.kt"); diff --git a/compiler/tests/org/jetbrains/kotlin/checkers/javac/DiagnosticsUsingJavacTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/checkers/javac/DiagnosticsUsingJavacTestGenerated.java index c659e43ff0e..0a2b6897d01 100644 --- a/compiler/tests/org/jetbrains/kotlin/checkers/javac/DiagnosticsUsingJavacTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/checkers/javac/DiagnosticsUsingJavacTestGenerated.java @@ -2300,11 +2300,21 @@ public class DiagnosticsUsingJavacTestGenerated extends AbstractDiagnosticsUsing KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/diagnostics/tests/callableReference/resolve"), Pattern.compile("^(.+)\\.kt$"), TargetBackend.ANY, true); } + @TestMetadata("ambiguityWhenNoApplicableCallableReferenceCandidate.kt") + public void testAmbiguityWhenNoApplicableCallableReferenceCandidate() throws Exception { + runTest("compiler/testData/diagnostics/tests/callableReference/resolve/ambiguityWhenNoApplicableCallableReferenceCandidate.kt"); + } + @TestMetadata("ambiguousWithVararg.kt") public void testAmbiguousWithVararg() throws Exception { runTest("compiler/testData/diagnostics/tests/callableReference/resolve/ambiguousWithVararg.kt"); } + @TestMetadata("applicableCallableReferenceFromDistantScope.kt") + public void testApplicableCallableReferenceFromDistantScope() throws Exception { + runTest("compiler/testData/diagnostics/tests/callableReference/resolve/applicableCallableReferenceFromDistantScope.kt"); + } + @TestMetadata("byArgType.kt") public void testByArgType() throws Exception { runTest("compiler/testData/diagnostics/tests/callableReference/resolve/byArgType.kt"); @@ -2320,11 +2330,26 @@ public class DiagnosticsUsingJavacTestGenerated extends AbstractDiagnosticsUsing runTest("compiler/testData/diagnostics/tests/callableReference/resolve/byValType.kt"); } + @TestMetadata("commonSupertypeFromReturnTypesOfCallableReference.kt") + public void testCommonSupertypeFromReturnTypesOfCallableReference() throws Exception { + runTest("compiler/testData/diagnostics/tests/callableReference/resolve/commonSupertypeFromReturnTypesOfCallableReference.kt"); + } + @TestMetadata("constructor.kt") public void testConstructor() throws Exception { runTest("compiler/testData/diagnostics/tests/callableReference/resolve/constructor.kt"); } + @TestMetadata("eagerAndPostponedCallableReferences.kt") + public void testEagerAndPostponedCallableReferences() throws Exception { + runTest("compiler/testData/diagnostics/tests/callableReference/resolve/eagerAndPostponedCallableReferences.kt"); + } + + @TestMetadata("eagerResolveOfSingleCallableReference.kt") + public void testEagerResolveOfSingleCallableReference() throws Exception { + runTest("compiler/testData/diagnostics/tests/callableReference/resolve/eagerResolveOfSingleCallableReference.kt"); + } + @TestMetadata("innerClassConstructorOnOuterClassInstance.kt") public void testInnerClassConstructorOnOuterClassInstance() throws Exception { runTest("compiler/testData/diagnostics/tests/callableReference/resolve/innerClassConstructorOnOuterClassInstance.kt"); @@ -2395,6 +2420,11 @@ public class DiagnosticsUsingJavacTestGenerated extends AbstractDiagnosticsUsing runTest("compiler/testData/diagnostics/tests/callableReference/resolve/overloadsMember.kt"); } + @TestMetadata("postponedResolveOfManyCallableReference.kt") + public void testPostponedResolveOfManyCallableReference() throws Exception { + runTest("compiler/testData/diagnostics/tests/callableReference/resolve/postponedResolveOfManyCallableReference.kt"); + } + @TestMetadata("resolveEqualsOperatorWithAnyExpectedType.kt") public void testResolveEqualsOperatorWithAnyExpectedType() throws Exception { runTest("compiler/testData/diagnostics/tests/callableReference/resolve/resolveEqualsOperatorWithAnyExpectedType.kt");