[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:
committed by
Mikhail Zarechenskiy
parent
e4b73fcdbd
commit
5f2cc75718
+4
-2
@@ -151,8 +151,10 @@ class DiagnosticReporterByTrackingStrategy(
|
||||
NewConstraintError::class.java -> {
|
||||
val constraintError = diagnostic as NewConstraintError
|
||||
val position = constraintError.position.from
|
||||
(position as? ArgumentConstraintPosition)?.let {
|
||||
val expression = it.argument.psiExpression ?: return
|
||||
val argument = (position as? ArgumentConstraintPosition)?.argument
|
||||
?: (position as? ReceiverConstraintPosition)?.argument
|
||||
argument?.let {
|
||||
val expression = it.psiExpression ?: return
|
||||
if (reportConstantTypeMismatch(constraintError, expression)) return
|
||||
trace.report(Errors.TYPE_MISMATCH.on(expression, constraintError.upperType, constraintError.lowerType))
|
||||
}
|
||||
|
||||
+1
@@ -479,6 +479,7 @@ class NewResolvedCallImpl<D : CallableDescriptor>(
|
||||
|
||||
fun ResolutionCandidateApplicability.toResolutionStatus(): ResolutionStatus = when (this) {
|
||||
ResolutionCandidateApplicability.RESOLVED, ResolutionCandidateApplicability.RESOLVED_LOW_PRIORITY -> ResolutionStatus.SUCCESS
|
||||
ResolutionCandidateApplicability.INAPPLICABLE_WRONG_RECEIVER -> ResolutionStatus.RECEIVER_TYPE_ERROR
|
||||
else -> ResolutionStatus.OTHER_ERROR
|
||||
}
|
||||
}
|
||||
|
||||
@@ -194,7 +194,10 @@ class PSICallResolver(
|
||||
}
|
||||
1 -> {
|
||||
val singleCandidate = result.single()
|
||||
val resolvedCall = kotlinToResolvedCallTransformer.transformAndReport<D>(singleCandidate, context, trace)
|
||||
|
||||
val reportToTrace = singleCandidate.currentStatus.resultingApplicability != ResolutionCandidateApplicability.INAPPLICABLE_WRONG_RECEIVER
|
||||
|
||||
val resolvedCall = kotlinToResolvedCallTransformer.transformAndReport<D>(singleCandidate, context, trace.takeIf { reportToTrace })
|
||||
return SingleOverloadResolutionResult(resolvedCall)
|
||||
}
|
||||
else -> {
|
||||
@@ -225,12 +228,7 @@ class PSICallResolver(
|
||||
|
||||
private fun Collection<ResolvedKotlinCall>.areAllCompletedAndInapplicable() =
|
||||
all {
|
||||
val applicability = when (it) {
|
||||
is ResolvedKotlinCall.CompletedResolvedKotlinCall ->
|
||||
it.completedCall.resolutionStatus.resultingApplicability
|
||||
is ResolvedKotlinCall.OnlyResolvedKotlinCall ->
|
||||
it.candidate.status.resultingApplicability
|
||||
}
|
||||
val applicability = it.currentStatus.resultingApplicability
|
||||
applicability == ResolutionCandidateApplicability.INAPPLICABLE || applicability == ResolutionCandidateApplicability.HIDDEN
|
||||
}
|
||||
|
||||
|
||||
+4
-2
@@ -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 }
|
||||
|
||||
+10
-2
@@ -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)
|
||||
}
|
||||
|
||||
|
||||
+8
-3
@@ -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 {
|
||||
|
||||
Reference in New Issue
Block a user