Report a warning when comparing incompatible enums

I've put `isIncompatibleEnums` to TypeIntersector because I placed
all of its usages after all of the TypeIntersector::isIntersectionEmpty ones

^KT-28225 Fixed
This commit is contained in:
Denis Zharkov
2018-11-15 18:07:49 +03:00
parent a0d74be7cf
commit aa63ad4a45
12 changed files with 292 additions and 3 deletions
@@ -11,6 +11,6 @@ public enum JavaEnumB {}
enum class KotlinEnumA
enum class KotlinEnumB
fun jj(a: JavaEnumA, b: JavaEnumB) = a == b
fun jk(a: JavaEnumA, b: KotlinEnumB) = a == b
fun kk(a: KotlinEnumA, b: KotlinEnumB) = a == b
fun jj(a: JavaEnumA, b: JavaEnumB) = <!INCOMPATIBLE_ENUM_COMPARISON!>a == b<!>
fun jk(a: JavaEnumA, b: KotlinEnumB) = <!INCOMPATIBLE_ENUM_COMPARISON!>a == b<!>
fun kk(a: KotlinEnumA, b: KotlinEnumB) = <!INCOMPATIBLE_ENUM_COMPARISON!>a == b<!>
@@ -0,0 +1,90 @@
interface I {
fun foo()
}
enum class E1 : I {
A {
override fun foo() {
<!EQUALITY_NOT_APPLICABLE!>this == E2.A<!>
val q = this
when (q) {
this -> {}
E1.A -> {}
E1.B -> {}
<!INCOMPATIBLE_TYPES!>E2.A<!> -> {}
<!INCOMPATIBLE_TYPES!>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 -> {}
}
}
@@ -0,0 +1,56 @@
package
public fun foo1(/*0*/ e1: E1, /*1*/ e2: E2): kotlin.Unit
public fun foo2(/*0*/ e1: E1, /*1*/ e2: E2): kotlin.Unit
public fun foo3(/*0*/ e1: kotlin.Enum<E1>, /*1*/ e2: kotlin.Enum<E2>, /*2*/ e: kotlin.Enum<*>): kotlin.Unit
public final enum class E1 : kotlin.Enum<E1>, I {
enum entry A
enum entry B
private constructor E1()
public final override /*1*/ /*fake_override*/ val name: kotlin.String
public final override /*1*/ /*fake_override*/ val ordinal: kotlin.Int
protected final override /*1*/ /*fake_override*/ fun clone(): kotlin.Any
public final override /*1*/ /*fake_override*/ fun compareTo(/*0*/ other: E1): kotlin.Int
public final override /*2*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
protected/*protected and package*/ final override /*1*/ /*fake_override*/ /*isHiddenForResolutionEverywhereBesideSupercalls*/ fun finalize(): kotlin.Unit
public abstract override /*1*/ /*fake_override*/ fun foo(): kotlin.Unit
public final override /*1*/ /*fake_override*/ /*isHiddenForResolutionEverywhereBesideSupercalls*/ fun getDeclaringClass(): java.lang.Class<E1!>!
public final override /*2*/ /*fake_override*/ fun hashCode(): kotlin.Int
public open override /*2*/ /*fake_override*/ fun toString(): kotlin.String
// Static members
public final /*synthesized*/ fun valueOf(/*0*/ value: kotlin.String): E1
public final /*synthesized*/ fun values(): kotlin.Array<E1>
}
public final enum class E2 : kotlin.Enum<E2>, I {
enum entry A
enum entry B
private constructor E2()
public final override /*1*/ /*fake_override*/ val name: kotlin.String
public final override /*1*/ /*fake_override*/ val ordinal: kotlin.Int
protected final override /*1*/ /*fake_override*/ fun clone(): kotlin.Any
public final override /*1*/ /*fake_override*/ fun compareTo(/*0*/ other: E2): kotlin.Int
public final override /*2*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
protected/*protected and package*/ final override /*1*/ /*fake_override*/ /*isHiddenForResolutionEverywhereBesideSupercalls*/ fun finalize(): kotlin.Unit
public abstract override /*1*/ /*fake_override*/ fun foo(): kotlin.Unit
public final override /*1*/ /*fake_override*/ /*isHiddenForResolutionEverywhereBesideSupercalls*/ fun getDeclaringClass(): java.lang.Class<E2!>!
public final override /*2*/ /*fake_override*/ fun hashCode(): kotlin.Int
public open override /*2*/ /*fake_override*/ fun toString(): kotlin.String
// Static members
public final /*synthesized*/ fun valueOf(/*0*/ value: kotlin.String): E2
public final /*synthesized*/ fun values(): kotlin.Array<E2>
}
public interface I {
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public abstract fun foo(): kotlin.Unit
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
}
@@ -0,0 +1,58 @@
enum class E1 {
A, B
}
enum class E2 {
A, B
}
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 -> {}
}
}
@@ -0,0 +1,47 @@
package
public fun foo1(/*0*/ e1: E1, /*1*/ e2: E2): kotlin.Unit
public fun foo2(/*0*/ e1: E1, /*1*/ e2: E2): kotlin.Unit
public fun foo3(/*0*/ e1: kotlin.Enum<E1>, /*1*/ e2: kotlin.Enum<E2>, /*2*/ e: kotlin.Enum<*>): kotlin.Unit
public final enum class E1 : kotlin.Enum<E1> {
enum entry A
enum entry B
private constructor E1()
public final override /*1*/ /*fake_override*/ val name: kotlin.String
public final override /*1*/ /*fake_override*/ val ordinal: kotlin.Int
protected final override /*1*/ /*fake_override*/ fun clone(): kotlin.Any
public final override /*1*/ /*fake_override*/ fun compareTo(/*0*/ other: E1): kotlin.Int
public final override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
protected/*protected and package*/ final override /*1*/ /*fake_override*/ /*isHiddenForResolutionEverywhereBesideSupercalls*/ fun finalize(): kotlin.Unit
public final override /*1*/ /*fake_override*/ /*isHiddenForResolutionEverywhereBesideSupercalls*/ fun getDeclaringClass(): java.lang.Class<E1!>!
public final override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
// Static members
public final /*synthesized*/ fun valueOf(/*0*/ value: kotlin.String): E1
public final /*synthesized*/ fun values(): kotlin.Array<E1>
}
public final enum class E2 : kotlin.Enum<E2> {
enum entry A
enum entry B
private constructor E2()
public final override /*1*/ /*fake_override*/ val name: kotlin.String
public final override /*1*/ /*fake_override*/ val ordinal: kotlin.Int
protected final override /*1*/ /*fake_override*/ fun clone(): kotlin.Any
public final override /*1*/ /*fake_override*/ fun compareTo(/*0*/ other: E2): kotlin.Int
public final override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
protected/*protected and package*/ final override /*1*/ /*fake_override*/ /*isHiddenForResolutionEverywhereBesideSupercalls*/ fun finalize(): kotlin.Unit
public final override /*1*/ /*fake_override*/ /*isHiddenForResolutionEverywhereBesideSupercalls*/ fun getDeclaringClass(): java.lang.Class<E2!>!
public final override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
// Static members
public final /*synthesized*/ fun valueOf(/*0*/ value: kotlin.String): E2
public final /*synthesized*/ fun values(): kotlin.Array<E2>
}