From 676c99b933362aa735d89bca15207fad73a63ba8 Mon Sep 17 00:00:00 2001 From: Denis Zharkov Date: Wed, 15 Jan 2020 16:10:11 +0300 Subject: [PATCH] NI: Fix exception during callable references overload resolution ^KT-35847 Fixed --- .../FirOldFrontendDiagnosticsTestGenerated.java | 5 +++++ ...ntendDiagnosticsTestWithStdlibGenerated.java | 5 +++++ .../components/CallableReferenceResolver.kt | 5 ++++- .../resolve/calls/results/FlatSignature.kt | 6 +++++- .../ambiguityWithBoundExtensionReceiver.fir.kt | 15 +++++++++++++++ .../ambiguityWithBoundExtensionReceiver.kt | 15 +++++++++++++++ .../testsWithStdLib/inference/kt35847.fir.kt | 17 +++++++++++++++++ .../testsWithStdLib/inference/kt35847.kt | 17 +++++++++++++++++ .../checkers/DiagnosticsTestGenerated.java | 5 +++++ .../DiagnosticsTestWithStdLibGenerated.java | 5 +++++ ...osticsTestWithStdLibUsingJavacGenerated.java | 5 +++++ .../DiagnosticsUsingJavacTestGenerated.java | 5 +++++ .../jetbrains/kotlin/builtins/functionTypes.kt | 5 ++--- 13 files changed, 105 insertions(+), 5 deletions(-) create mode 100644 compiler/testData/diagnostics/tests/callableReference/resolve/ambiguityWithBoundExtensionReceiver.fir.kt create mode 100644 compiler/testData/diagnostics/tests/callableReference/resolve/ambiguityWithBoundExtensionReceiver.kt create mode 100644 compiler/testData/diagnostics/testsWithStdLib/inference/kt35847.fir.kt create mode 100644 compiler/testData/diagnostics/testsWithStdLib/inference/kt35847.kt diff --git a/compiler/fir/resolve/tests/org/jetbrains/kotlin/fir/FirOldFrontendDiagnosticsTestGenerated.java b/compiler/fir/resolve/tests/org/jetbrains/kotlin/fir/FirOldFrontendDiagnosticsTestGenerated.java index e083b71f35d..ce8c11576ba 100644 --- a/compiler/fir/resolve/tests/org/jetbrains/kotlin/fir/FirOldFrontendDiagnosticsTestGenerated.java +++ b/compiler/fir/resolve/tests/org/jetbrains/kotlin/fir/FirOldFrontendDiagnosticsTestGenerated.java @@ -2538,6 +2538,11 @@ public class FirOldFrontendDiagnosticsTestGenerated extends AbstractFirOldFronte runTest("compiler/testData/diagnostics/tests/callableReference/resolve/ambiguityWhenNoApplicableCallableReferenceCandidate.kt"); } + @TestMetadata("ambiguityWithBoundExtensionReceiver.kt") + public void testAmbiguityWithBoundExtensionReceiver() throws Exception { + runTest("compiler/testData/diagnostics/tests/callableReference/resolve/ambiguityWithBoundExtensionReceiver.kt"); + } + @TestMetadata("ambiguousWithVararg.kt") public void testAmbiguousWithVararg() throws Exception { runTest("compiler/testData/diagnostics/tests/callableReference/resolve/ambiguousWithVararg.kt"); diff --git a/compiler/fir/resolve/tests/org/jetbrains/kotlin/fir/FirOldFrontendDiagnosticsTestWithStdlibGenerated.java b/compiler/fir/resolve/tests/org/jetbrains/kotlin/fir/FirOldFrontendDiagnosticsTestWithStdlibGenerated.java index 9fb9a7d3e26..1c5f9823a08 100644 --- a/compiler/fir/resolve/tests/org/jetbrains/kotlin/fir/FirOldFrontendDiagnosticsTestWithStdlibGenerated.java +++ b/compiler/fir/resolve/tests/org/jetbrains/kotlin/fir/FirOldFrontendDiagnosticsTestWithStdlibGenerated.java @@ -1886,6 +1886,11 @@ public class FirOldFrontendDiagnosticsTestWithStdlibGenerated extends AbstractFi runTest("compiler/testData/diagnostics/testsWithStdLib/inference/kt3458.kt"); } + @TestMetadata("kt35847.kt") + public void testKt35847() throws Exception { + runTest("compiler/testData/diagnostics/testsWithStdLib/inference/kt35847.kt"); + } + @TestMetadata("kt4975.kt") public void testKt4975() throws Exception { runTest("compiler/testData/diagnostics/testsWithStdLib/inference/kt4975.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 c2aef4f7b85..a0eaf463f38 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 @@ -55,7 +55,10 @@ class CallableReferenceOverloadConflictResolver( ) { companion object { private fun createFlatSignature(candidate: CallableReferenceCandidate) = - FlatSignature.createFromReflectionType(candidate, candidate.candidate, candidate.numDefaults, candidate.reflectionCandidateType) + FlatSignature.createFromReflectionType( + candidate, candidate.candidate, candidate.numDefaults, hasBoundExtensionReceiver = candidate.extensionReceiver != null, + candidate.reflectionCandidateType + ) } } diff --git a/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/results/FlatSignature.kt b/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/results/FlatSignature.kt index 31e9887ef82..9fe7df4405b 100644 --- a/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/results/FlatSignature.kt +++ b/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/results/FlatSignature.kt @@ -59,6 +59,8 @@ class FlatSignature constructor( origin: T, descriptor: CallableDescriptor, numDefaults: Int, + // Reflection type for callable references with bound receiver doesn't contain receiver type + hasBoundExtensionReceiver: Boolean, reflectionType: UnwrappedType ): FlatSignature { // Note that receiver is taking over descriptor, not reflection type @@ -66,7 +68,9 @@ class FlatSignature constructor( // 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 } + val parameters = reflectionType.getValueParameterTypesFromCallableReflectionType( + receiver != null && !hasBoundExtensionReceiver + ).map { it.type } return FlatSignature( origin, diff --git a/compiler/testData/diagnostics/tests/callableReference/resolve/ambiguityWithBoundExtensionReceiver.fir.kt b/compiler/testData/diagnostics/tests/callableReference/resolve/ambiguityWithBoundExtensionReceiver.fir.kt new file mode 100644 index 00000000000..3529dca196d --- /dev/null +++ b/compiler/testData/diagnostics/tests/callableReference/resolve/ambiguityWithBoundExtensionReceiver.fir.kt @@ -0,0 +1,15 @@ +// SKIP_TXT +// !LANGUAGE: +NewInference +// !DIAGNOSTICS: -UNUSED_PARAMETER +// !CHECK_TYPE + +fun bar(f: () -> R): R = TODO() + +fun Any.foo() = 1 +fun A.foo() = "" + +class A { + fun main() { + bar(::foo) checkType { _() } + } +} diff --git a/compiler/testData/diagnostics/tests/callableReference/resolve/ambiguityWithBoundExtensionReceiver.kt b/compiler/testData/diagnostics/tests/callableReference/resolve/ambiguityWithBoundExtensionReceiver.kt new file mode 100644 index 00000000000..62e99f697ce --- /dev/null +++ b/compiler/testData/diagnostics/tests/callableReference/resolve/ambiguityWithBoundExtensionReceiver.kt @@ -0,0 +1,15 @@ +// SKIP_TXT +// !LANGUAGE: +NewInference +// !DIAGNOSTICS: -UNUSED_PARAMETER +// !CHECK_TYPE + +fun bar(f: () -> R): R = TODO() + +fun Any.foo() = 1 +fun A.foo() = "" + +class A { + fun main() { + bar(::foo) checkType { _() } + } +} diff --git a/compiler/testData/diagnostics/testsWithStdLib/inference/kt35847.fir.kt b/compiler/testData/diagnostics/testsWithStdLib/inference/kt35847.fir.kt new file mode 100644 index 00000000000..cd6154e7026 --- /dev/null +++ b/compiler/testData/diagnostics/testsWithStdLib/inference/kt35847.fir.kt @@ -0,0 +1,17 @@ +// SKIP_TXT +// !LANGUAGE: +NewInference +// !DIAGNOSTICS: -UNUSED_PARAMETER + +import kotlin.reflect.KProperty1 +import kotlin.reflect.KFunction1 + +fun has(property: KFunction1) = null +fun has(property: KProperty1) = null + +fun toInt(s: String) = 10 + +object A { + fun main() { + has(::toInt) // throwing an exception here + } +} diff --git a/compiler/testData/diagnostics/testsWithStdLib/inference/kt35847.kt b/compiler/testData/diagnostics/testsWithStdLib/inference/kt35847.kt new file mode 100644 index 00000000000..cd6154e7026 --- /dev/null +++ b/compiler/testData/diagnostics/testsWithStdLib/inference/kt35847.kt @@ -0,0 +1,17 @@ +// SKIP_TXT +// !LANGUAGE: +NewInference +// !DIAGNOSTICS: -UNUSED_PARAMETER + +import kotlin.reflect.KProperty1 +import kotlin.reflect.KFunction1 + +fun has(property: KFunction1) = null +fun has(property: KProperty1) = null + +fun toInt(s: String) = 10 + +object A { + fun main() { + has(::toInt) // throwing an exception here + } +} diff --git a/compiler/tests/org/jetbrains/kotlin/checkers/DiagnosticsTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/checkers/DiagnosticsTestGenerated.java index aafd7625de7..2d01b9801b0 100644 --- a/compiler/tests/org/jetbrains/kotlin/checkers/DiagnosticsTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/checkers/DiagnosticsTestGenerated.java @@ -2545,6 +2545,11 @@ public class DiagnosticsTestGenerated extends AbstractDiagnosticsTest { runTest("compiler/testData/diagnostics/tests/callableReference/resolve/ambiguityWhenNoApplicableCallableReferenceCandidate.kt"); } + @TestMetadata("ambiguityWithBoundExtensionReceiver.kt") + public void testAmbiguityWithBoundExtensionReceiver() throws Exception { + runTest("compiler/testData/diagnostics/tests/callableReference/resolve/ambiguityWithBoundExtensionReceiver.kt"); + } + @TestMetadata("ambiguousWithVararg.kt") public void testAmbiguousWithVararg() throws Exception { runTest("compiler/testData/diagnostics/tests/callableReference/resolve/ambiguousWithVararg.kt"); diff --git a/compiler/tests/org/jetbrains/kotlin/checkers/DiagnosticsTestWithStdLibGenerated.java b/compiler/tests/org/jetbrains/kotlin/checkers/DiagnosticsTestWithStdLibGenerated.java index bb45abb3acf..866b0426e9f 100644 --- a/compiler/tests/org/jetbrains/kotlin/checkers/DiagnosticsTestWithStdLibGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/checkers/DiagnosticsTestWithStdLibGenerated.java @@ -2821,6 +2821,11 @@ public class DiagnosticsTestWithStdLibGenerated extends AbstractDiagnosticsTestW runTest("compiler/testData/diagnostics/testsWithStdLib/inference/kt3458.kt"); } + @TestMetadata("kt35847.kt") + public void testKt35847() throws Exception { + runTest("compiler/testData/diagnostics/testsWithStdLib/inference/kt35847.kt"); + } + @TestMetadata("kt4975.kt") public void testKt4975() throws Exception { runTest("compiler/testData/diagnostics/testsWithStdLib/inference/kt4975.kt"); diff --git a/compiler/tests/org/jetbrains/kotlin/checkers/javac/DiagnosticsTestWithStdLibUsingJavacGenerated.java b/compiler/tests/org/jetbrains/kotlin/checkers/javac/DiagnosticsTestWithStdLibUsingJavacGenerated.java index a26d6710092..900cf8c7ada 100644 --- a/compiler/tests/org/jetbrains/kotlin/checkers/javac/DiagnosticsTestWithStdLibUsingJavacGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/checkers/javac/DiagnosticsTestWithStdLibUsingJavacGenerated.java @@ -2821,6 +2821,11 @@ public class DiagnosticsTestWithStdLibUsingJavacGenerated extends AbstractDiagno runTest("compiler/testData/diagnostics/testsWithStdLib/inference/kt3458.kt"); } + @TestMetadata("kt35847.kt") + public void testKt35847() throws Exception { + runTest("compiler/testData/diagnostics/testsWithStdLib/inference/kt35847.kt"); + } + @TestMetadata("kt4975.kt") public void testKt4975() throws Exception { runTest("compiler/testData/diagnostics/testsWithStdLib/inference/kt4975.kt"); diff --git a/compiler/tests/org/jetbrains/kotlin/checkers/javac/DiagnosticsUsingJavacTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/checkers/javac/DiagnosticsUsingJavacTestGenerated.java index e13497ce314..6702cd25d43 100644 --- a/compiler/tests/org/jetbrains/kotlin/checkers/javac/DiagnosticsUsingJavacTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/checkers/javac/DiagnosticsUsingJavacTestGenerated.java @@ -2540,6 +2540,11 @@ public class DiagnosticsUsingJavacTestGenerated extends AbstractDiagnosticsUsing runTest("compiler/testData/diagnostics/tests/callableReference/resolve/ambiguityWhenNoApplicableCallableReferenceCandidate.kt"); } + @TestMetadata("ambiguityWithBoundExtensionReceiver.kt") + public void testAmbiguityWithBoundExtensionReceiver() throws Exception { + runTest("compiler/testData/diagnostics/tests/callableReference/resolve/ambiguityWithBoundExtensionReceiver.kt"); + } + @TestMetadata("ambiguousWithVararg.kt") public void testAmbiguousWithVararg() throws Exception { runTest("compiler/testData/diagnostics/tests/callableReference/resolve/ambiguousWithVararg.kt"); diff --git a/core/descriptors/src/org/jetbrains/kotlin/builtins/functionTypes.kt b/core/descriptors/src/org/jetbrains/kotlin/builtins/functionTypes.kt index 534ef21b06e..a7815568b43 100644 --- a/core/descriptors/src/org/jetbrains/kotlin/builtins/functionTypes.kt +++ b/core/descriptors/src/org/jetbrains/kotlin/builtins/functionTypes.kt @@ -21,7 +21,6 @@ import org.jetbrains.kotlin.types.typeUtil.asTypeProjection import org.jetbrains.kotlin.types.typeUtil.replaceAnnotations import org.jetbrains.kotlin.utils.DFS import org.jetbrains.kotlin.utils.addIfNotNull -import org.jetbrains.kotlin.utils.addToStdlib.safeAs import java.util.* private fun KotlinType.isTypeOrSubtypeOf(predicate: (KotlinType) -> Boolean): Boolean = @@ -140,10 +139,10 @@ fun KotlinType.getValueParameterTypesFromFunctionType(): List { return arguments.subList(first, last) } -fun KotlinType.getValueParameterTypesFromCallableReflectionType(withReceiver: Boolean): List { +fun KotlinType.getValueParameterTypesFromCallableReflectionType(isCallableTypeWithExtension: Boolean): List { assert(ReflectionTypes.isKCallableType(this)) { "Not a callable reflection type: $this" } val arguments = arguments - val first = if (withReceiver) 0 else 1 + val first = if (isCallableTypeWithExtension) 1 else 0 val last = arguments.size - 1 assert(first <= last) { "Not an exact function type: $this" } return arguments.subList(first, last)