[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 allTypes = types.flatMapTo(mutableSetOf()) { it }
|
||||||
val commonTypes = allTypes.toMutableSet()
|
val commonTypes = allTypes.toMutableSet()
|
||||||
types.forEach { commonTypes.retainAll(it) }
|
types.forEach { commonTypes.retainAll(it) }
|
||||||
val differentTypes = allTypes - commonTypes
|
val differentTypes = types.mapNotNull { (it - commonTypes).takeIf { it.isNotEmpty() } }
|
||||||
context.commonSuperTypeOrNull(differentTypes.toList())?.let { commonTypes += it }
|
if (differentTypes.size == types.size) {
|
||||||
|
context.commonSuperTypeOrNull(differentTypes.flatten())?.let { commonTypes += it }
|
||||||
|
}
|
||||||
return commonTypes
|
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");
|
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")
|
@TestMetadata("smartCastInInit.kt")
|
||||||
public void testSmartCastInInit() throws Exception {
|
public void testSmartCastInInit() throws Exception {
|
||||||
runTest("compiler/fir/resolve/testData/resolve/smartcasts/smartCastInInit.kt");
|
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");
|
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")
|
@TestMetadata("smartCastInInit.kt")
|
||||||
public void testSmartCastInInit() throws Exception {
|
public void testSmartCastInInit() throws Exception {
|
||||||
runTest("compiler/fir/resolve/testData/resolve/smartcasts/smartCastInInit.kt");
|
runTest("compiler/fir/resolve/testData/resolve/smartcasts/smartCastInInit.kt");
|
||||||
|
|||||||
@@ -196,7 +196,7 @@ fun mergeSmartCasts(a: Any?) {
|
|||||||
a.<!INAPPLICABLE_CANDIDATE!>compareTo<!>("")
|
a.<!INAPPLICABLE_CANDIDATE!>compareTo<!>("")
|
||||||
}
|
}
|
||||||
when (a) {
|
when (a) {
|
||||||
is String, is Any -> a.compareTo("")
|
is String, is Any -> a.<!UNRESOLVED_REFERENCE!>compareTo<!>("")
|
||||||
}
|
}
|
||||||
if (a is String && a is Any) {
|
if (a is String && a is Any) {
|
||||||
val i: Int = a.compareTo("")
|
val i: Int = a.compareTo("")
|
||||||
|
|||||||
Reference in New Issue
Block a user