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:
+39
@@ -81,8 +81,47 @@ public final class IC4 {
|
||||
public synthetic final method unbox-impl(): int
|
||||
}
|
||||
|
||||
@kotlin.jvm.JvmInline
|
||||
@kotlin.Metadata
|
||||
public final class IC5 {
|
||||
// source: 'inlineClassEqualsOverride.kt'
|
||||
private final field value: int
|
||||
private synthetic method <init>(p0: int): void
|
||||
public synthetic final static method box-impl(p0: int): IC5
|
||||
public static method constructor-impl(p0: int): int
|
||||
public method equals(p0: java.lang.Object): boolean
|
||||
public static method equals-impl(p0: int, p1: java.lang.Object): boolean
|
||||
public final static @org.jetbrains.annotations.NotNull method equals-impl0(p0: int, p1: int): java.lang.Void
|
||||
public final method getValue(): int
|
||||
public method hashCode(): int
|
||||
public static method hashCode-impl(p0: int): int
|
||||
public method toString(): java.lang.String
|
||||
public static method toString-impl(p0: int): java.lang.String
|
||||
public synthetic final method unbox-impl(): int
|
||||
}
|
||||
|
||||
@kotlin.jvm.JvmInline
|
||||
@kotlin.Metadata
|
||||
public final class IC6 {
|
||||
// source: 'inlineClassEqualsOverride.kt'
|
||||
private final field value: int
|
||||
private synthetic method <init>(p0: int): void
|
||||
public synthetic final static method box-impl(p0: int): IC6
|
||||
public static method constructor-impl(p0: int): int
|
||||
public final @org.jetbrains.annotations.NotNull method equals(@org.jetbrains.annotations.Nullable p0: java.lang.Object): java.lang.Void
|
||||
public final static @org.jetbrains.annotations.NotNull method equals-impl(p0: int, @org.jetbrains.annotations.Nullable p1: java.lang.Object): java.lang.Void
|
||||
public final static method equals-impl0(p0: int, p1: int): boolean
|
||||
public final method getValue(): int
|
||||
public method hashCode(): int
|
||||
public static method hashCode-impl(p0: int): int
|
||||
public method toString(): java.lang.String
|
||||
public static method toString-impl(p0: int): java.lang.String
|
||||
public synthetic final method unbox-impl(): int
|
||||
}
|
||||
|
||||
@kotlin.Metadata
|
||||
public final class InlineClassEqualsOverrideKt {
|
||||
// source: 'inlineClassEqualsOverride.kt'
|
||||
public synthetic final static method assertThrows(p0: kotlin.jvm.functions.Function0): boolean
|
||||
public final static @org.jetbrains.annotations.NotNull method box(): java.lang.String
|
||||
}
|
||||
|
||||
@@ -19,7 +19,7 @@ interface I {
|
||||
|
||||
OPTIONAL_JVM_INLINE_ANNOTATION
|
||||
value class IC2(val value: Int) : I {
|
||||
override fun equals(param: IC2): Boolean {
|
||||
override operator fun equals(param: IC2): Boolean {
|
||||
return abs(value - param.value) < 2
|
||||
}
|
||||
}
|
||||
@@ -34,6 +34,26 @@ value class IC4(val value: Int) {
|
||||
override fun equals(other: Any?) = TODO()
|
||||
}
|
||||
|
||||
OPTIONAL_JVM_INLINE_ANNOTATION
|
||||
value class IC5(val value: Int) {
|
||||
operator fun equals(other: IC5): Nothing = TODO()
|
||||
}
|
||||
|
||||
OPTIONAL_JVM_INLINE_ANNOTATION
|
||||
value class IC6(val value: Int) {
|
||||
override fun equals(other: Any?): Nothing = TODO()
|
||||
}
|
||||
|
||||
inline fun <reified T> assertThrows(block: () -> Unit): Boolean {
|
||||
try {
|
||||
block.invoke()
|
||||
} catch (t: Throwable) {
|
||||
return t is T
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
|
||||
fun box() = when {
|
||||
IC1(1.0) != IC1(1.05) -> "Fail 1.1"
|
||||
(IC1(1.0) as Any) != IC1(1.05) -> "Fail 1.2"
|
||||
@@ -68,5 +88,9 @@ fun box() = when {
|
||||
IC1(1.0) == Any() -> "Fail 7.1"
|
||||
(IC1(1.0) as Any) == Any() -> "Fail 7.2"
|
||||
|
||||
!assertThrows<NotImplementedError> { IC5(0) == IC5(1) } -> "Fail 8.1"
|
||||
!assertThrows<NotImplementedError> { IC6(0) == IC6(1) } -> "Fail 8.2"
|
||||
|
||||
|
||||
else -> "OK"
|
||||
}
|
||||
@@ -81,8 +81,47 @@ public final class IC4 {
|
||||
public synthetic final method unbox-impl(): int
|
||||
}
|
||||
|
||||
@kotlin.jvm.JvmInline
|
||||
@kotlin.Metadata
|
||||
public final class IC5 {
|
||||
// source: 'inlineClassEqualsOverride.kt'
|
||||
private final field value: int
|
||||
private synthetic method <init>(p0: int): void
|
||||
public synthetic final static method box-impl(p0: int): IC5
|
||||
public static method constructor-impl(p0: int): int
|
||||
public method equals(p0: java.lang.Object): boolean
|
||||
public static method equals-impl(p0: int, p1: java.lang.Object): boolean
|
||||
public final static @org.jetbrains.annotations.NotNull method equals-impl0(p0: int, p1: int): java.lang.Void
|
||||
public final method getValue(): int
|
||||
public method hashCode(): int
|
||||
public static method hashCode-impl(p0: int): int
|
||||
public method toString(): java.lang.String
|
||||
public static method toString-impl(p0: int): java.lang.String
|
||||
public synthetic final method unbox-impl(): int
|
||||
}
|
||||
|
||||
@kotlin.jvm.JvmInline
|
||||
@kotlin.Metadata
|
||||
public final class IC6 {
|
||||
// source: 'inlineClassEqualsOverride.kt'
|
||||
private final field value: int
|
||||
private synthetic method <init>(p0: int): void
|
||||
public synthetic final static method box-impl(p0: int): IC6
|
||||
public static method constructor-impl(p0: int): int
|
||||
public @org.jetbrains.annotations.NotNull method equals(@org.jetbrains.annotations.Nullable p0: java.lang.Object): java.lang.Void
|
||||
public static @org.jetbrains.annotations.NotNull method equals-impl(p0: int, @org.jetbrains.annotations.Nullable p1: java.lang.Object): java.lang.Void
|
||||
public final static method equals-impl0(p0: int, p1: int): boolean
|
||||
public final method getValue(): int
|
||||
public method hashCode(): int
|
||||
public static method hashCode-impl(p0: int): int
|
||||
public method toString(): java.lang.String
|
||||
public static method toString-impl(p0: int): java.lang.String
|
||||
public synthetic final method unbox-impl(): int
|
||||
}
|
||||
|
||||
@kotlin.Metadata
|
||||
public final class InlineClassEqualsOverrideKt {
|
||||
// source: 'inlineClassEqualsOverride.kt'
|
||||
public synthetic final static method assertThrows(p0: kotlin.jvm.functions.Function0): boolean
|
||||
public final static @org.jetbrains.annotations.NotNull method box(): java.lang.String
|
||||
}
|
||||
|
||||
+1
-1
@@ -7,7 +7,7 @@ import kotlin.math.abs
|
||||
|
||||
OPTIONAL_JVM_INLINE_ANNOTATION
|
||||
value class IC(val x: Double) {
|
||||
fun equals(other: IC): Boolean {
|
||||
operator fun equals(other: IC): Boolean {
|
||||
return abs(x - other.x) < 0.1
|
||||
}
|
||||
|
||||
|
||||
+4
-4
@@ -6,7 +6,7 @@
|
||||
OPTIONAL_JVM_INLINE_ANNOTATION
|
||||
value class IC1<T : Number>(val x: T) {
|
||||
fun equals(other: Int) = false
|
||||
fun equals(other: IC1<T>) = true
|
||||
operator fun equals(other: IC1<*>) = true
|
||||
}
|
||||
|
||||
class Generic<T, R>(val x: T, val y: R)
|
||||
@@ -14,19 +14,19 @@ class Generic<T, R>(val x: T, val y: R)
|
||||
OPTIONAL_JVM_INLINE_ANNOTATION
|
||||
value class IC2<T, R>(val value: Generic<T, R>) {
|
||||
fun equals(other: IC1<Double>) = false
|
||||
fun equals(other: IC2<T, R>) = true
|
||||
operator fun equals(other: IC2<*, *>) = true
|
||||
}
|
||||
|
||||
OPTIONAL_JVM_INLINE_ANNOTATION
|
||||
value class IC3<T>(val value: T) {
|
||||
fun equals(other: Int) = false
|
||||
fun equals(other: IC3<*>) = true
|
||||
operator fun equals(other: IC3<*>) = true
|
||||
}
|
||||
|
||||
OPTIONAL_JVM_INLINE_ANNOTATION
|
||||
value class IC4<T>(val value: T) {
|
||||
fun equals(other: String) = false
|
||||
fun equals(other: IC4<String>) = true
|
||||
operator fun equals(other: IC4<*>) = true
|
||||
}
|
||||
|
||||
|
||||
|
||||
+3
-3
@@ -6,7 +6,7 @@
|
||||
|
||||
OPTIONAL_JVM_INLINE_ANNOTATION
|
||||
value class A(val x: Int) {
|
||||
fun equals(other: A) = true
|
||||
operator fun equals(other: A) = true
|
||||
}
|
||||
|
||||
class C
|
||||
@@ -20,13 +20,13 @@ value class B2(val x: A?)
|
||||
|
||||
OPTIONAL_JVM_INLINE_ANNOTATION
|
||||
value class D1(val x: C) {
|
||||
fun equals(other: D1) = true
|
||||
operator fun equals(other: D1) = true
|
||||
}
|
||||
|
||||
|
||||
OPTIONAL_JVM_INLINE_ANNOTATION
|
||||
value class D2(val x: C?) {
|
||||
fun equals(other: D2) = true
|
||||
operator fun equals(other: D2) = true
|
||||
}
|
||||
|
||||
OPTIONAL_JVM_INLINE_ANNOTATION
|
||||
|
||||
+1
-1
@@ -5,7 +5,7 @@
|
||||
|
||||
OPTIONAL_JVM_INLINE_ANNOTATION
|
||||
value class A(val x: Int) {
|
||||
fun equals(other: A) = x % 5 == other.x % 5
|
||||
operator fun equals(other: A) = x % 5 == other.x % 5
|
||||
}
|
||||
|
||||
OPTIONAL_JVM_INLINE_ANNOTATION
|
||||
|
||||
Vendored
+10
-1
@@ -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
|
||||
}
|
||||
Vendored
+11
-1
@@ -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
|
||||
}
|
||||
|
||||
|
||||
+52
@@ -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()
|
||||
}
|
||||
+74
@@ -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
|
||||
}
|
||||
Vendored
-22
@@ -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) {
|
||||
}
|
||||
}
|
||||
Vendored
-20
@@ -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
|
||||
}
|
||||
Reference in New Issue
Block a user