[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:
Mikhail Zarechenskiy
2019-04-05 12:39:34 +03:00
parent c3bc6ef2fa
commit ff2ce316e1
10 changed files with 86 additions and 11 deletions
@@ -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");
@@ -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
@@ -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
)
}
@@ -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
@@ -213,6 +213,7 @@ enum class KotlinCallKind(vararg resolutionPart: ResolutionPart) {
CheckReceivers,
CheckArgumentsInParenthesis,
CheckExternalArgument,
EagerResolveOfCallableReferences,
PostponedVariablesInitializerResolutionPart
),
INVOKE(*FUNCTION.resolutionSequence.toTypedArray()),
@@ -95,6 +95,8 @@ class KotlinResolutionCandidate(
currentApplicability = maxOf(diagnostic.candidateApplicability, currentApplicability)
}
fun getSubResolvedAtoms(): List<ResolvedAtom> = subResolvedAtoms
fun addResolvedKtPrimitive(resolvedAtom: ResolvedAtom) {
subResolvedAtoms.add(resolvedAtom)
}
@@ -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)
}
@@ -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");
@@ -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");