[FIR] Do not terminate smartcast CFG nodes when result is Nothing

Terminating a CFG node because the result is Nothing should be reserved
for explicit Nothing type definitions, and not apply when smartcasting.
This allows boolean expressions to propagate implications correctly even
when the RHS is impossible or will never be executed.

^KT-47931 Fixed
This commit is contained in:
Brian Norman
2023-11-14 10:21:38 -06:00
committed by Space Team
parent e92fab65aa
commit a4b3b08e59
6 changed files with 298 additions and 309 deletions
@@ -78,7 +78,7 @@ fun case_7() {
// TESTCASE NUMBER: 8
fun case_8(x: TypealiasString) {
if (<!SENSELESS_COMPARISON!>x == null<!> && <!SENSELESS_COMPARISON!><!DEBUG_INFO_EXPRESSION_TYPE("TypealiasString & kotlin.Nothing")!>x<!> == null<!>) <!DEBUG_INFO_EXPRESSION_TYPE("TypealiasString")!>x<!>
if (<!SENSELESS_COMPARISON!>x == null<!> && <!SENSELESS_COMPARISON!><!DEBUG_INFO_EXPRESSION_TYPE("TypealiasString & kotlin.Nothing")!>x<!> == null<!>) <!DEBUG_INFO_EXPRESSION_TYPE("TypealiasString & kotlin.Nothing")!>x<!>
}
// TESTCASE NUMBER: 9
@@ -244,7 +244,7 @@ fun case_12(x: TypealiasNullableString, y: TypealiasNullableString, z1: Nothing?
// TESTCASE NUMBER: 13
fun case_13(x: EmptyClass12_48?, z: Nothing?) =
if (x == z || <!SENSELESS_COMPARISON!>x === z<!> && <!SENSELESS_COMPARISON!>x <!UNREACHABLE_CODE!>== z<!><!>) {
if (x == z || <!SENSELESS_COMPARISON!>x === z<!> && <!SENSELESS_COMPARISON!>x == z<!>) {
throw Exception()
} else {
<!DEBUG_INFO_EXPRESSION_TYPE("othertypes.EmptyClass12_48? & othertypes.EmptyClass12_48")!>x<!>
@@ -289,7 +289,7 @@ fun case_14() {
// TESTCASE NUMBER: 15
fun case_15(x: TypealiasNullableString) {
val y = null
val <!UNUSED_VARIABLE!>z<!> = if (x === null || <!SENSELESS_COMPARISON!>y == x<!> && <!SENSELESS_COMPARISON!>x <!UNREACHABLE_CODE!>=== y<!><!> || <!SENSELESS_COMPARISON!>null === x<!>) "" else {
val <!UNUSED_VARIABLE!>z<!> = if (x === null || <!SENSELESS_COMPARISON!>y == x<!> && <!SENSELESS_COMPARISON!>x === y<!> || <!SENSELESS_COMPARISON!>null === x<!>) "" else {
<!DEBUG_INFO_EXPRESSION_TYPE("TypealiasNullableString & kotlin.String")!>x<!>
<!DEBUG_INFO_EXPRESSION_TYPE("TypealiasNullableString & kotlin.String")!>x<!>.equals(null)
<!DEBUG_INFO_EXPRESSION_TYPE("TypealiasNullableString & kotlin.String")!>x<!>.propT
@@ -310,7 +310,7 @@ fun case_16() {
if (<!SENSELESS_COMPARISON!>x !== y<!>) {
<!DEBUG_INFO_EXPRESSION_TYPE("TypealiasNullableNothing & kotlin.Nothing")!>x<!>
<!UNREACHABLE_CODE!><!DEBUG_INFO_EXPRESSION_TYPE("TypealiasNullableNothing & kotlin.Nothing")!>x<!>.hashCode()<!>
<!DEBUG_INFO_EXPRESSION_TYPE("TypealiasNullableNothing & kotlin.Nothing")!>x<!>.hashCode()
}
}
@@ -722,7 +722,7 @@ fun case_36(x: Any) {
if (<!SENSELESS_COMPARISON!>x == z<!>) {
<!DEBUG_INFO_EXPRESSION_TYPE("kotlin.Any & kotlin.Nothing")!>x<!>
<!UNREACHABLE_CODE!><!DEBUG_INFO_EXPRESSION_TYPE("kotlin.Any & kotlin.Nothing")!>x<!>.<!NEW_INFERENCE_NO_INFORMATION_FOR_PARAMETER!>java<!><!>
<!DEBUG_INFO_EXPRESSION_TYPE("kotlin.Any & kotlin.Nothing")!>x<!>.<!NEW_INFERENCE_NO_INFORMATION_FOR_PARAMETER!>java<!>
}
}
@@ -744,7 +744,7 @@ fun case_38() {
if (<!SENSELESS_COMPARISON!>Object.prop_2 != z<!>)
else {
Object.prop_2
<!UNREACHABLE_CODE!>Object.prop_2.<!NEW_INFERENCE_NO_INFORMATION_FOR_PARAMETER!>java<!><!>
Object.prop_2.<!NEW_INFERENCE_NO_INFORMATION_FOR_PARAMETER!>java<!>
}
}
@@ -918,7 +918,7 @@ fun case_51() {
val x: TypealiasNullableNothing = null
val z: Nothing? = null
if (<!SENSELESS_COMPARISON!>x === z<!> || <!SENSELESS_COMPARISON!>z <!UNREACHABLE_CODE!>==<!> x<!> && <!SENSELESS_COMPARISON, UNREACHABLE_CODE!>x == z<!> || false || false || false) {
if (<!SENSELESS_COMPARISON!>x === z<!> || <!SENSELESS_COMPARISON!>z == x<!> && <!SENSELESS_COMPARISON!>x == z<!> || false || false || false) {
<!DEBUG_INFO_EXPRESSION_TYPE("TypealiasNullableNothing")!>x<!>
<!DEBUG_INFO_EXPRESSION_TYPE("TypealiasNullableNothing")!>x<!>.hashCode()
}
@@ -1002,7 +1002,7 @@ fun case_57(a: (() -> Unit)) {
if (<!SENSELESS_COMPARISON!>a == z<!>) {
<!DEBUG_INFO_EXPRESSION_TYPE("kotlin.Function0<kotlin.Unit> & kotlin.Nothing")!>a<!>
<!UNREACHABLE_CODE!><!DEBUG_INFO_EXPRESSION_TYPE("kotlin.Function0<kotlin.Unit> & kotlin.Nothing")!>a<!>.<!NEW_INFERENCE_NO_INFORMATION_FOR_PARAMETER!>java<!><!>
<!DEBUG_INFO_EXPRESSION_TYPE("kotlin.Function0<kotlin.Unit> & kotlin.Nothing")!>a<!>.<!NEW_INFERENCE_NO_INFORMATION_FOR_PARAMETER!>java<!>
}
}
@@ -48,8 +48,8 @@ fun case_1(x: Any?) {
* ISSUES: KT-28159
*/
fun case_2(x: Nothing?) {
if (<!SENSELESS_COMPARISON!>x !== null<!> && <!SENSELESS_COMPARISON!>x <!UNREACHABLE_CODE!>!== null<!><!>) {
<!DEBUG_INFO_EXPRESSION_TYPE("kotlin.Nothing?")!>x<!>
if (<!SENSELESS_COMPARISON!>x !== null<!> && <!SENSELESS_COMPARISON!>x !== null<!>) {
<!DEBUG_INFO_EXPRESSION_TYPE("kotlin.Nothing? & kotlin.Nothing")!>x<!>
}
}
@@ -90,17 +90,17 @@ fun case_4(x: Char?) {
fun case_5() {
val x: Unit? = null
if (x !== null || <!SENSELESS_COMPARISON!>x !== null<!> && <!SENSELESS_COMPARISON!>x <!UNREACHABLE_CODE!>!== null<!><!> || <!SENSELESS_COMPARISON!>x !== null<!> && <!SENSELESS_COMPARISON!>x <!UNREACHABLE_CODE!>!== null<!><!>) {
<!DEBUG_INFO_EXPRESSION_TYPE("kotlin.Unit?")!>x<!>
<!DEBUG_INFO_EXPRESSION_TYPE("kotlin.Unit?")!>x<!><!UNSAFE_CALL!>.<!>equals(null)
<!DEBUG_INFO_EXPRESSION_TYPE("kotlin.Unit?")!>x<!>.propT
<!DEBUG_INFO_EXPRESSION_TYPE("kotlin.Unit?")!>x<!><!UNSAFE_CALL!>.<!>propAny
<!DEBUG_INFO_EXPRESSION_TYPE("kotlin.Unit?")!>x<!>.propNullableT
<!DEBUG_INFO_EXPRESSION_TYPE("kotlin.Unit?")!>x<!>.propNullableAny
<!DEBUG_INFO_EXPRESSION_TYPE("kotlin.Unit?")!>x<!>.funT()
<!DEBUG_INFO_EXPRESSION_TYPE("kotlin.Unit?")!>x<!><!UNSAFE_CALL!>.<!>funAny()
<!DEBUG_INFO_EXPRESSION_TYPE("kotlin.Unit?")!>x<!>.funNullableT()
<!DEBUG_INFO_EXPRESSION_TYPE("kotlin.Unit?")!>x<!>.funNullableAny()
if (x !== null || <!SENSELESS_COMPARISON!>x !== null<!> && <!SENSELESS_COMPARISON!>x !== null<!> || <!SENSELESS_COMPARISON!>x !== null<!> && <!SENSELESS_COMPARISON!>x !== null<!>) {
<!DEBUG_INFO_EXPRESSION_TYPE("kotlin.Unit? & kotlin.Unit")!>x<!>
<!DEBUG_INFO_EXPRESSION_TYPE("kotlin.Unit? & kotlin.Unit")!>x<!>.equals(null)
<!DEBUG_INFO_EXPRESSION_TYPE("kotlin.Unit? & kotlin.Unit")!>x<!>.propT
<!DEBUG_INFO_EXPRESSION_TYPE("kotlin.Unit? & kotlin.Unit")!>x<!>.propAny
<!DEBUG_INFO_EXPRESSION_TYPE("kotlin.Unit? & kotlin.Unit")!>x<!>.propNullableT
<!DEBUG_INFO_EXPRESSION_TYPE("kotlin.Unit? & kotlin.Unit")!>x<!>.propNullableAny
<!DEBUG_INFO_EXPRESSION_TYPE("kotlin.Unit? & kotlin.Unit")!>x<!>.funT()
<!DEBUG_INFO_EXPRESSION_TYPE("kotlin.Unit? & kotlin.Unit")!>x<!>.funAny()
<!DEBUG_INFO_EXPRESSION_TYPE("kotlin.Unit? & kotlin.Unit")!>x<!>.funNullableT()
<!DEBUG_INFO_EXPRESSION_TYPE("kotlin.Unit? & kotlin.Unit")!>x<!>.funNullableAny()
}
}
@@ -274,7 +274,7 @@ fun case_14() {
// TESTCASE NUMBER: 15
fun case_15(x: TypealiasString?) {
<!CAN_BE_VAL!>var<!> y = null
val <!UNUSED_VARIABLE!>t<!> = <!DEBUG_INFO_EXPRESSION_TYPE("kotlin.String")!>if (x === null || <!SENSELESS_COMPARISON!>x == y<!> && <!SENSELESS_COMPARISON!>x <!UNREACHABLE_CODE!>=== y<!><!>) "" else {
val <!UNUSED_VARIABLE!>t<!> = <!DEBUG_INFO_EXPRESSION_TYPE("kotlin.String")!>if (x === null || <!SENSELESS_COMPARISON!>x == y<!> && <!SENSELESS_COMPARISON!>x === y<!>) "" else {
<!DEBUG_INFO_EXPRESSION_TYPE("TypealiasString? & kotlin.String")!>x<!>.equals(null)
<!DEBUG_INFO_EXPRESSION_TYPE("TypealiasString? & kotlin.String")!>x<!>.propT
<!DEBUG_INFO_EXPRESSION_TYPE("TypealiasString? & kotlin.String")!>x<!>.propAny
@@ -295,7 +295,7 @@ fun case_16() {
if (<!SENSELESS_COMPARISON!>x != null<!> || <!SENSELESS_COMPARISON!>x !== null<!> || <!SENSELESS_COMPARISON!>x != y<!>) {
<!DEBUG_INFO_EXPRESSION_TYPE("TypealiasNothing? & kotlin.Nothing")!>x<!>
<!UNREACHABLE_CODE!><!DEBUG_INFO_EXPRESSION_TYPE("TypealiasNothing? & kotlin.Nothing")!>x<!>.hashCode()<!>
<!DEBUG_INFO_EXPRESSION_TYPE("TypealiasNothing? & kotlin.Nothing")!>x<!>.hashCode()
}
}