[FIR] Don't miss modality of anonymous objects in canHaveSubtypes()

They are not `FirRegularClassSymbol`, but are
final. `FirClassSymbol` is enough, because
`toSymbol()` returns `FirClassifierSymbol`, and:

- type parameters are always expected to have
  subtypes
- typealiases have been expanded in the
  previous line
This commit is contained in:
Nikolay Lunyak
2024-02-26 16:12:55 +02:00
committed by Space Team
parent 226d4df277
commit bb812add14
4 changed files with 3 additions and 94 deletions
@@ -592,7 +592,7 @@ fun ConeKotlinType.canHaveSubtypes(session: FirSession): Boolean {
return true
}
val expandedType = fullyExpandedType(session)
val classSymbol = expandedType.toSymbol(session) as? FirRegularClassSymbol ?: return true
val classSymbol = expandedType.toSymbol(session) as? FirClassSymbol ?: return true
// In K2 enum classes are final, though enum entries are their subclasses (which is a compiler implementation detail).
if (classSymbol.isEnumClass || classSymbol.isExpect || classSymbol.modality != Modality.FINAL) {
return true
@@ -1,92 +0,0 @@
// !LANGUAGE: -ProhibitComparisonOfIncompatibleEnums
interface I {
fun foo()
}
enum class E1 : I {
A {
override fun foo() {
<!INCOMPATIBLE_ENUM_COMPARISON!>this == E2.A<!>
val q = this
when (q) {
this -> {}
E1.A -> {}
E1.B -> {}
<!INCOMPATIBLE_ENUM_COMPARISON!>E2.A<!> -> {}
<!INCOMPATIBLE_ENUM_COMPARISON!>E2.B<!> -> {}
else -> {}
}
}
},
B {
override fun foo() {
}
}
}
enum class E2 : I {
A {
override fun foo() {
}
},
B {
override fun foo() {
}
}
}
fun foo1(e1: E1, e2: E2) {
<!INCOMPATIBLE_ENUM_COMPARISON!>e1 == e2<!>
<!INCOMPATIBLE_ENUM_COMPARISON!>e1 != e2<!>
<!INCOMPATIBLE_ENUM_COMPARISON!>e1 == E2.A<!>
<!INCOMPATIBLE_ENUM_COMPARISON!>E1.B == e2<!>
<!INCOMPATIBLE_ENUM_COMPARISON!>E1.A == E2.B<!>
e1 == E1.A
E1.A == e1
e2 == E2.B
E2.B == e2
}
fun foo2(e1: E1, e2: E2) {
when (e1) {
E1.A -> {}
<!INCOMPATIBLE_ENUM_COMPARISON!>E2.A<!> -> {}
<!INCOMPATIBLE_ENUM_COMPARISON!>E2.B<!> -> {}
e1 -> {}
<!INCOMPATIBLE_ENUM_COMPARISON!>e2<!> -> {}
else -> {}
}
}
fun foo3(e1: Enum<E1>, e2: Enum<E2>, e: Enum<*>) {
e1 == e
e1 == e2
e1 == E1.A
e1 == E2.A
when (e1) {
e1 -> {}
e2 -> {}
e -> {}
E1.A -> {}
E2.A -> {}
else -> {}
}
when (e) {
e -> {}
e2 -> {}
E1.A -> {}
E2.A -> {}
else -> {}
}
}
@@ -1,3 +1,4 @@
// FIR_IDENTICAL
// !LANGUAGE: -ProhibitComparisonOfIncompatibleEnums
interface I {
@@ -585,7 +585,7 @@ fun case_29(x: Boolean) {
if (false || false || false || false || y !== v) {
val t = <!DEBUG_INFO_EXPRESSION_TYPE("<anonymous>?")!><!UNSAFE_IMPLICIT_INVOKE_CALL!>y<!>()<!>
if (<!EQUALITY_NOT_APPLICABLE_WARNING!>z !== t<!> || false) {
if (<!EQUALITY_NOT_APPLICABLE!>z !== t<!> || false) {
<!DEBUG_INFO_EXPRESSION_TYPE("<anonymous>?")!>t<!><!UNSAFE_CALL!>.<!>a
<!DEBUG_INFO_EXPRESSION_TYPE("<anonymous>?")!>t<!><!UNSAFE_CALL!>.<!>equals(null)
<!DEBUG_INFO_EXPRESSION_TYPE("<anonymous>?")!>t<!>.propT