Don't clean type info for containment operator if the resolution was unsuccessful, but all diagnostics were about only input types and non-strict only input types check was enabled

This commit is contained in:
Victor Petukhov
2020-12-23 15:03:40 +03:00
parent 954c9cecca
commit b4d8adeeb4
7 changed files with 144 additions and 6 deletions
@@ -566,6 +566,8 @@ sealed class NewAbstractResolvedCall<D : CallableDescriptor>() : ResolvedCall<D>
private var nonTrivialUpdatedResultInfo: DataFlowInfo? = null
abstract fun containsOnlyOnlyInputTypesErrors(): Boolean
override fun getCall(): Call = kotlinCall.psiKotlinCall.psiCall
override fun getValueArguments(): Map<ValueParameterDescriptor, ResolvedValueArgument> {
@@ -710,6 +712,9 @@ class NewResolvedCallImpl<D : CallableDescriptor>(
return typeParameters.zip(typeArguments).toMap()
}
override fun containsOnlyOnlyInputTypesErrors() =
diagnostics.all { it is KotlinConstraintSystemDiagnostic && it.error is OnlyInputTypesDiagnostic }
override fun getSmartCastDispatchReceiverType(): KotlinType? = smartCastDispatchReceiverType
fun updateExtensionReceiverWithSmartCastIfNeeded(smartCastExtensionReceiverType: KotlinType) {
@@ -60,6 +60,7 @@ import org.jetbrains.kotlin.resolve.calls.smartcasts.Nullability;
import org.jetbrains.kotlin.resolve.calls.tasks.ExplicitReceiverKind;
import org.jetbrains.kotlin.resolve.calls.tasks.ResolutionCandidate;
import org.jetbrains.kotlin.resolve.calls.tasks.TracingStrategy;
import org.jetbrains.kotlin.resolve.calls.tower.NewAbstractResolvedCall;
import org.jetbrains.kotlin.resolve.calls.util.CallMaker;
import org.jetbrains.kotlin.resolve.checkers.UnderscoreChecker;
import org.jetbrains.kotlin.resolve.constants.*;
@@ -1394,14 +1395,26 @@ public class BasicExpressionTypingVisitor extends ExpressionTypingVisitor {
rightTypeInfo = rightTypeInfo.replaceDataFlowInfo(dataFlowInfo);
}
if (resolutionResult.isSuccess()) {
if (resolutionResult.isSuccess() || isResolutionSuccessfulWithOnlyInputTypesWarnings(resolutionResult.getResultingCalls(), context)) {
return rightTypeInfo.replaceType(components.builtIns.getBooleanType());
}
else {
} else {
return rightTypeInfo.clearType();
}
}
private static boolean isResolutionSuccessfulWithOnlyInputTypesWarnings(
@Nullable Collection<? extends ResolvedCall<FunctionDescriptor>> allCandidates,
@NotNull ExpressionTypingContext context
) {
if (allCandidates == null || allCandidates.isEmpty()) return false;
boolean areAllCandidatesFailedWithOnlyInputTypesError = allCandidates.stream().allMatch((resolvedCall) ->
resolvedCall instanceof NewAbstractResolvedCall<?> && ((NewAbstractResolvedCall<?>) resolvedCall).containsOnlyOnlyInputTypesErrors()
);
boolean isNonStrictOnlyInputTypesCheckEnabled = context.languageVersionSettings.supportsFeature(LanguageFeature.NonStrictOnlyInputTypesChecks);
return areAllCandidatesFailedWithOnlyInputTypesError && isNonStrictOnlyInputTypesCheckEnabled;
}
private boolean ensureBooleanResult(KtExpression operationSign, Name name, KotlinType resultType, ExpressionTypingContext context) {
return ensureBooleanResultWithCustomSubject(operationSign, resultType, "'" + name + "'", context);