Support of custom 'equals' and 'hashCode' in inline classes

'equals' from any made available for overriding in inline classes
'typed' equals made available for definition in inline classes
'typed' equals definition made compulsory if 'untyped' is overridden
'operator' keyword is allowed in 'typed' equals definition

^KT-24874: Fixed
This commit is contained in:
vladislav.grechko
2022-10-04 20:22:11 +02:00
committed by teamcity
parent 527e8dde27
commit e0c8142106
47 changed files with 684 additions and 53 deletions
@@ -0,0 +1,28 @@
// FIR_IDENTICAL
// WITH_STDLIB
// !DIAGNOSTICS: -DEBUG_INFO_SMARTCAST
// LANGUAGE: +CustomEqualsInInlineClasses
@JvmInline
value class IC1(val x: Int) {
<!INEFFICIENT_EQUALS_OVERRIDING_IN_INLINE_CLASS!>override fun equals(other: Any?): Boolean<!> {
if (other !is IC1) {
return false
}
return x == other.x
}
}
@JvmInline
value class IC2(val x: Int) {
override fun hashCode() = 0
}
@JvmInline
value class IC3(val x: Int) {
override fun equals(other: Any?) = true
fun equals(other: IC3) = true
override fun hashCode() = 0
}
@@ -0,0 +1,26 @@
package
@kotlin.jvm.JvmInline public final value class IC1 {
public constructor IC1(/*0*/ x: kotlin.Int)
public final val x: kotlin.Int
public open override /*1*/ 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 IC2 {
public constructor IC2(/*0*/ x: kotlin.Int)
public final val x: kotlin.Int
public open override /*1*/ /*synthesized*/ 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 IC3 {
public constructor IC3(/*0*/ x: kotlin.Int)
public final val x: kotlin.Int
public final 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
}
@@ -1,4 +1,4 @@
// !LANGUAGE: +InlineClasses, -JvmInlineValueClasses
// !LANGUAGE: +InlineClasses, -JvmInlineValueClasses, +CustomEqualsInInlineClasses
// !DIAGNOSTICS: -UNUSED_PARAMETER
inline class IC1(val x: Any) {
@@ -8,8 +8,8 @@ inline class IC1(val x: Any) {
fun <!RESERVED_MEMBER_INSIDE_VALUE_CLASS!>unbox<!>() {}
fun <!RESERVED_MEMBER_INSIDE_VALUE_CLASS!>unbox<!>(x: Any) {}
override fun <!RESERVED_MEMBER_INSIDE_VALUE_CLASS!>equals<!>(other: Any?): Boolean = true
override fun <!RESERVED_MEMBER_INSIDE_VALUE_CLASS!>hashCode<!>(): Int = 0
<!INEFFICIENT_EQUALS_OVERRIDING_IN_INLINE_CLASS!>override fun equals(other: Any?): Boolean<!> = true
override fun hashCode(): Int = 0
}
inline class IC2(val x: Any) {
@@ -19,15 +19,15 @@ inline class IC2(val x: Any) {
fun <!RESERVED_MEMBER_INSIDE_VALUE_CLASS!>unbox<!>(x: Any) {}
fun <!RESERVED_MEMBER_INSIDE_VALUE_CLASS!>unbox<!>(): Any = TODO()
fun <!RESERVED_MEMBER_INSIDE_VALUE_CLASS!>equals<!>(my: Any, other: Any): Boolean = true
fun <!RESERVED_MEMBER_INSIDE_VALUE_CLASS!>hashCode<!>(a: Any): Int = 0
fun equals(my: Any, other: Any): Boolean = true
fun hashCode(a: Any): Int = 0
}
inline class IC3(val x: Any) {
fun <!RESERVED_MEMBER_INSIDE_VALUE_CLASS!>box<!>(x: Any): Any = TODO()
fun <!RESERVED_MEMBER_INSIDE_VALUE_CLASS!>unbox<!>(x: Any): Any = TODO()
fun <!RESERVED_MEMBER_INSIDE_VALUE_CLASS!>equals<!>(): Boolean = true
fun equals(): Boolean = true
}
interface WithBox {
@@ -1,4 +1,4 @@
// !LANGUAGE: +InlineClasses, -JvmInlineValueClasses
// !LANGUAGE: +InlineClasses, -JvmInlineValueClasses, +CustomEqualsInInlineClasses
// !DIAGNOSTICS: -UNUSED_PARAMETER
inline class IC1(val x: Any) {
@@ -8,8 +8,8 @@ inline class IC1(val x: Any) {
fun <!RESERVED_MEMBER_INSIDE_VALUE_CLASS!>unbox<!>() {}
fun <!RESERVED_MEMBER_INSIDE_VALUE_CLASS!>unbox<!>(x: Any) {}
override fun <!RESERVED_MEMBER_INSIDE_VALUE_CLASS!>equals<!>(other: Any?): Boolean = true
override fun <!RESERVED_MEMBER_INSIDE_VALUE_CLASS!>hashCode<!>(): Int = 0
<!INEFFICIENT_EQUALS_OVERRIDING_IN_INLINE_CLASS!>override fun equals(other: Any?): Boolean<!> = true
override fun hashCode(): Int = 0
}
inline class IC2(val x: Any) {
@@ -19,15 +19,15 @@ inline class IC2(val x: Any) {
fun <!RESERVED_MEMBER_INSIDE_VALUE_CLASS!>unbox<!>(x: Any) {}
fun <!RESERVED_MEMBER_INSIDE_VALUE_CLASS!>unbox<!>(): Any = TODO()
fun <!RESERVED_MEMBER_INSIDE_VALUE_CLASS!>equals<!>(my: Any, other: Any): Boolean = true
fun <!RESERVED_MEMBER_INSIDE_VALUE_CLASS!>hashCode<!>(a: Any): Int = 0
fun equals(my: Any, other: Any): Boolean = true
fun hashCode(a: Any): Int = 0
}
inline class IC3(val x: Any) {
fun <!RESERVED_MEMBER_INSIDE_VALUE_CLASS!>box<!>(x: Any): Any = TODO()
fun <!RESERVED_MEMBER_INSIDE_VALUE_CLASS!>unbox<!>(x: Any): Any = TODO()
fun <!RESERVED_MEMBER_INSIDE_VALUE_CLASS!>equals<!>(): Boolean = true
fun equals(): Boolean = true
}
interface WithBox {
@@ -0,0 +1,22 @@
// 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) {
}
}
@@ -0,0 +1,20 @@
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
}
@@ -1,5 +1,5 @@
// !SKIP_JAVAC
// !LANGUAGE: +InlineClasses
// !LANGUAGE: +InlineClasses, +CustomEqualsInInlineClasses
// ALLOW_KOTLIN_PACKAGE
// !DIAGNOSTICS: -UNUSED_PARAMETER
@@ -15,8 +15,8 @@ value class IC1(val x: Any) {
fun <!RESERVED_MEMBER_INSIDE_VALUE_CLASS!>unbox<!>() {}
fun <!RESERVED_MEMBER_INSIDE_VALUE_CLASS!>unbox<!>(x: Any) {}
override fun <!RESERVED_MEMBER_INSIDE_VALUE_CLASS!>equals<!>(other: Any?): Boolean = true
override fun <!RESERVED_MEMBER_INSIDE_VALUE_CLASS!>hashCode<!>(): Int = 0
<!INEFFICIENT_EQUALS_OVERRIDING_IN_INLINE_CLASS!>override fun equals(other: Any?): Boolean<!> = true
override fun hashCode(): Int = 0
}
@JvmInline
@@ -27,8 +27,8 @@ value class IC2(val x: Any) {
fun <!RESERVED_MEMBER_INSIDE_VALUE_CLASS!>unbox<!>(x: Any) {}
fun <!RESERVED_MEMBER_INSIDE_VALUE_CLASS!>unbox<!>(): Any = TODO()
fun <!RESERVED_MEMBER_INSIDE_VALUE_CLASS!>equals<!>(my: Any, other: Any): Boolean = true
fun <!RESERVED_MEMBER_INSIDE_VALUE_CLASS!>hashCode<!>(a: Any): Int = 0
fun equals(my: Any, other: Any): Boolean = true
fun hashCode(a: Any): Int = 0
}
@JvmInline
@@ -36,7 +36,7 @@ value class IC3(val x: Any) {
fun <!RESERVED_MEMBER_INSIDE_VALUE_CLASS!>box<!>(x: Any): Any = TODO()
fun <!RESERVED_MEMBER_INSIDE_VALUE_CLASS!>unbox<!>(x: Any): Any = TODO()
fun <!RESERVED_MEMBER_INSIDE_VALUE_CLASS!>equals<!>(): Boolean = true
fun equals(): Boolean = true
}
interface WithBox {
@@ -1,5 +1,5 @@
// !SKIP_JAVAC
// !LANGUAGE: +InlineClasses
// !LANGUAGE: +InlineClasses, +CustomEqualsInInlineClasses
// ALLOW_KOTLIN_PACKAGE
// !DIAGNOSTICS: -UNUSED_PARAMETER
@@ -15,8 +15,8 @@ value class IC1(val x: Any) {
fun <!RESERVED_MEMBER_INSIDE_VALUE_CLASS!>unbox<!>() {}
fun <!RESERVED_MEMBER_INSIDE_VALUE_CLASS!>unbox<!>(x: Any) {}
override fun <!RESERVED_MEMBER_INSIDE_VALUE_CLASS!>equals<!>(other: Any?): Boolean = true
override fun <!RESERVED_MEMBER_INSIDE_VALUE_CLASS!>hashCode<!>(): Int = 0
<!INEFFICIENT_EQUALS_OVERRIDING_IN_INLINE_CLASS!>override fun equals(other: Any?): Boolean<!> = true
override fun hashCode(): Int = 0
}
@JvmInline
@@ -27,8 +27,8 @@ value class IC2(val x: Any) {
fun <!RESERVED_MEMBER_INSIDE_VALUE_CLASS!>unbox<!>(x: Any) {}
fun <!RESERVED_MEMBER_INSIDE_VALUE_CLASS!>unbox<!>(): Any = TODO()
fun <!RESERVED_MEMBER_INSIDE_VALUE_CLASS!>equals<!>(my: Any, other: Any): Boolean = true
fun <!RESERVED_MEMBER_INSIDE_VALUE_CLASS!>hashCode<!>(a: Any): Int = 0
fun equals(my: Any, other: Any): Boolean = true
fun hashCode(a: Any): Int = 0
}
@JvmInline
@@ -36,7 +36,7 @@ value class IC3(val x: Any) {
fun <!RESERVED_MEMBER_INSIDE_VALUE_CLASS!>box<!>(x: Any): Any = TODO()
fun <!RESERVED_MEMBER_INSIDE_VALUE_CLASS!>unbox<!>(x: Any): Any = TODO()
fun <!RESERVED_MEMBER_INSIDE_VALUE_CLASS!>equals<!>(): Boolean = true
fun equals(): Boolean = true
}
interface WithBox {