[FIR] Fix incorrect smartcasts from || expressions
#KT-36057 Fixed
This commit is contained in:
@@ -137,8 +137,10 @@ abstract class LogicSystem<FLOW : Flow>(protected val context: ConeInferenceCont
|
||||
val allTypes = types.flatMapTo(mutableSetOf()) { it }
|
||||
val commonTypes = allTypes.toMutableSet()
|
||||
types.forEach { commonTypes.retainAll(it) }
|
||||
val differentTypes = allTypes - commonTypes
|
||||
context.commonSuperTypeOrNull(differentTypes.toList())?.let { commonTypes += it }
|
||||
val differentTypes = types.mapNotNull { (it - commonTypes).takeIf { it.isNotEmpty() } }
|
||||
if (differentTypes.size == types.size) {
|
||||
context.commonSuperTypeOrNull(differentTypes.flatten())?.let { commonTypes += it }
|
||||
}
|
||||
return commonTypes
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,27 @@
|
||||
// ISSUE: KT-36057
|
||||
|
||||
fun String.foo() {}
|
||||
|
||||
fun test_1(a: Any?) {
|
||||
when (a) {
|
||||
is String, is Any -> a.<!INAPPLICABLE_CANDIDATE!>foo<!>() // Should be Bad
|
||||
}
|
||||
}
|
||||
|
||||
fun test_2(a: Any?) {
|
||||
if (a is String || a is Any) {
|
||||
a.<!INAPPLICABLE_CANDIDATE!>foo<!>() // Should be Bad
|
||||
}
|
||||
}
|
||||
|
||||
fun test_3(a: Any?, b: Boolean) {
|
||||
when (a) {
|
||||
is String, b -> a.<!INAPPLICABLE_CANDIDATE!>foo<!>() // Should be Bad
|
||||
}
|
||||
}
|
||||
|
||||
fun test_4(a: Any?, b: Boolean) {
|
||||
if (a is String || b) {
|
||||
a.<!INAPPLICABLE_CANDIDATE!>foo<!>() // Should be Bad
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
FILE: orInWhenBranch.kt
|
||||
public final fun R|kotlin/String|.foo(): R|kotlin/Unit| {
|
||||
}
|
||||
public final fun test_1(a: R|kotlin/Any?|): R|kotlin/Unit| {
|
||||
when (R|<local>/a|) {
|
||||
($subj$ is R|kotlin/String|) || ($subj$ is R|kotlin/Any|) -> {
|
||||
R|<local>/a|.<Inapplicable(WRONG_RECEIVER): [/foo]>#()
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
public final fun test_2(a: R|kotlin/Any?|): R|kotlin/Unit| {
|
||||
when () {
|
||||
(R|<local>/a| is R|kotlin/String|) || (R|<local>/a| is R|kotlin/Any|) -> {
|
||||
R|<local>/a|.<Inapplicable(WRONG_RECEIVER): [/foo]>#()
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
public final fun test_3(a: R|kotlin/Any?|, b: R|kotlin/Boolean|): R|kotlin/Unit| {
|
||||
when (R|<local>/a|) {
|
||||
($subj$ is R|kotlin/String|) || ==($subj$, R|<local>/b|) -> {
|
||||
R|<local>/a|.<Inapplicable(WRONG_RECEIVER): [/foo]>#()
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
public final fun test_4(a: R|kotlin/Any?|, b: R|kotlin/Boolean|): R|kotlin/Unit| {
|
||||
when () {
|
||||
(R|<local>/a| is R|kotlin/String|) || R|<local>/b| -> {
|
||||
R|<local>/a|.<Inapplicable(WRONG_RECEIVER): [/foo]>#()
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
+5
@@ -1461,6 +1461,11 @@ public class FirDiagnosticsTestGenerated extends AbstractFirDiagnosticsTest {
|
||||
runTest("compiler/fir/resolve/testData/resolve/smartcasts/nullability.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("orInWhenBranch.kt")
|
||||
public void testOrInWhenBranch() throws Exception {
|
||||
runTest("compiler/fir/resolve/testData/resolve/smartcasts/orInWhenBranch.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("smartCastInInit.kt")
|
||||
public void testSmartCastInInit() throws Exception {
|
||||
runTest("compiler/fir/resolve/testData/resolve/smartcasts/smartCastInInit.kt");
|
||||
|
||||
Generated
+5
@@ -1461,6 +1461,11 @@ public class FirDiagnosticsWithLightTreeTestGenerated extends AbstractFirDiagnos
|
||||
runTest("compiler/fir/resolve/testData/resolve/smartcasts/nullability.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("orInWhenBranch.kt")
|
||||
public void testOrInWhenBranch() throws Exception {
|
||||
runTest("compiler/fir/resolve/testData/resolve/smartcasts/orInWhenBranch.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("smartCastInInit.kt")
|
||||
public void testSmartCastInInit() throws Exception {
|
||||
runTest("compiler/fir/resolve/testData/resolve/smartcasts/smartCastInInit.kt");
|
||||
|
||||
@@ -196,7 +196,7 @@ fun mergeSmartCasts(a: Any?) {
|
||||
a.<!INAPPLICABLE_CANDIDATE!>compareTo<!>("")
|
||||
}
|
||||
when (a) {
|
||||
is String, is Any -> a.compareTo("")
|
||||
is String, is Any -> a.<!UNRESOLVED_REFERENCE!>compareTo<!>("")
|
||||
}
|
||||
if (a is String && a is Any) {
|
||||
val i: Int = a.compareTo("")
|
||||
|
||||
Reference in New Issue
Block a user