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
|
private var nonTrivialUpdatedResultInfo: DataFlowInfo? = null
|
||||||
|
|
||||||
|
abstract fun containsOnlyOnlyInputTypesErrors(): Boolean
|
||||||
|
|
||||||
override fun getCall(): Call = kotlinCall.psiKotlinCall.psiCall
|
override fun getCall(): Call = kotlinCall.psiKotlinCall.psiCall
|
||||||
|
|
||||||
override fun getValueArguments(): Map<ValueParameterDescriptor, ResolvedValueArgument> {
|
override fun getValueArguments(): Map<ValueParameterDescriptor, ResolvedValueArgument> {
|
||||||
@@ -710,6 +712,9 @@ class NewResolvedCallImpl<D : CallableDescriptor>(
|
|||||||
return typeParameters.zip(typeArguments).toMap()
|
return typeParameters.zip(typeArguments).toMap()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun containsOnlyOnlyInputTypesErrors() =
|
||||||
|
diagnostics.all { it is KotlinConstraintSystemDiagnostic && it.error is OnlyInputTypesDiagnostic }
|
||||||
|
|
||||||
override fun getSmartCastDispatchReceiverType(): KotlinType? = smartCastDispatchReceiverType
|
override fun getSmartCastDispatchReceiverType(): KotlinType? = smartCastDispatchReceiverType
|
||||||
|
|
||||||
fun updateExtensionReceiverWithSmartCastIfNeeded(smartCastExtensionReceiverType: KotlinType) {
|
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.ExplicitReceiverKind;
|
||||||
import org.jetbrains.kotlin.resolve.calls.tasks.ResolutionCandidate;
|
import org.jetbrains.kotlin.resolve.calls.tasks.ResolutionCandidate;
|
||||||
import org.jetbrains.kotlin.resolve.calls.tasks.TracingStrategy;
|
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.calls.util.CallMaker;
|
||||||
import org.jetbrains.kotlin.resolve.checkers.UnderscoreChecker;
|
import org.jetbrains.kotlin.resolve.checkers.UnderscoreChecker;
|
||||||
import org.jetbrains.kotlin.resolve.constants.*;
|
import org.jetbrains.kotlin.resolve.constants.*;
|
||||||
@@ -1394,14 +1395,26 @@ public class BasicExpressionTypingVisitor extends ExpressionTypingVisitor {
|
|||||||
rightTypeInfo = rightTypeInfo.replaceDataFlowInfo(dataFlowInfo);
|
rightTypeInfo = rightTypeInfo.replaceDataFlowInfo(dataFlowInfo);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (resolutionResult.isSuccess()) {
|
if (resolutionResult.isSuccess() || isResolutionSuccessfulWithOnlyInputTypesWarnings(resolutionResult.getResultingCalls(), context)) {
|
||||||
return rightTypeInfo.replaceType(components.builtIns.getBooleanType());
|
return rightTypeInfo.replaceType(components.builtIns.getBooleanType());
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
return rightTypeInfo.clearType();
|
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) {
|
private boolean ensureBooleanResult(KtExpression operationSign, Name name, KotlinType resultType, ExpressionTypingContext context) {
|
||||||
return ensureBooleanResultWithCustomSubject(operationSign, resultType, "'" + name + "'", 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");
|
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")
|
@TestMetadata("substituteStubTypeIntoCR.kt")
|
||||||
public void testSubstituteStubTypeIntoCR() throws Exception {
|
public void testSubstituteStubTypeIntoCR() throws Exception {
|
||||||
runTest("compiler/testData/codegen/box/inference/builderInference/substituteStubTypeIntoCR.kt");
|
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) {
|
fun case_2(value_1: Int, value_3: Nothing) {
|
||||||
when (value_1) {
|
when (value_1) {
|
||||||
<!OVERLOAD_RESOLUTION_AMBIGUITY, TYPE_MISMATCH_IN_RANGE, UNREACHABLE_CODE!>in<!> value_3 -> <!UNREACHABLE_CODE!>{}<!>
|
<!OVERLOAD_RESOLUTION_AMBIGUITY, UNREACHABLE_CODE!>in<!> value_3 -> <!UNREACHABLE_CODE!>{}<!>
|
||||||
<!UNREACHABLE_CODE!><!OVERLOAD_RESOLUTION_AMBIGUITY, TYPE_MISMATCH_IN_RANGE!>in<!> throw Exception() -> {}<!>
|
<!UNREACHABLE_CODE!><!OVERLOAD_RESOLUTION_AMBIGUITY!>in<!> throw Exception() -> {}<!>
|
||||||
<!UNREACHABLE_CODE!><!OVERLOAD_RESOLUTION_AMBIGUITY, TYPE_MISMATCH_IN_RANGE!>in<!> return -> {}<!>
|
<!UNREACHABLE_CODE!><!OVERLOAD_RESOLUTION_AMBIGUITY!>in<!> return -> {}<!>
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user