[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 -> {
|
NewConstraintError::class.java -> {
|
||||||
val constraintError = diagnostic as NewConstraintError
|
val constraintError = diagnostic as NewConstraintError
|
||||||
val position = constraintError.position.from
|
val position = constraintError.position.from
|
||||||
(position as? ArgumentConstraintPosition)?.let {
|
val argument = (position as? ArgumentConstraintPosition)?.argument
|
||||||
val expression = it.argument.psiExpression ?: return
|
?: (position as? ReceiverConstraintPosition)?.argument
|
||||||
|
argument?.let {
|
||||||
|
val expression = it.psiExpression ?: return
|
||||||
if (reportConstantTypeMismatch(constraintError, expression)) return
|
if (reportConstantTypeMismatch(constraintError, expression)) return
|
||||||
trace.report(Errors.TYPE_MISMATCH.on(expression, constraintError.upperType, constraintError.lowerType))
|
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) {
|
fun ResolutionCandidateApplicability.toResolutionStatus(): ResolutionStatus = when (this) {
|
||||||
ResolutionCandidateApplicability.RESOLVED, ResolutionCandidateApplicability.RESOLVED_LOW_PRIORITY -> ResolutionStatus.SUCCESS
|
ResolutionCandidateApplicability.RESOLVED, ResolutionCandidateApplicability.RESOLVED_LOW_PRIORITY -> ResolutionStatus.SUCCESS
|
||||||
|
ResolutionCandidateApplicability.INAPPLICABLE_WRONG_RECEIVER -> ResolutionStatus.RECEIVER_TYPE_ERROR
|
||||||
else -> ResolutionStatus.OTHER_ERROR
|
else -> ResolutionStatus.OTHER_ERROR
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -194,7 +194,10 @@ class PSICallResolver(
|
|||||||
}
|
}
|
||||||
1 -> {
|
1 -> {
|
||||||
val singleCandidate = result.single()
|
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)
|
return SingleOverloadResolutionResult(resolvedCall)
|
||||||
}
|
}
|
||||||
else -> {
|
else -> {
|
||||||
@@ -225,12 +228,7 @@ class PSICallResolver(
|
|||||||
|
|
||||||
private fun Collection<ResolvedKotlinCall>.areAllCompletedAndInapplicable() =
|
private fun Collection<ResolvedKotlinCall>.areAllCompletedAndInapplicable() =
|
||||||
all {
|
all {
|
||||||
val applicability = when (it) {
|
val applicability = it.currentStatus.resultingApplicability
|
||||||
is ResolvedKotlinCall.CompletedResolvedKotlinCall ->
|
|
||||||
it.completedCall.resolutionStatus.resultingApplicability
|
|
||||||
is ResolvedKotlinCall.OnlyResolvedKotlinCall ->
|
|
||||||
it.candidate.status.resultingApplicability
|
|
||||||
}
|
|
||||||
applicability == ResolutionCandidateApplicability.INAPPLICABLE || applicability == ResolutionCandidateApplicability.HIDDEN
|
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.ConstraintSystemBuilder
|
||||||
import org.jetbrains.kotlin.resolve.calls.inference.addSubtypeConstraintIfCompatible
|
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.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.inference.model.TypeVariableForLambdaReturnType
|
||||||
import org.jetbrains.kotlin.resolve.calls.model.*
|
import org.jetbrains.kotlin.resolve.calls.model.*
|
||||||
import org.jetbrains.kotlin.resolve.calls.tower.isSuccess
|
import org.jetbrains.kotlin.resolve.calls.tower.isSuccess
|
||||||
@@ -203,7 +205,7 @@ internal fun checkExpressionArgument(
|
|||||||
val argumentType = captureFromTypeParameterUpperBoundIfNeeded(expressionArgument.stableType, expectedType)
|
val argumentType = captureFromTypeParameterUpperBoundIfNeeded(expressionArgument.stableType, expectedType)
|
||||||
|
|
||||||
fun unstableSmartCastOrSubtypeError(
|
fun unstableSmartCastOrSubtypeError(
|
||||||
unstableType: UnwrappedType?, expectedType: UnwrappedType, position: ArgumentConstraintPosition
|
unstableType: UnwrappedType?, expectedType: UnwrappedType, position: ConstraintPosition
|
||||||
): KotlinCallDiagnostic? {
|
): KotlinCallDiagnostic? {
|
||||||
if (unstableType != null) {
|
if (unstableType != null) {
|
||||||
if (csBuilder.addSubtypeConstraintIfCompatible(unstableType, expectedType, position)) {
|
if (csBuilder.addSubtypeConstraintIfCompatible(unstableType, expectedType, position)) {
|
||||||
@@ -215,7 +217,7 @@ internal fun checkExpressionArgument(
|
|||||||
}
|
}
|
||||||
|
|
||||||
val expectedNullableType = expectedType.makeNullableAsSpecified(true)
|
val expectedNullableType = expectedType.makeNullableAsSpecified(true)
|
||||||
val position = ArgumentConstraintPosition(expressionArgument)
|
val position = if (isReceiver) ReceiverConstraintPosition(expressionArgument) else ArgumentConstraintPosition(expressionArgument)
|
||||||
if (expressionArgument.isSafeCall) {
|
if (expressionArgument.isSafeCall) {
|
||||||
if (!csBuilder.addSubtypeConstraintIfCompatible(argumentType, expectedNullableType, position)) {
|
if (!csBuilder.addSubtypeConstraintIfCompatible(argumentType, expectedNullableType, position)) {
|
||||||
return unstableSmartCastOrSubtypeError(expressionArgument.unstableType, expectedNullableType, position)?.let { return it }
|
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() {
|
class ArgumentConstraintPosition(val argument: KotlinCallArgument) : ConstraintPosition() {
|
||||||
override fun toString() = "Argument $argument"
|
override fun toString() = "Argument $argument"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class ReceiverConstraintPosition(val argument: KotlinCallArgument) : ConstraintPosition() {
|
||||||
|
override fun toString() = "Receiver $argument"
|
||||||
|
}
|
||||||
|
|
||||||
class FixVariableConstraintPosition(val variable: NewTypeVariable) : ConstraintPosition() {
|
class FixVariableConstraintPosition(val variable: NewTypeVariable) : ConstraintPosition() {
|
||||||
override fun toString() = "Fix variable $variable"
|
override fun toString() = "Fix variable $variable"
|
||||||
}
|
}
|
||||||
@@ -57,8 +62,11 @@ class IncorporationConstraintPosition(val from: ConstraintPosition, val initialC
|
|||||||
object SimpleConstraintSystemConstraintPosition : ConstraintPosition()
|
object SimpleConstraintSystemConstraintPosition : ConstraintPosition()
|
||||||
|
|
||||||
|
|
||||||
class NewConstraintError(val lowerType: UnwrappedType, val upperType: UnwrappedType, val position: IncorporationConstraintPosition):
|
class NewConstraintError(val lowerType: UnwrappedType, val upperType: UnwrappedType, val position: IncorporationConstraintPosition) :
|
||||||
KotlinCallDiagnostic(ResolutionCandidateApplicability.INAPPLICABLE) {
|
KotlinCallDiagnostic(
|
||||||
|
if (position.from is ReceiverConstraintPosition) ResolutionCandidateApplicability.INAPPLICABLE_WRONG_RECEIVER
|
||||||
|
else ResolutionCandidateApplicability.INAPPLICABLE
|
||||||
|
) {
|
||||||
override fun report(reporter: DiagnosticReporter) = reporter.constraintError(this)
|
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.CallableDescriptor
|
||||||
import org.jetbrains.kotlin.descriptors.ValueParameterDescriptor
|
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.tasks.ExplicitReceiverKind
|
||||||
import org.jetbrains.kotlin.resolve.calls.tower.ResolutionCandidateStatus
|
import org.jetbrains.kotlin.resolve.calls.tower.ResolutionCandidateStatus
|
||||||
import org.jetbrains.kotlin.resolve.scopes.receivers.ReceiverValueWithSmartCastInfo
|
import org.jetbrains.kotlin.resolve.scopes.receivers.ReceiverValueWithSmartCastInfo
|
||||||
import org.jetbrains.kotlin.types.UnwrappedType
|
import org.jetbrains.kotlin.types.UnwrappedType
|
||||||
|
|
||||||
sealed class ResolvedKotlinCall {
|
sealed class ResolvedKotlinCall {
|
||||||
|
abstract val currentStatus: ResolutionCandidateStatus
|
||||||
|
|
||||||
class CompletedResolvedKotlinCall(
|
class CompletedResolvedKotlinCall(
|
||||||
val completedCall: CompletedKotlinCall,
|
val completedCall: CompletedKotlinCall,
|
||||||
val allInnerCalls: Collection<CompletedKotlinCall>,
|
val allInnerCalls: Collection<CompletedKotlinCall>,
|
||||||
val lambdaArguments: List<ResolvedLambdaArgument>
|
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 {
|
sealed class CompletedKotlinCall {
|
||||||
|
|||||||
Reference in New Issue
Block a user