Improve support of custom equals in inline classes

- Ensure that typed equals parameter's type is a star projection of
  corresponding inline class

- Make possible to declare typed equals that returns 'Nothing'

- Forbid type parameters in typed equals operator declaration

^KT-54909 fixed
^KT-54910 fixed
This commit is contained in:
vladislav.grechko
2022-11-11 16:44:03 +01:00
parent 02484baf07
commit 36b8ba8df3
38 changed files with 369 additions and 136 deletions
@@ -22,7 +22,16 @@ value class IC2(val x: Int) {
value class IC3(val x: Int) {
override fun equals(other: Any?) = true
fun equals(other: IC3) = true
operator fun equals(other: IC3) = true
override fun hashCode() = 0
}
@JvmInline
value class IC4<T>(val x: Int) {
override fun <!INEFFICIENT_EQUALS_OVERRIDING_IN_INLINE_CLASS!>equals<!>(other: Any?) = true
fun equals(other: IC4<T>) = true
override fun hashCode() = 0
}
@@ -19,8 +19,18 @@ package
@kotlin.jvm.JvmInline public final value class IC3 {
public constructor IC3(/*0*/ x: kotlin.Int)
public final val x: kotlin.Int
public final fun equals(/*0*/ other: IC3): kotlin.Boolean
public final operator fun equals(/*0*/ other: IC3): kotlin.Boolean
public open override /*1*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public open override /*1*/ fun hashCode(): kotlin.Int
public open override /*1*/ /*synthesized*/ fun toString(): kotlin.String
}
@kotlin.jvm.JvmInline public final value class IC4</*0*/ T> {
public constructor IC4</*0*/ T>(/*0*/ x: kotlin.Int)
public final val x: kotlin.Int
public final fun equals(/*0*/ other: IC4<T>): kotlin.Boolean
public open override /*1*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public open override /*1*/ fun hashCode(): kotlin.Int
public open override /*1*/ /*synthesized*/ fun toString(): kotlin.String
}
@@ -0,0 +1,52 @@
// FIR_IDENTICAL
// WITH_STDLIB
// !DIAGNOSTICS: -DEBUG_INFO_SMARTCAST
// LANGUAGE: +CustomEqualsInInlineClasses
@JvmInline
value class IC1(val x: Int) {
override fun equals(other: Any?) = true
operator fun equals(other: IC1) = true
override fun hashCode() = 0
}
@JvmInline
value class IC2(val x: Int) {
<!INAPPLICABLE_OPERATOR_MODIFIER!>operator<!> fun equals(other: IC1) = true
<!INAPPLICABLE_OPERATOR_MODIFIER!>operator<!> fun equals(other: IC2) {
}
}
@JvmInline
value class IC3<T>(val x: T) {
<!INAPPLICABLE_OPERATOR_MODIFIER!>operator<!> fun equals(other: IC3<T>) = true
}
@JvmInline
value class IC4<T>(val x: T) {
<!INAPPLICABLE_OPERATOR_MODIFIER!>operator<!> fun equals(other: IC4<String>) = true
}
@JvmInline
value class IC5<T: Number>(val x: T) {
<!INAPPLICABLE_OPERATOR_MODIFIER!>operator<!> fun equals(other: T) = true
}
@JvmInline
value class IC6<T, R>(val x: T) {
operator fun<!TYPE_PARAMETERS_NOT_ALLOWED!><S1, S2><!> equals(other: IC6<*, *>) = true
}
@JvmInline
value class IC7<T, R>(val x: T) {
operator fun equals(other: IC7<*, *>) = true
}
@JvmInline
value class IC8<T, R>(val x: T) {
operator fun equals(other: IC8<*, *>): Nothing = TODO()
}
@@ -0,0 +1,74 @@
package
@kotlin.jvm.JvmInline public final value class IC1 {
public constructor IC1(/*0*/ x: kotlin.Int)
public final val x: kotlin.Int
public final operator fun equals(/*0*/ other: IC1): kotlin.Boolean
public open override /*1*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public open override /*1*/ fun hashCode(): kotlin.Int
public open override /*1*/ /*synthesized*/ fun toString(): kotlin.String
}
@kotlin.jvm.JvmInline public final value class IC2 {
public constructor IC2(/*0*/ x: kotlin.Int)
public final val x: kotlin.Int
public final operator fun equals(/*0*/ other: IC1): kotlin.Boolean
public final operator fun equals(/*0*/ other: IC2): kotlin.Unit
public open override /*1*/ /*synthesized*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public open override /*1*/ /*synthesized*/ fun hashCode(): kotlin.Int
public open override /*1*/ /*synthesized*/ fun toString(): kotlin.String
}
@kotlin.jvm.JvmInline public final value class IC3</*0*/ T> {
public constructor IC3</*0*/ T>(/*0*/ x: T)
public final val x: T
public final operator fun equals(/*0*/ other: IC3<T>): kotlin.Boolean
public open override /*1*/ /*synthesized*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public open override /*1*/ /*synthesized*/ fun hashCode(): kotlin.Int
public open override /*1*/ /*synthesized*/ fun toString(): kotlin.String
}
@kotlin.jvm.JvmInline public final value class IC4</*0*/ T> {
public constructor IC4</*0*/ T>(/*0*/ x: T)
public final val x: T
public final operator fun equals(/*0*/ other: IC4<kotlin.String>): kotlin.Boolean
public open override /*1*/ /*synthesized*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public open override /*1*/ /*synthesized*/ fun hashCode(): kotlin.Int
public open override /*1*/ /*synthesized*/ fun toString(): kotlin.String
}
@kotlin.jvm.JvmInline public final value class IC5</*0*/ T : kotlin.Number> {
public constructor IC5</*0*/ T : kotlin.Number>(/*0*/ x: T)
public final val x: T
public final operator fun equals(/*0*/ other: T): kotlin.Boolean
public open override /*1*/ /*synthesized*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public open override /*1*/ /*synthesized*/ fun hashCode(): kotlin.Int
public open override /*1*/ /*synthesized*/ fun toString(): kotlin.String
}
@kotlin.jvm.JvmInline public final value class IC6</*0*/ T, /*1*/ R> {
public constructor IC6</*0*/ T, /*1*/ R>(/*0*/ x: T)
public final val x: T
public final operator fun </*0*/ S1, /*1*/ S2> equals(/*0*/ other: IC6<*, *>): kotlin.Boolean
public open override /*1*/ /*synthesized*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public open override /*1*/ /*synthesized*/ fun hashCode(): kotlin.Int
public open override /*1*/ /*synthesized*/ fun toString(): kotlin.String
}
@kotlin.jvm.JvmInline public final value class IC7</*0*/ T, /*1*/ R> {
public constructor IC7</*0*/ T, /*1*/ R>(/*0*/ x: T)
public final val x: T
public final operator fun equals(/*0*/ other: IC7<*, *>): kotlin.Boolean
public open override /*1*/ /*synthesized*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public open override /*1*/ /*synthesized*/ fun hashCode(): kotlin.Int
public open override /*1*/ /*synthesized*/ fun toString(): kotlin.String
}
@kotlin.jvm.JvmInline public final value class IC8</*0*/ T, /*1*/ R> {
public constructor IC8</*0*/ T, /*1*/ R>(/*0*/ x: T)
public final val x: T
public final operator fun equals(/*0*/ other: IC8<*, *>): kotlin.Nothing
public open override /*1*/ /*synthesized*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public open override /*1*/ /*synthesized*/ fun hashCode(): kotlin.Int
public open override /*1*/ /*synthesized*/ fun toString(): kotlin.String
}
@@ -1,22 +0,0 @@
// FIR_IDENTICAL
// WITH_STDLIB
// !DIAGNOSTICS: -DEBUG_INFO_SMARTCAST
// LANGUAGE: +CustomEqualsInInlineClasses
@JvmInline
value class IC1(val x: Int) {
override fun equals(other: Any?) = true
operator fun equals(other: IC1) = true
override fun hashCode() = 0
}
@JvmInline
value class IC2(val x: Int) {
<!INAPPLICABLE_OPERATOR_MODIFIER!>operator<!> fun equals(other: IC1) = true
<!INAPPLICABLE_OPERATOR_MODIFIER!>operator<!> fun equals(other: IC2) {
}
}
@@ -1,20 +0,0 @@
package
@kotlin.jvm.JvmInline public final value class IC1 {
public constructor IC1(/*0*/ x: kotlin.Int)
public final val x: kotlin.Int
public final operator fun equals(/*0*/ other: IC1): kotlin.Boolean
public open override /*1*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public open override /*1*/ fun hashCode(): kotlin.Int
public open override /*1*/ /*synthesized*/ fun toString(): kotlin.String
}
@kotlin.jvm.JvmInline public final value class IC2 {
public constructor IC2(/*0*/ x: kotlin.Int)
public final val x: kotlin.Int
public final operator fun equals(/*0*/ other: IC1): kotlin.Boolean
public final operator fun equals(/*0*/ other: IC2): kotlin.Unit
public open override /*1*/ /*synthesized*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public open override /*1*/ /*synthesized*/ fun hashCode(): kotlin.Int
public open override /*1*/ /*synthesized*/ fun toString(): kotlin.String
}