[FIR] Support @LowPriorityInOverloadResolution annotation
This commit is contained in:
@@ -12,7 +12,8 @@ enum class CallKind(vararg resolutionSequence: ResolutionStage) {
|
||||
CheckExplicitReceiverConsistency,
|
||||
CreateFreshTypeVariableSubstitutorStage,
|
||||
CheckReceivers.Dispatch,
|
||||
CheckReceivers.Extension
|
||||
CheckReceivers.Extension,
|
||||
CheckLowPriorityInOverloadResolution
|
||||
),
|
||||
SyntheticSelect(
|
||||
MapArguments,
|
||||
@@ -29,7 +30,8 @@ enum class CallKind(vararg resolutionSequence: ResolutionStage) {
|
||||
CheckReceivers.Dispatch,
|
||||
CheckReceivers.Extension,
|
||||
CheckArguments,
|
||||
EagerResolveOfCallableReferences
|
||||
EagerResolveOfCallableReferences,
|
||||
CheckLowPriorityInOverloadResolution
|
||||
),
|
||||
CallableReference(
|
||||
CheckVisibility,
|
||||
|
||||
@@ -71,6 +71,7 @@ enum class CandidateApplicability {
|
||||
PARAMETER_MAPPING_ERROR,
|
||||
INAPPLICABLE,
|
||||
SYNTHETIC_RESOLVED,
|
||||
RESOLVED_LOW_PRIORITY,
|
||||
RESOLVED
|
||||
}
|
||||
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
package org.jetbrains.kotlin.fir.resolve.calls
|
||||
|
||||
import org.jetbrains.kotlin.descriptors.Visibilities
|
||||
import org.jetbrains.kotlin.fir.FirAnnotationContainer
|
||||
import org.jetbrains.kotlin.fir.FirSession
|
||||
import org.jetbrains.kotlin.fir.declarations.*
|
||||
import org.jetbrains.kotlin.fir.expressions.FirExpression
|
||||
@@ -26,6 +27,7 @@ import org.jetbrains.kotlin.fir.types.*
|
||||
import org.jetbrains.kotlin.load.java.JavaVisibilities
|
||||
import org.jetbrains.kotlin.name.ClassId
|
||||
import org.jetbrains.kotlin.name.FqName
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
import org.jetbrains.kotlin.resolve.calls.inference.ConstraintSystemOperation
|
||||
import org.jetbrains.kotlin.resolve.calls.inference.model.SimpleConstraintSystemConstraintPosition
|
||||
import org.jetbrains.kotlin.resolve.calls.tasks.ExplicitReceiverKind
|
||||
@@ -472,3 +474,24 @@ internal object CheckVisibility : CheckerStage() {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
internal object CheckLowPriorityInOverloadResolution : CheckerStage() {
|
||||
private val LOW_PRIORITY_IN_OVERLOAD_RESOLUTION_CLASS_ID: ClassId =
|
||||
ClassId(FqName("kotlin.internal"), Name.identifier("LowPriorityInOverloadResolution"))
|
||||
|
||||
override suspend fun check(candidate: Candidate, sink: CheckerSink, callInfo: CallInfo) {
|
||||
val annotations = when (val fir = candidate.symbol.fir) {
|
||||
is FirSimpleFunction -> fir.annotations
|
||||
is FirProperty -> fir.annotations
|
||||
else -> return
|
||||
}
|
||||
val hasLowPriorityAnnotation = annotations.any {
|
||||
val lookupTag = ((it.annotationTypeRef as? FirResolvedTypeRef)?.type as? ConeClassLikeType)?.lookupTag ?: return@any false
|
||||
lookupTag.classId == LOW_PRIORITY_IN_OVERLOAD_RESOLUTION_CLASS_ID
|
||||
}
|
||||
|
||||
if (hasLowPriorityAnnotation) {
|
||||
sink.reportApplicability(CandidateApplicability.RESOLVED_LOW_PRIORITY)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,10 @@
|
||||
@Suppress("INVISIBLE_MEMBER", "INVISIBLE_REFERENCE")
|
||||
@kotlin.internal.LowPriorityInOverloadResolution
|
||||
fun foo(): Int = 1
|
||||
|
||||
fun foo(): String = ""
|
||||
|
||||
fun test() {
|
||||
val s = foo()
|
||||
s.length
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
FILE: lowPriorityInResolution.kt
|
||||
@R|kotlin/Suppress|(String(INVISIBLE_MEMBER), String(INVISIBLE_REFERENCE)) @R|kotlin/internal/LowPriorityInOverloadResolution|() public final fun foo(): R|kotlin/Int| {
|
||||
^foo Int(1)
|
||||
}
|
||||
public final fun foo(): R|kotlin/String| {
|
||||
^foo String()
|
||||
}
|
||||
public final fun test(): R|kotlin/Unit| {
|
||||
lval s: R|kotlin/String| = R|/foo|()
|
||||
R|<local>/s|.R|kotlin/String.length|
|
||||
}
|
||||
Generated
+5
@@ -163,6 +163,11 @@ public class FirDiagnosticsWithStdlibTestGenerated extends AbstractFirDiagnostic
|
||||
runTest("compiler/fir/resolve/testData/resolveWithStdlib/listPlusAssign.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("lowPriorityInResolution.kt")
|
||||
public void testLowPriorityInResolution() throws Exception {
|
||||
runTest("compiler/fir/resolve/testData/resolveWithStdlib/lowPriorityInResolution.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("mapList.kt")
|
||||
public void testMapList() throws Exception {
|
||||
runTest("compiler/fir/resolve/testData/resolveWithStdlib/mapList.kt");
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
// IGNORE_BACKEND_FIR: JVM_IR
|
||||
// WITH_RUNTIME
|
||||
|
||||
@Suppress("INVISIBLE_MEMBER", "INVISIBLE_REFERENCE")
|
||||
|
||||
+2
-2
@@ -11,6 +11,6 @@ public fun <T> Iterable<T>.contains1(element: @kotlin.internal.NoInfer T): Boole
|
||||
|
||||
|
||||
fun test() {
|
||||
val a: Boolean = listOf(1).<!AMBIGUITY!>contains1<!>("")
|
||||
val b: Boolean = listOf(1).<!AMBIGUITY!>contains1<!>(1)
|
||||
val a: Boolean = listOf(1).contains1("")
|
||||
val b: Boolean = listOf(1).contains1(1)
|
||||
}
|
||||
+2
-2
@@ -19,8 +19,8 @@ public fun <K, V> Map<K, V>.get1(key: Any?): Int = null!!
|
||||
public fun <@kotlin.internal.OnlyInputTypes K, V> Map<out K, V>.get1(key: K): V? = null!!
|
||||
|
||||
fun test(map: Map<Int, String>) {
|
||||
val a: Int = listOf(1).<!AMBIGUITY!>contains1<!>("")
|
||||
val b: Boolean = listOf(1).<!AMBIGUITY!>contains1<!>(1)
|
||||
val a: Int = listOf(1).contains1("")
|
||||
val b: Boolean = listOf(1).contains1(1)
|
||||
|
||||
val c: String? = map.get1("")
|
||||
val d: String? = map.get1(1)
|
||||
|
||||
Reference in New Issue
Block a user