[NI] Resolve callable reference eagerly at the end of resolution parts
This way we'll resolve less callable references later as we'll have more constraints to clip wrong candidates for callable references
This commit is contained in:
+10
@@ -2328,6 +2328,11 @@ public class FirDiagnosticsSmokeTestGenerated extends AbstractFirDiagnosticsSmok
|
||||
runTest("compiler/testData/diagnostics/tests/callableReference/resolve/byValType.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("chooseCallableReferenceDependingOnInferredReceiver.kt")
|
||||
public void testChooseCallableReferenceDependingOnInferredReceiver() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/tests/callableReference/resolve/chooseCallableReferenceDependingOnInferredReceiver.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("chooseOuterCallBySingleCallableReference.kt")
|
||||
public void testChooseOuterCallBySingleCallableReference() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/tests/callableReference/resolve/chooseOuterCallBySingleCallableReference.kt");
|
||||
@@ -2433,6 +2438,11 @@ public class FirDiagnosticsSmokeTestGenerated extends AbstractFirDiagnosticsSmok
|
||||
runTest("compiler/testData/diagnostics/tests/callableReference/resolve/postponedResolveOfManyCallableReference.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("resolveCallableReferencesAfterAllSimpleArguments.kt")
|
||||
public void testResolveCallableReferencesAfterAllSimpleArguments() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/tests/callableReference/resolve/resolveCallableReferencesAfterAllSimpleArguments.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("resolveEqualsOperatorWithAnyExpectedType.kt")
|
||||
public void testResolveEqualsOperatorWithAnyExpectedType() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/tests/callableReference/resolve/resolveEqualsOperatorWithAnyExpectedType.kt");
|
||||
|
||||
+1
-4
@@ -29,7 +29,6 @@ import org.jetbrains.kotlin.utils.addToStdlib.safeAs
|
||||
|
||||
fun resolveKtPrimitive(
|
||||
csBuilder: ConstraintSystemBuilder,
|
||||
callableReferenceResolver: CallableReferenceResolver,
|
||||
argument: KotlinCallArgument,
|
||||
expectedType: UnwrappedType?,
|
||||
diagnosticsHolder: KotlinDiagnosticsHolder,
|
||||
@@ -42,7 +41,7 @@ fun resolveKtPrimitive(
|
||||
preprocessLambdaArgument(csBuilder, argument, expectedType)
|
||||
|
||||
is CallableReferenceKotlinCallArgument ->
|
||||
preprocessCallableReference(csBuilder, callableReferenceResolver, argument, expectedType, diagnosticsHolder)
|
||||
preprocessCallableReference(csBuilder, argument, expectedType, diagnosticsHolder)
|
||||
|
||||
is CollectionLiteralKotlinCallArgument ->
|
||||
preprocessCollectionLiteralArgument(argument, expectedType)
|
||||
@@ -142,13 +141,11 @@ fun LambdaWithTypeVariableAsExpectedTypeAtom.transformToResolvedLambda(csBuilder
|
||||
|
||||
private fun preprocessCallableReference(
|
||||
csBuilder: ConstraintSystemBuilder,
|
||||
callableReferenceResolver: CallableReferenceResolver,
|
||||
argument: CallableReferenceKotlinCallArgument,
|
||||
expectedType: UnwrappedType?,
|
||||
diagnosticsHolder: KotlinDiagnosticsHolder
|
||||
): ResolvedAtom {
|
||||
val result = EagerCallableReferenceAtom(argument, expectedType)
|
||||
callableReferenceResolver.processCallableReferenceArgument(csBuilder, result, diagnosticsHolder)
|
||||
|
||||
if (expectedType == null) return result
|
||||
|
||||
|
||||
+1
-1
@@ -94,7 +94,7 @@ class PostponedArgumentsAnalyzer(
|
||||
|
||||
val subResolvedKtPrimitives = returnArguments.map {
|
||||
resolveKtPrimitive(
|
||||
c.getBuilder(), callableReferenceResolver, it, lambda.returnType.let(::substitute), diagnosticHolder, isReceiver = false
|
||||
c.getBuilder(), it, lambda.returnType.let(::substitute), diagnosticHolder, isReceiver = false
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
+17
-6
@@ -5,15 +5,18 @@
|
||||
|
||||
package org.jetbrains.kotlin.resolve.calls.components
|
||||
|
||||
import org.jetbrains.kotlin.builtins.getReceiverTypeFromFunctionType
|
||||
import org.jetbrains.kotlin.builtins.functions.FunctionClassDescriptor
|
||||
import org.jetbrains.kotlin.builtins.getFunctionalClassKind
|
||||
import org.jetbrains.kotlin.builtins.getReceiverTypeFromFunctionType
|
||||
import org.jetbrains.kotlin.descriptors.*
|
||||
import org.jetbrains.kotlin.descriptors.impl.TypeAliasConstructorDescriptor
|
||||
import org.jetbrains.kotlin.resolve.calls.components.TypeArgumentsToParametersMapper.TypeArgumentsMapping.NoExplicitArguments
|
||||
import org.jetbrains.kotlin.resolve.calls.inference.ConstraintSystemOperation
|
||||
import org.jetbrains.kotlin.resolve.calls.inference.components.FreshVariableNewTypeSubstitutor
|
||||
import org.jetbrains.kotlin.resolve.calls.inference.model.*
|
||||
import org.jetbrains.kotlin.resolve.calls.inference.model.DeclaredUpperBoundConstraintPosition
|
||||
import org.jetbrains.kotlin.resolve.calls.inference.model.ExplicitTypeParameterConstraintPosition
|
||||
import org.jetbrains.kotlin.resolve.calls.inference.model.KnownTypeParameterConstraintPosition
|
||||
import org.jetbrains.kotlin.resolve.calls.inference.model.TypeVariableFromCallableDescriptor
|
||||
import org.jetbrains.kotlin.resolve.calls.inference.substitute
|
||||
import org.jetbrains.kotlin.resolve.calls.model.*
|
||||
import org.jetbrains.kotlin.resolve.calls.smartcasts.getReceiverValueWithSmartCast
|
||||
@@ -23,9 +26,9 @@ import org.jetbrains.kotlin.resolve.calls.tower.InvokeConventionCallNoOperatorMo
|
||||
import org.jetbrains.kotlin.resolve.calls.tower.VisibilityError
|
||||
import org.jetbrains.kotlin.types.ErrorUtils
|
||||
import org.jetbrains.kotlin.types.KotlinType
|
||||
import org.jetbrains.kotlin.types.typeUtil.contains
|
||||
import org.jetbrains.kotlin.types.UnwrappedType
|
||||
import org.jetbrains.kotlin.types.checker.anySuperTypeConstructor
|
||||
import org.jetbrains.kotlin.types.typeUtil.contains
|
||||
import org.jetbrains.kotlin.utils.addToStdlib.safeAs
|
||||
|
||||
internal object CheckInstantiationOfAbstractClass : ResolutionPart() {
|
||||
@@ -275,9 +278,7 @@ private fun KotlinResolutionCandidate.resolveKotlinArgument(
|
||||
isReceiver: Boolean
|
||||
) {
|
||||
val expectedType = candidateParameter?.let { prepareExpectedType(argument, candidateParameter) }
|
||||
addResolvedKtPrimitive(
|
||||
resolveKtPrimitive(csBuilder, callableReferenceResolver, argument, expectedType, this, isReceiver)
|
||||
)
|
||||
addResolvedKtPrimitive(resolveKtPrimitive(csBuilder, argument, expectedType, this, isReceiver))
|
||||
}
|
||||
|
||||
private fun KotlinResolutionCandidate.prepareExpectedType(
|
||||
@@ -368,6 +369,16 @@ internal object CheckExternalArgument : ResolutionPart() {
|
||||
}
|
||||
}
|
||||
|
||||
internal object EagerResolveOfCallableReferences : ResolutionPart() {
|
||||
override fun KotlinResolutionCandidate.process(workIndex: Int) {
|
||||
getSubResolvedAtoms()
|
||||
.filterIsInstance<EagerCallableReferenceAtom>()
|
||||
.forEach {
|
||||
callableReferenceResolver.processCallableReferenceArgument(csBuilder, it, this)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
internal object CheckInfixResolutionPart : ResolutionPart() {
|
||||
override fun KotlinResolutionCandidate.process(workIndex: Int) {
|
||||
val candidateDescriptor = resolvedCall.candidateDescriptor
|
||||
|
||||
+1
@@ -213,6 +213,7 @@ enum class KotlinCallKind(vararg resolutionPart: ResolutionPart) {
|
||||
CheckReceivers,
|
||||
CheckArgumentsInParenthesis,
|
||||
CheckExternalArgument,
|
||||
EagerResolveOfCallableReferences,
|
||||
PostponedVariablesInitializerResolutionPart
|
||||
),
|
||||
INVOKE(*FUNCTION.resolutionSequence.toTypedArray()),
|
||||
|
||||
+2
@@ -95,6 +95,8 @@ class KotlinResolutionCandidate(
|
||||
currentApplicability = maxOf(diagnostic.candidateApplicability, currentApplicability)
|
||||
}
|
||||
|
||||
fun getSubResolvedAtoms(): List<ResolvedAtom> = subResolvedAtoms
|
||||
|
||||
fun addResolvedKtPrimitive(resolvedAtom: ResolvedAtom) {
|
||||
subResolvedAtoms.add(resolvedAtom)
|
||||
}
|
||||
|
||||
+16
@@ -0,0 +1,16 @@
|
||||
// !LANGUAGE: +NewInference
|
||||
// !DIAGNOSTICS: -UNUSED_PARAMETER
|
||||
|
||||
interface A
|
||||
interface B
|
||||
|
||||
fun fooB(b: B) {}
|
||||
|
||||
fun <T> bar(f: (T) -> Unit, e: T) {}
|
||||
fun <T> baz(e: T, f: (T) -> Unit) {}
|
||||
|
||||
fun test(a: A, b: B) {
|
||||
// Note that diagnostic is always on callable references as they are resolved after simple arguments
|
||||
baz(a, <!TYPE_MISMATCH!>::fooB<!>)
|
||||
bar(<!TYPE_MISMATCH!>::fooB<!>, a)
|
||||
}
|
||||
+18
@@ -0,0 +1,18 @@
|
||||
package
|
||||
|
||||
public fun </*0*/ T> bar(/*0*/ f: (T) -> kotlin.Unit, /*1*/ e: T): kotlin.Unit
|
||||
public fun </*0*/ T> baz(/*0*/ e: T, /*1*/ f: (T) -> kotlin.Unit): kotlin.Unit
|
||||
public fun fooB(/*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
|
||||
}
|
||||
@@ -2335,6 +2335,11 @@ public class DiagnosticsTestGenerated extends AbstractDiagnosticsTest {
|
||||
runTest("compiler/testData/diagnostics/tests/callableReference/resolve/byValType.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("chooseCallableReferenceDependingOnInferredReceiver.kt")
|
||||
public void testChooseCallableReferenceDependingOnInferredReceiver() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/tests/callableReference/resolve/chooseCallableReferenceDependingOnInferredReceiver.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("chooseOuterCallBySingleCallableReference.kt")
|
||||
public void testChooseOuterCallBySingleCallableReference() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/tests/callableReference/resolve/chooseOuterCallBySingleCallableReference.kt");
|
||||
@@ -2440,6 +2445,11 @@ public class DiagnosticsTestGenerated extends AbstractDiagnosticsTest {
|
||||
runTest("compiler/testData/diagnostics/tests/callableReference/resolve/postponedResolveOfManyCallableReference.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("resolveCallableReferencesAfterAllSimpleArguments.kt")
|
||||
public void testResolveCallableReferencesAfterAllSimpleArguments() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/tests/callableReference/resolve/resolveCallableReferencesAfterAllSimpleArguments.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("resolveEqualsOperatorWithAnyExpectedType.kt")
|
||||
public void testResolveEqualsOperatorWithAnyExpectedType() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/tests/callableReference/resolve/resolveEqualsOperatorWithAnyExpectedType.kt");
|
||||
|
||||
Generated
+10
@@ -2330,6 +2330,11 @@ public class DiagnosticsUsingJavacTestGenerated extends AbstractDiagnosticsUsing
|
||||
runTest("compiler/testData/diagnostics/tests/callableReference/resolve/byValType.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("chooseCallableReferenceDependingOnInferredReceiver.kt")
|
||||
public void testChooseCallableReferenceDependingOnInferredReceiver() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/tests/callableReference/resolve/chooseCallableReferenceDependingOnInferredReceiver.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("chooseOuterCallBySingleCallableReference.kt")
|
||||
public void testChooseOuterCallBySingleCallableReference() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/tests/callableReference/resolve/chooseOuterCallBySingleCallableReference.kt");
|
||||
@@ -2435,6 +2440,11 @@ public class DiagnosticsUsingJavacTestGenerated extends AbstractDiagnosticsUsing
|
||||
runTest("compiler/testData/diagnostics/tests/callableReference/resolve/postponedResolveOfManyCallableReference.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("resolveCallableReferencesAfterAllSimpleArguments.kt")
|
||||
public void testResolveCallableReferencesAfterAllSimpleArguments() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/tests/callableReference/resolve/resolveCallableReferencesAfterAllSimpleArguments.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("resolveEqualsOperatorWithAnyExpectedType.kt")
|
||||
public void testResolveEqualsOperatorWithAnyExpectedType() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/tests/callableReference/resolve/resolveEqualsOperatorWithAnyExpectedType.kt");
|
||||
|
||||
Reference in New Issue
Block a user