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:
+5
@@ -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) {
|
||||
|
||||
+16
-3
@@ -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);
|
||||
|
||||
+45
@@ -0,0 +1,45 @@
|
||||
// WITH_RUNTIME
|
||||
|
||||
import kotlin.experimental.ExperimentalTypeInference
|
||||
|
||||
fun <K> FlowCollector<K>.bar(): K = null as K
|
||||
fun <K> FlowCollector<K>.foo(): K = null as K
|
||||
|
||||
fun bar2(): Int = 1
|
||||
fun foo2(): Float = 1f
|
||||
|
||||
val bar4: Int
|
||||
get() = 1
|
||||
|
||||
var foo4: Float
|
||||
get() = 1f
|
||||
set(value) {}
|
||||
|
||||
fun <T> materialize() = null as T
|
||||
|
||||
interface FlowCollector<in T> {}
|
||||
|
||||
@Suppress("EXPERIMENTAL_API_USAGE_ERROR")
|
||||
fun <L> flow(@BuilderInference block: suspend FlowCollector<L>.() -> Unit) = Flow(block)
|
||||
|
||||
class Flow<out R>(private val block: suspend FlowCollector<R>.() -> Unit)
|
||||
|
||||
fun poll81(): Flow<String> {
|
||||
return flow {
|
||||
val inv = ::bar2 in setOf(::foo2)
|
||||
inv
|
||||
}
|
||||
}
|
||||
|
||||
fun poll83(): Flow<String> {
|
||||
return flow {
|
||||
val inv = ::bar4 in setOf(::foo4)
|
||||
inv
|
||||
}
|
||||
}
|
||||
|
||||
fun box(): String {
|
||||
poll81()
|
||||
poll83()
|
||||
return "OK"
|
||||
}
|
||||
+35
@@ -0,0 +1,35 @@
|
||||
// WITH_RUNTIME
|
||||
// SKIP_TXT
|
||||
// !DIAGNOSTICS: -CAST_NEVER_SUCCEEDS -UNCHECKED_CAST -UNUSED_PARAMETER -UNUSED_VARIABLE -EXPERIMENTAL_API_USAGE_ERROR -UNUSED_EXPRESSION
|
||||
|
||||
import kotlin.experimental.ExperimentalTypeInference
|
||||
|
||||
fun bar2(): Int = 1
|
||||
fun foo2(): Float = 1f
|
||||
|
||||
val bar4: Int
|
||||
get() = 1
|
||||
|
||||
var foo4: Float
|
||||
get() = 1f
|
||||
set(value) {}
|
||||
|
||||
interface FlowCollector<in T> {}
|
||||
|
||||
fun <L> flow(@BuilderInference block: suspend FlowCollector<L>.() -> Unit) = Flow(block)
|
||||
|
||||
class Flow<out R>(private val block: suspend FlowCollector<R>.() -> Unit)
|
||||
|
||||
fun poll81(): Flow<String> {
|
||||
return flow {
|
||||
val inv = ::bar2 in setOf(::foo2)
|
||||
<!UNRESOLVED_REFERENCE!>inv<!>()
|
||||
}
|
||||
}
|
||||
|
||||
fun poll83(): Flow<String> {
|
||||
return flow {
|
||||
val inv = ::bar4 in setOf(::foo4)
|
||||
inv
|
||||
}
|
||||
}
|
||||
+35
@@ -0,0 +1,35 @@
|
||||
// WITH_RUNTIME
|
||||
// SKIP_TXT
|
||||
// !DIAGNOSTICS: -CAST_NEVER_SUCCEEDS -UNCHECKED_CAST -UNUSED_PARAMETER -UNUSED_VARIABLE -EXPERIMENTAL_API_USAGE_ERROR -UNUSED_EXPRESSION
|
||||
|
||||
import kotlin.experimental.ExperimentalTypeInference
|
||||
|
||||
fun bar2(): Int = 1
|
||||
fun foo2(): Float = 1f
|
||||
|
||||
val bar4: Int
|
||||
get() = 1
|
||||
|
||||
var foo4: Float
|
||||
get() = 1f
|
||||
set(value) {}
|
||||
|
||||
interface FlowCollector<in T> {}
|
||||
|
||||
fun <L> flow(@BuilderInference block: suspend FlowCollector<L>.() -> Unit) = Flow(block)
|
||||
|
||||
class Flow<out R>(private val block: suspend FlowCollector<R>.() -> Unit)
|
||||
|
||||
fun poll81(): Flow<String> {
|
||||
return flow {
|
||||
val inv = ::bar2 <!TYPE_INFERENCE_ONLY_INPUT_TYPES_WARNING!>in<!> setOf(::foo2)
|
||||
<!UNRESOLVED_REFERENCE_WRONG_RECEIVER!>inv<!>()
|
||||
}
|
||||
}
|
||||
|
||||
fun poll83(): Flow<String> {
|
||||
return flow {
|
||||
val inv = ::bar4 <!TYPE_INFERENCE_ONLY_INPUT_TYPES_WARNING!>in<!> setOf(::foo4)
|
||||
inv
|
||||
}
|
||||
}
|
||||
+5
@@ -13506,6 +13506,11 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest {
|
||||
runTest("compiler/testData/codegen/box/inference/builderInference/specialCallsWithCallableReferencesErrorType.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("specialCallsWithCallableReferencesNonStrictOnlyInputTypes.kt")
|
||||
public void testSpecialCallsWithCallableReferencesNonStrictOnlyInputTypes() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/inference/builderInference/specialCallsWithCallableReferencesNonStrictOnlyInputTypes.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("substituteStubTypeIntoCR.kt")
|
||||
public void testSubstituteStubTypeIntoCR() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/inference/builderInference/substituteStubTypeIntoCR.kt");
|
||||
|
||||
+3
-3
@@ -29,8 +29,8 @@ fun case_1(value_1: Int, value_2: EmptyClass, value_3: Int, value_4: Any): Strin
|
||||
*/
|
||||
fun case_2(value_1: Int, value_3: Nothing) {
|
||||
when (value_1) {
|
||||
<!OVERLOAD_RESOLUTION_AMBIGUITY, TYPE_MISMATCH_IN_RANGE, UNREACHABLE_CODE!>in<!> value_3 -> <!UNREACHABLE_CODE!>{}<!>
|
||||
<!UNREACHABLE_CODE!><!OVERLOAD_RESOLUTION_AMBIGUITY, TYPE_MISMATCH_IN_RANGE!>in<!> throw Exception() -> {}<!>
|
||||
<!UNREACHABLE_CODE!><!OVERLOAD_RESOLUTION_AMBIGUITY, TYPE_MISMATCH_IN_RANGE!>in<!> return -> {}<!>
|
||||
<!OVERLOAD_RESOLUTION_AMBIGUITY, UNREACHABLE_CODE!>in<!> value_3 -> <!UNREACHABLE_CODE!>{}<!>
|
||||
<!UNREACHABLE_CODE!><!OVERLOAD_RESOLUTION_AMBIGUITY!>in<!> throw Exception() -> {}<!>
|
||||
<!UNREACHABLE_CODE!><!OVERLOAD_RESOLUTION_AMBIGUITY!>in<!> return -> {}<!>
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user