FIR: Add more complicated workaround for OverloadResolutionByLambdaReturnType

That helps for minOfOrNull/maxOfOrNull
This commit is contained in:
Denis Zharkov
2020-11-03 13:32:08 +03:00
parent 4612f26bfb
commit a936386e53
3 changed files with 19 additions and 32 deletions
@@ -7,7 +7,12 @@ package org.jetbrains.kotlin.fir.resolve.calls
import org.jetbrains.kotlin.fir.FirSession
import org.jetbrains.kotlin.fir.declarations.FirCallableDeclaration
import org.jetbrains.kotlin.fir.declarations.FirFunction
import org.jetbrains.kotlin.fir.resolve.fqName
import org.jetbrains.kotlin.fir.resolve.inference.isBuiltinFunctionalType
import org.jetbrains.kotlin.fir.types.ConeKotlinType
import org.jetbrains.kotlin.fir.types.ConeTypeParameterType
import org.jetbrains.kotlin.fir.types.coneTypeSafe
import org.jetbrains.kotlin.resolve.descriptorUtil.OVERLOAD_RESOLUTION_BY_LAMBDA_ANNOTATION
class ConeOverloadResolutionByLambdaConflictResolve(private val session: FirSession) : ConeCallConflictResolver() {
@@ -18,10 +23,20 @@ class ConeOverloadResolutionByLambdaConflictResolve(private val session: FirSess
): Set<Candidate> {
if (candidates.size == 1) return candidates
candidates.singleOrNull { candidate ->
(candidate.symbol.fir as? FirCallableDeclaration<*>)?.annotations?.any {
it.fqName(session) == OVERLOAD_RESOLUTION_BY_LAMBDA_ANNOTATION
val (candidatesWithAnnotation, candidatesWithoutAnnotation) = candidates.partition { candidate ->
(candidate.symbol.fir as? FirCallableDeclaration<*>)?.annotations?.any { annotation ->
annotation.fqName(session) == OVERLOAD_RESOLUTION_BY_LAMBDA_ANNOTATION
} == true
}
if (candidatesWithoutAnnotation.size == 1) return setOf(candidatesWithoutAnnotation.single())
candidatesWithAnnotation.singleOrNull { candidate ->
(candidate.symbol.fir as? FirFunction<*>)
?.valueParameters?.singleOrNull()?.returnTypeRef?.coneTypeSafe<ConeKotlinType>()
.let { type ->
type != null && type.isBuiltinFunctionalType(session) && type.typeArguments.last() is ConeTypeParameterType
}
}?.let {
return setOf(it)
}
@@ -1,29 +0,0 @@
// !LANGUAGE: +NewInference +OverloadResolutionByLambdaReturnType
// !DIAGNOSTICS: -UNUSED_PARAMETER -UNUSED_VARIABLE -UNUSED_EXPRESSION -EXPERIMENTAL_API_USAGE -EXPERIMENTAL_UNSIGNED_LITERALS
// ISSUE: KT-11265
// FILE: OverloadResolutionByLambdaReturnType.kt
package kotlin
annotation class OverloadResolutionByLambdaReturnType
// FILE: main.kt
import kotlin.OverloadResolutionByLambdaReturnType
@OverloadResolutionByLambdaReturnType
fun <T, R : Comparable<R>> Iterable<T>.myMaxOf(selector: (T) -> R): R = TODO()
@OverloadResolutionByLambdaReturnType
fun <T> Iterable<T>.myMaxOf(selector: (T) -> Double): Double = TODO()
@OverloadResolutionByLambdaReturnType
fun <T> Iterable<T>.myMaxOf(selector: (T) -> Float): Float = TODO()
fun Double.pow(v: Int): Double = this
fun test() {
val value = listOf(1, 2, 3, 4, 5, 6).<!AMBIGUITY!>myMaxOf<!> { -2.0.pow(<!UNRESOLVED_REFERENCE!>it<!>) }
takeDouble(value)
}
fun takeDouble(value: Double) {}
@@ -1,3 +1,4 @@
// FIR_IDENTICAL
// !LANGUAGE: +NewInference +OverloadResolutionByLambdaReturnType
// !DIAGNOSTICS: -UNUSED_PARAMETER -UNUSED_VARIABLE -UNUSED_EXPRESSION -EXPERIMENTAL_API_USAGE -EXPERIMENTAL_UNSIGNED_LITERALS
// ISSUE: KT-11265