[NI] Support INAPPLICABLE_WRONG_RECEIVER candidate applicability

It is important for provideDelegate resolution, because if scope has
provideDelegate with wrong receiver we shouldn't resolve to it and
report any errors.
This commit is contained in:
Stanislav Erokhin
2017-06-08 19:16:33 +03:00
committed by Mikhail Zarechenskiy
parent e4b73fcdbd
commit 5f2cc75718
6 changed files with 32 additions and 16 deletions
@@ -24,6 +24,8 @@ import org.jetbrains.kotlin.resolve.calls.components.CreateDescriptorWithFreshTy
import org.jetbrains.kotlin.resolve.calls.inference.ConstraintSystemBuilder
import org.jetbrains.kotlin.resolve.calls.inference.addSubtypeConstraintIfCompatible
import org.jetbrains.kotlin.resolve.calls.inference.model.ArgumentConstraintPosition
import org.jetbrains.kotlin.resolve.calls.inference.model.ConstraintPosition
import org.jetbrains.kotlin.resolve.calls.inference.model.ReceiverConstraintPosition
import org.jetbrains.kotlin.resolve.calls.inference.model.TypeVariableForLambdaReturnType
import org.jetbrains.kotlin.resolve.calls.model.*
import org.jetbrains.kotlin.resolve.calls.tower.isSuccess
@@ -203,7 +205,7 @@ internal fun checkExpressionArgument(
val argumentType = captureFromTypeParameterUpperBoundIfNeeded(expressionArgument.stableType, expectedType)
fun unstableSmartCastOrSubtypeError(
unstableType: UnwrappedType?, expectedType: UnwrappedType, position: ArgumentConstraintPosition
unstableType: UnwrappedType?, expectedType: UnwrappedType, position: ConstraintPosition
): KotlinCallDiagnostic? {
if (unstableType != null) {
if (csBuilder.addSubtypeConstraintIfCompatible(unstableType, expectedType, position)) {
@@ -215,7 +217,7 @@ internal fun checkExpressionArgument(
}
val expectedNullableType = expectedType.makeNullableAsSpecified(true)
val position = ArgumentConstraintPosition(expressionArgument)
val position = if (isReceiver) ReceiverConstraintPosition(expressionArgument) else ArgumentConstraintPosition(expressionArgument)
if (expressionArgument.isSafeCall) {
if (!csBuilder.addSubtypeConstraintIfCompatible(argumentType, expectedNullableType, position)) {
return unstableSmartCastOrSubtypeError(expressionArgument.unstableType, expectedNullableType, position)?.let { return it }
@@ -37,6 +37,11 @@ class DeclaredUpperBoundConstraintPosition(val typeParameterDescriptor: TypePara
class ArgumentConstraintPosition(val argument: KotlinCallArgument) : ConstraintPosition() {
override fun toString() = "Argument $argument"
}
class ReceiverConstraintPosition(val argument: KotlinCallArgument) : ConstraintPosition() {
override fun toString() = "Receiver $argument"
}
class FixVariableConstraintPosition(val variable: NewTypeVariable) : ConstraintPosition() {
override fun toString() = "Fix variable $variable"
}
@@ -57,8 +62,11 @@ class IncorporationConstraintPosition(val from: ConstraintPosition, val initialC
object SimpleConstraintSystemConstraintPosition : ConstraintPosition()
class NewConstraintError(val lowerType: UnwrappedType, val upperType: UnwrappedType, val position: IncorporationConstraintPosition):
KotlinCallDiagnostic(ResolutionCandidateApplicability.INAPPLICABLE) {
class NewConstraintError(val lowerType: UnwrappedType, val upperType: UnwrappedType, val position: IncorporationConstraintPosition) :
KotlinCallDiagnostic(
if (position.from is ReceiverConstraintPosition) ResolutionCandidateApplicability.INAPPLICABLE_WRONG_RECEIVER
else ResolutionCandidateApplicability.INAPPLICABLE
) {
override fun report(reporter: DiagnosticReporter) = reporter.constraintError(this)
}
@@ -18,20 +18,25 @@ package org.jetbrains.kotlin.resolve.calls.model
import org.jetbrains.kotlin.descriptors.CallableDescriptor
import org.jetbrains.kotlin.descriptors.ValueParameterDescriptor
import org.jetbrains.kotlin.resolve.calls.inference.returnTypeOrNothing
import org.jetbrains.kotlin.resolve.calls.tasks.ExplicitReceiverKind
import org.jetbrains.kotlin.resolve.calls.tower.ResolutionCandidateStatus
import org.jetbrains.kotlin.resolve.scopes.receivers.ReceiverValueWithSmartCastInfo
import org.jetbrains.kotlin.types.UnwrappedType
sealed class ResolvedKotlinCall {
abstract val currentStatus: ResolutionCandidateStatus
class CompletedResolvedKotlinCall(
val completedCall: CompletedKotlinCall,
val allInnerCalls: Collection<CompletedKotlinCall>,
val lambdaArguments: List<ResolvedLambdaArgument>
): ResolvedKotlinCall()
): ResolvedKotlinCall() {
override val currentStatus get() = completedCall.resolutionStatus
}
class OnlyResolvedKotlinCall(val candidate: KotlinResolutionCandidate) : ResolvedKotlinCall()
class OnlyResolvedKotlinCall(val candidate: KotlinResolutionCandidate) : ResolvedKotlinCall() {
override val currentStatus get() = candidate.status
}
}
sealed class CompletedKotlinCall {