[FIR] Support @LowPriorityInOverloadResolution annotation
This commit is contained in:
@@ -12,7 +12,8 @@ enum class CallKind(vararg resolutionSequence: ResolutionStage) {
|
|||||||
CheckExplicitReceiverConsistency,
|
CheckExplicitReceiverConsistency,
|
||||||
CreateFreshTypeVariableSubstitutorStage,
|
CreateFreshTypeVariableSubstitutorStage,
|
||||||
CheckReceivers.Dispatch,
|
CheckReceivers.Dispatch,
|
||||||
CheckReceivers.Extension
|
CheckReceivers.Extension,
|
||||||
|
CheckLowPriorityInOverloadResolution
|
||||||
),
|
),
|
||||||
SyntheticSelect(
|
SyntheticSelect(
|
||||||
MapArguments,
|
MapArguments,
|
||||||
@@ -29,7 +30,8 @@ enum class CallKind(vararg resolutionSequence: ResolutionStage) {
|
|||||||
CheckReceivers.Dispatch,
|
CheckReceivers.Dispatch,
|
||||||
CheckReceivers.Extension,
|
CheckReceivers.Extension,
|
||||||
CheckArguments,
|
CheckArguments,
|
||||||
EagerResolveOfCallableReferences
|
EagerResolveOfCallableReferences,
|
||||||
|
CheckLowPriorityInOverloadResolution
|
||||||
),
|
),
|
||||||
CallableReference(
|
CallableReference(
|
||||||
CheckVisibility,
|
CheckVisibility,
|
||||||
|
|||||||
@@ -71,6 +71,7 @@ enum class CandidateApplicability {
|
|||||||
PARAMETER_MAPPING_ERROR,
|
PARAMETER_MAPPING_ERROR,
|
||||||
INAPPLICABLE,
|
INAPPLICABLE,
|
||||||
SYNTHETIC_RESOLVED,
|
SYNTHETIC_RESOLVED,
|
||||||
|
RESOLVED_LOW_PRIORITY,
|
||||||
RESOLVED
|
RESOLVED
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -6,6 +6,7 @@
|
|||||||
package org.jetbrains.kotlin.fir.resolve.calls
|
package org.jetbrains.kotlin.fir.resolve.calls
|
||||||
|
|
||||||
import org.jetbrains.kotlin.descriptors.Visibilities
|
import org.jetbrains.kotlin.descriptors.Visibilities
|
||||||
|
import org.jetbrains.kotlin.fir.FirAnnotationContainer
|
||||||
import org.jetbrains.kotlin.fir.FirSession
|
import org.jetbrains.kotlin.fir.FirSession
|
||||||
import org.jetbrains.kotlin.fir.declarations.*
|
import org.jetbrains.kotlin.fir.declarations.*
|
||||||
import org.jetbrains.kotlin.fir.expressions.FirExpression
|
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.load.java.JavaVisibilities
|
||||||
import org.jetbrains.kotlin.name.ClassId
|
import org.jetbrains.kotlin.name.ClassId
|
||||||
import org.jetbrains.kotlin.name.FqName
|
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.ConstraintSystemOperation
|
||||||
import org.jetbrains.kotlin.resolve.calls.inference.model.SimpleConstraintSystemConstraintPosition
|
import org.jetbrains.kotlin.resolve.calls.inference.model.SimpleConstraintSystemConstraintPosition
|
||||||
import org.jetbrains.kotlin.resolve.calls.tasks.ExplicitReceiverKind
|
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");
|
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")
|
@TestMetadata("mapList.kt")
|
||||||
public void testMapList() throws Exception {
|
public void testMapList() throws Exception {
|
||||||
runTest("compiler/fir/resolve/testData/resolveWithStdlib/mapList.kt");
|
runTest("compiler/fir/resolve/testData/resolveWithStdlib/mapList.kt");
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
// IGNORE_BACKEND_FIR: JVM_IR
|
|
||||||
// WITH_RUNTIME
|
// WITH_RUNTIME
|
||||||
|
|
||||||
@Suppress("INVISIBLE_MEMBER", "INVISIBLE_REFERENCE")
|
@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() {
|
fun test() {
|
||||||
val a: Boolean = listOf(1).<!AMBIGUITY!>contains1<!>("")
|
val a: Boolean = listOf(1).contains1("")
|
||||||
val b: Boolean = listOf(1).<!AMBIGUITY!>contains1<!>(1)
|
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!!
|
public fun <@kotlin.internal.OnlyInputTypes K, V> Map<out K, V>.get1(key: K): V? = null!!
|
||||||
|
|
||||||
fun test(map: Map<Int, String>) {
|
fun test(map: Map<Int, String>) {
|
||||||
val a: Int = listOf(1).<!AMBIGUITY!>contains1<!>("")
|
val a: Int = listOf(1).contains1("")
|
||||||
val b: Boolean = listOf(1).<!AMBIGUITY!>contains1<!>(1)
|
val b: Boolean = listOf(1).contains1(1)
|
||||||
|
|
||||||
val c: String? = map.get1("")
|
val c: String? = map.get1("")
|
||||||
val d: String? = map.get1(1)
|
val d: String? = map.get1(1)
|
||||||
|
|||||||
Reference in New Issue
Block a user