FIR: apply overload conflict resolver even for variable (due to receivers)

This commit is contained in:
Mikhail Glukhikh
2019-10-07 14:17:39 +03:00
parent 4cd8b78779
commit a0ed03a121
3 changed files with 29 additions and 9 deletions
@@ -166,15 +166,20 @@ class FirCallResolver(
)
val result = towerResolver.runResolver(consumer, implicitReceiverStack.receiversAsReversed())
val candidates = result.bestCandidates()
val bestCandidates = result.bestCandidates()
val reducedCandidates = if (result.currentApplicability < CandidateApplicability.SYNTHETIC_RESOLVED) {
bestCandidates.toSet()
} else {
conflictResolver.chooseMaximallySpecificCandidates(bestCandidates, discriminateGenerics = false)
}
val nameReference = createResolvedNamedReference(
callee,
candidates,
reducedCandidates,
result.currentApplicability
)
if (qualifiedAccess.explicitReceiver == null &&
(candidates.size <= 1 && result.currentApplicability < CandidateApplicability.SYNTHETIC_RESOLVED)
(reducedCandidates.size <= 1 && result.currentApplicability < CandidateApplicability.SYNTHETIC_RESOLVED)
) {
qualifiedResolver.tryResolveAsQualifier()?.let { return it }
}
@@ -196,8 +201,8 @@ class FirCallResolver(
@Suppress("UNCHECKED_CAST")
var resultExpression = qualifiedAccess.transformCalleeReference(StoreNameReference, nameReference) as T
if (candidates.size == 1) {
val candidate = candidates.single()
if (reducedCandidates.size == 1) {
val candidate = reducedCandidates.single()
resultExpression = resultExpression.transformDispatchReceiver(StoreReceiver, candidate.dispatchReceiverExpression()) as T
resultExpression = resultExpression.transformExtensionReceiver(StoreReceiver, candidate.extensionReceiverExpression()) as T
}
@@ -5,10 +5,11 @@
package org.jetbrains.kotlin.fir.resolve.calls
import org.jetbrains.kotlin.fir.FirSession
import org.jetbrains.kotlin.fir.declarations.FirConstructor
import org.jetbrains.kotlin.fir.declarations.FirNamedFunction
import org.jetbrains.kotlin.fir.declarations.FirProperty
import org.jetbrains.kotlin.fir.declarations.FirValueParameter
import org.jetbrains.kotlin.fir.expressions.FirVariable
import org.jetbrains.kotlin.fir.resolve.substitution.substitutorByMap
import org.jetbrains.kotlin.fir.symbols.impl.FirTypeParameterSymbol
import org.jetbrains.kotlin.fir.types.ConeKotlinType
@@ -55,6 +56,7 @@ class ConeOverloadConflictResolver(
return when (val declaration = call.symbol.fir) {
is FirNamedFunction -> createFlatSignature(call, declaration)
is FirConstructor -> createFlatSignature(call, declaration)
is FirVariable<*> -> createFlatSignature(call, declaration)
else -> error("Not supported: $declaration")
}
}
@@ -84,7 +86,7 @@ class ConeOverloadConflictResolver(
call,
function.typeParameters.map { it.symbol },
listOfNotNull<ConeKotlinType>(function.receiverTypeRef?.coneTypeUnsafe()) +
call.argumentMapping!!.map { it.value.argumentType() },
call.argumentMapping?.map { it.value.argumentType() }.orEmpty(),
function.receiverTypeRef != null,
function.valueParameters.any { it.isVararg },
function.valueParameters.count { it.defaultValue != null },
@@ -93,6 +95,19 @@ class ConeOverloadConflictResolver(
)
}
private fun createFlatSignature(call: Candidate, variable: FirVariable<*>): FlatSignature<Candidate> {
return FlatSignature(
call,
(variable as? FirProperty)?.typeParameters?.map { it.symbol }.orEmpty(),
listOfNotNull<ConeKotlinType>(variable.receiverTypeRef?.coneTypeUnsafe()),
variable.receiverTypeRef != null,
false,
0,
(variable as? FirProperty)?.isExpect == true,
false // TODO
)
}
private fun createEmptyConstraintSystem(): SimpleConstraintSystem {
return ConeSimpleConstraintSystemImpl(inferenceComponents.createConstraintSystem())
}
+2 -2
View File
@@ -34,8 +34,8 @@ FILE: problems.kt
public get(): R|kotlin/String| {
^ String(987)
}
public final val t: <ERROR TYPE REF: Ambiguity: bar, [/bar, /bar]> = String().<Ambiguity: bar, [/bar, /bar]>#
public get(): <ERROR TYPE REF: Ambiguity: bar, [/bar, /bar]>
public final val t: R|kotlin/String| = String().R|/bar|
public get(): R|kotlin/String|
public final val p: R|kotlin/Pair<kotlin/Int, kotlin/String>| = R|kotlin/Pair.Pair|<R|kotlin/Int|, R|kotlin/String|>(Int(0), String())
public get(): R|kotlin/Pair<kotlin/Int, kotlin/String>|
public final class Base<T> : R|kotlin/Any| {