diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/DiagnosticReporterByTrackingStrategy.kt b/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/DiagnosticReporterByTrackingStrategy.kt index fd74e06f523..cca8f68aed8 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/DiagnosticReporterByTrackingStrategy.kt +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/DiagnosticReporterByTrackingStrategy.kt @@ -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)) } diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/tower/KotlinToResolvedCallTransformer.kt b/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/tower/KotlinToResolvedCallTransformer.kt index ec60eff9963..5c0f3d40ad7 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/tower/KotlinToResolvedCallTransformer.kt +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/tower/KotlinToResolvedCallTransformer.kt @@ -479,6 +479,7 @@ class NewResolvedCallImpl( 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 } } diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/tower/PSICallResolver.kt b/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/tower/PSICallResolver.kt index b97b84ebec4..813bc3bc568 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/tower/PSICallResolver.kt +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/tower/PSICallResolver.kt @@ -194,7 +194,10 @@ class PSICallResolver( } 1 -> { val singleCandidate = result.single() - val resolvedCall = kotlinToResolvedCallTransformer.transformAndReport(singleCandidate, context, trace) + + val reportToTrace = singleCandidate.currentStatus.resultingApplicability != ResolutionCandidateApplicability.INAPPLICABLE_WRONG_RECEIVER + + val resolvedCall = kotlinToResolvedCallTransformer.transformAndReport(singleCandidate, context, trace.takeIf { reportToTrace }) return SingleOverloadResolutionResult(resolvedCall) } else -> { @@ -225,12 +228,7 @@ class PSICallResolver( private fun Collection.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 } diff --git a/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/components/CheckArgumentsResolutionPart.kt b/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/components/CheckArgumentsResolutionPart.kt index fa4cf8295cc..5036276c56e 100644 --- a/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/components/CheckArgumentsResolutionPart.kt +++ b/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/components/CheckArgumentsResolutionPart.kt @@ -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 } diff --git a/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/inference/model/ConstraintPositionAndErrors.kt b/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/inference/model/ConstraintPositionAndErrors.kt index 3f576a252f7..4d06587fe3e 100644 --- a/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/inference/model/ConstraintPositionAndErrors.kt +++ b/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/inference/model/ConstraintPositionAndErrors.kt @@ -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) } diff --git a/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/model/ResolvedKotlinCall.kt b/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/model/ResolvedKotlinCall.kt index 0c1a98df09b..f1bd6c105a0 100644 --- a/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/model/ResolvedKotlinCall.kt +++ b/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/model/ResolvedKotlinCall.kt @@ -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, val lambdaArguments: List - ): 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 {