FIR: Refine callable reference resolution in assignment position

synthetic_select<() -> T>(::foo) form allows to select better candidate
than synthetic_select(::foo) with expect type `() -> T`
This commit is contained in:
Denis.Zharkov
2021-11-08 12:00:19 +03:00
committed by teamcity
parent 65d7da122f
commit 6e15ee8fea
14 changed files with 83 additions and 20 deletions
@@ -11,7 +11,7 @@ package testsCase1
class Case() {
fun case(v: V) {
// InitializerTypeMismatchChecker bug
val va: () -> String = <!INITIALIZER_TYPE_MISMATCH!>(V)::a<!>
val va: () -> String = (V)::a
val vb: () -> String = (V)::b
@@ -2603,6 +2603,12 @@ public class FirOldFrontendDiagnosticsTestGenerated extends AbstractFirDiagnosti
runTest("compiler/testData/diagnostics/tests/callableReference/callableReferenceAsLastExpressionInBlock.kt");
}
@Test
@TestMetadata("callableReferenceAssignmentToVar.kt")
public void testCallableReferenceAssignmentToVar() throws Exception {
runTest("compiler/testData/diagnostics/tests/callableReference/callableReferenceAssignmentToVar.kt");
}
@Test
@TestMetadata("classVsPackage.kt")
public void testClassVsPackage() throws Exception {
@@ -2603,6 +2603,12 @@ public class FirOldFrontendDiagnosticsWithLightTreeTestGenerated extends Abstrac
runTest("compiler/testData/diagnostics/tests/callableReference/callableReferenceAsLastExpressionInBlock.kt");
}
@Test
@TestMetadata("callableReferenceAssignmentToVar.kt")
public void testCallableReferenceAssignmentToVar() throws Exception {
runTest("compiler/testData/diagnostics/tests/callableReference/callableReferenceAssignmentToVar.kt");
}
@Test
@TestMetadata("classVsPackage.kt")
public void testClassVsPackage() throws Exception {
@@ -80,7 +80,7 @@ sealed class CallKind(vararg resolutionSequence: ResolutionStage) {
object SyntheticIdForCallableReferencesResolution : CallKind(
MapArguments,
NoTypeArguments,
MapTypeArguments,
CreateFreshTypeVariableSubstitutorStage,
CollectTypeVariableUsagesInfo,
CheckArguments,
@@ -151,6 +151,17 @@ class FirSyntheticCallGenerator(
): FirCallableReferenceAccess? {
val argumentList = buildUnaryArgumentList(callableReferenceAccess)
val typeArguments =
when {
expectedTypeRef is FirResolvedTypeRef && !expectedTypeRef.coneType.isUnitOrFlexibleUnit -> listOf(
buildTypeProjectionWithVariance {
variance = Variance.INVARIANT
typeRef = expectedTypeRef
}
)
else -> emptyList()
}
val reference =
generateCalleeReferenceWithCandidate(
callableReferenceAccess,
@@ -158,7 +169,8 @@ class FirSyntheticCallGenerator(
argumentList,
SyntheticCallableId.ID.callableName,
CallKind.SyntheticIdForCallableReferencesResolution,
context
context,
typeArguments,
)
val fakeCallElement = buildFunctionCall {
calleeReference = reference
@@ -175,9 +187,10 @@ class FirSyntheticCallGenerator(
argumentList: FirArgumentList,
name: Name,
callKind: CallKind = CallKind.SyntheticSelect,
context: ResolutionContext
context: ResolutionContext,
typeArguments: List<FirTypeProjection> = emptyList()
): FirNamedReferenceWithCandidate {
val callInfo = generateCallInfo(callSite, name, argumentList, callKind)
val callInfo = generateCallInfo(callSite, name, argumentList, callKind, typeArguments)
val candidate = generateCandidate(callInfo, function, context)
val applicability = components.resolutionStageRunner.processCandidate(candidate, context)
if (applicability <= CandidateApplicability.INAPPLICABLE) {
@@ -203,14 +216,20 @@ class FirSyntheticCallGenerator(
)
}
private fun generateCallInfo(callSite: FirExpression, name: Name, argumentList: FirArgumentList, callKind: CallKind) = CallInfo(
private fun generateCallInfo(
callSite: FirExpression,
name: Name,
argumentList: FirArgumentList,
callKind: CallKind,
typeArguments: List<FirTypeProjection> = emptyList()
) = CallInfo(
callSite = callSite,
callKind = callKind,
name = name,
explicitReceiver = null,
argumentList = argumentList,
isImplicitInvoke = false,
typeArguments = emptyList(),
typeArguments = typeArguments,
session = session,
containingFile = components.file,
containingDeclarations = components.containingDeclarations