From 817afcd4afbc0ed2429875f9113cb61b3071c8cb Mon Sep 17 00:00:00 2001 From: "vladislav.grechko" Date: Wed, 12 Oct 2022 17:27:00 +0200 Subject: [PATCH] KT-MR-7307 review fixes --- .../api/fir/diagnostics/KtFirDiagnostics.kt | 2 +- .../fir/diagnostics/KtFirDiagnosticsImpl.kt | 2 +- ...CompilerTestFE10TestdataTestGenerated.java | 6 +- .../inlineClasses/inlineClassMembers.kt | 2 +- ...irOldFrontendDiagnosticsTestGenerated.java | 6 +- ...DiagnosticsWithLightTreeTestGenerated.java | 6 +- .../diagnostics/FirDiagnosticsList.kt | 2 +- .../fir/analysis/diagnostics/FirErrors.kt | 2 +- .../FirInlineClassDeclarationChecker.kt | 25 ++++++--- .../checkers/declaration/declarationUtils.kt | 17 ++---- .../FirBlackBoxCodegenTestGenerated.java | 6 ++ .../kotlin/fir/resolve/DeclarationUtils.kt | 2 + .../jetbrains/kotlin/diagnostics/Errors.java | 4 +- .../inlineClassTypedEqualsGenerics.kt | 55 +++++++++++++++++++ ...efficientEqualsOverridingInInlineClass.kt} | 2 +- ...fficientEqualsOverridingInInlineClass.txt} | 0 ...mbersAndConstructsInsideInlineClass.fir.kt | 2 +- ...edMembersAndConstructsInsideInlineClass.kt | 2 +- ...embersAndConstructsInsideValueClass.fir.kt | 2 +- ...vedMembersAndConstructsInsideValueClass.kt | 2 +- .../test/runners/DiagnosticTestGenerated.java | 6 +- .../IrBlackBoxCodegenTestGenerated.java | 6 ++ .../kotlin/config/LanguageVersionSettings.kt | 2 +- .../kotlin/descriptors/descriptorUtil.kt | 6 +- 24 files changed, 118 insertions(+), 49 deletions(-) create mode 100644 compiler/testData/codegen/box/inlineClasses/inlineClassTypedEqualsGenerics.kt rename compiler/testData/diagnostics/tests/inlineClasses/{illegalEqualsOverridingInInlineClass.kt => inefficientEqualsOverridingInInlineClass.kt} (82%) rename compiler/testData/diagnostics/tests/inlineClasses/{illegalEqualsOverridingInInlineClass.txt => inefficientEqualsOverridingInInlineClass.txt} (100%) diff --git a/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/diagnostics/KtFirDiagnostics.kt b/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/diagnostics/KtFirDiagnostics.kt index 2e6ca203181..de0746fd526 100644 --- a/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/diagnostics/KtFirDiagnostics.kt +++ b/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/diagnostics/KtFirDiagnostics.kt @@ -2704,7 +2704,7 @@ sealed class KtFirDiagnostic : KtDiagnosticWithPsi { override val diagnosticClass get() = RedundantInlineSuspendFunctionType::class } - abstract class InefficientEqualsOverridingInInlineClass : KtFirDiagnostic() { + abstract class InefficientEqualsOverridingInInlineClass : KtFirDiagnostic() { override val diagnosticClass get() = InefficientEqualsOverridingInInlineClass::class abstract val className: String } diff --git a/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/diagnostics/KtFirDiagnosticsImpl.kt b/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/diagnostics/KtFirDiagnosticsImpl.kt index ee48eedcbae..c02ece3bb4a 100644 --- a/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/diagnostics/KtFirDiagnosticsImpl.kt +++ b/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/diagnostics/KtFirDiagnosticsImpl.kt @@ -3265,7 +3265,7 @@ internal class InefficientEqualsOverridingInInlineClassImpl( override val className: String, override val firDiagnostic: KtPsiDiagnostic, override val token: KtLifetimeToken, -) : KtFirDiagnostic.InefficientEqualsOverridingInInlineClass(), KtAbstractFirDiagnostic +) : KtFirDiagnostic.InefficientEqualsOverridingInInlineClass(), KtAbstractFirDiagnostic internal class CannotAllUnderImportFromSingletonImpl( override val objectName: Name, diff --git a/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/diagnostic/compiler/based/DiagnosisCompilerTestFE10TestdataTestGenerated.java b/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/diagnostic/compiler/based/DiagnosisCompilerTestFE10TestdataTestGenerated.java index fa87fb57e58..5949ca3821c 100644 --- a/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/diagnostic/compiler/based/DiagnosisCompilerTestFE10TestdataTestGenerated.java +++ b/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/diagnostic/compiler/based/DiagnosisCompilerTestFE10TestdataTestGenerated.java @@ -17855,9 +17855,9 @@ public class DiagnosisCompilerTestFE10TestdataTestGenerated extends AbstractDiag } @Test - @TestMetadata("illegalEqualsOverridingInInlineClass.kt") - public void testIllegalEqualsOverridingInInlineClass() throws Exception { - runTest("compiler/testData/diagnostics/tests/inlineClasses/illegalEqualsOverridingInInlineClass.kt"); + @TestMetadata("inefficientEqualsOverridingInInlineClass.kt") + public void testInefficientEqualsOverridingInInlineClass() throws Exception { + runTest("compiler/testData/diagnostics/tests/inlineClasses/inefficientEqualsOverridingInInlineClass.kt"); } @Test diff --git a/compiler/fir/analysis-tests/testData/resolve/inlineClasses/inlineClassMembers.kt b/compiler/fir/analysis-tests/testData/resolve/inlineClasses/inlineClassMembers.kt index 5a7018fee20..919842cee90 100644 --- a/compiler/fir/analysis-tests/testData/resolve/inlineClasses/inlineClassMembers.kt +++ b/compiler/fir/analysis-tests/testData/resolve/inlineClasses/inlineClassMembers.kt @@ -18,7 +18,7 @@ inline class ReversedMembers(val x: Int) { fun box() {} fun unbox() {} - override fun equals(other: Any?) = true + override fun equals(other: Any?) = true override fun hashCode() = 1 } diff --git a/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirOldFrontendDiagnosticsTestGenerated.java b/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirOldFrontendDiagnosticsTestGenerated.java index f804d3416e0..87b2ff34b00 100644 --- a/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirOldFrontendDiagnosticsTestGenerated.java +++ b/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirOldFrontendDiagnosticsTestGenerated.java @@ -17855,9 +17855,9 @@ public class FirOldFrontendDiagnosticsTestGenerated extends AbstractFirDiagnosti } @Test - @TestMetadata("illegalEqualsOverridingInInlineClass.kt") - public void testIllegalEqualsOverridingInInlineClass() throws Exception { - runTest("compiler/testData/diagnostics/tests/inlineClasses/illegalEqualsOverridingInInlineClass.kt"); + @TestMetadata("inefficientEqualsOverridingInInlineClass.kt") + public void testInefficientEqualsOverridingInInlineClass() throws Exception { + runTest("compiler/testData/diagnostics/tests/inlineClasses/inefficientEqualsOverridingInInlineClass.kt"); } @Test diff --git a/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirOldFrontendDiagnosticsWithLightTreeTestGenerated.java b/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirOldFrontendDiagnosticsWithLightTreeTestGenerated.java index 65284856917..db07df84360 100644 --- a/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirOldFrontendDiagnosticsWithLightTreeTestGenerated.java +++ b/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirOldFrontendDiagnosticsWithLightTreeTestGenerated.java @@ -17855,9 +17855,9 @@ public class FirOldFrontendDiagnosticsWithLightTreeTestGenerated extends Abstrac } @Test - @TestMetadata("illegalEqualsOverridingInInlineClass.kt") - public void testIllegalEqualsOverridingInInlineClass() throws Exception { - runTest("compiler/testData/diagnostics/tests/inlineClasses/illegalEqualsOverridingInInlineClass.kt"); + @TestMetadata("inefficientEqualsOverridingInInlineClass.kt") + public void testInefficientEqualsOverridingInInlineClass() throws Exception { + runTest("compiler/testData/diagnostics/tests/inlineClasses/inefficientEqualsOverridingInInlineClass.kt"); } @Test diff --git a/compiler/fir/checkers/checkers-component-generator/src/org/jetbrains/kotlin/fir/checkers/generator/diagnostics/FirDiagnosticsList.kt b/compiler/fir/checkers/checkers-component-generator/src/org/jetbrains/kotlin/fir/checkers/generator/diagnostics/FirDiagnosticsList.kt index 38791a7b720..0337343ab9f 100644 --- a/compiler/fir/checkers/checkers-component-generator/src/org/jetbrains/kotlin/fir/checkers/generator/diagnostics/FirDiagnosticsList.kt +++ b/compiler/fir/checkers/checkers-component-generator/src/org/jetbrains/kotlin/fir/checkers/generator/diagnostics/FirDiagnosticsList.kt @@ -1398,7 +1398,7 @@ object DIAGNOSTICS_LIST : DiagnosticList("FirErrors") { val REDUNDANT_INLINE_SUSPEND_FUNCTION_TYPE by warning(PositioningStrategy.SUSPEND_MODIFIER) - val INEFFICIENT_EQUALS_OVERRIDING_IN_INLINE_CLASS by warning(PositioningStrategy.DECLARATION_SIGNATURE) { + val INEFFICIENT_EQUALS_OVERRIDING_IN_INLINE_CLASS by warning(PositioningStrategy.DECLARATION_NAME) { parameter("className") } } diff --git a/compiler/fir/checkers/gen/org/jetbrains/kotlin/fir/analysis/diagnostics/FirErrors.kt b/compiler/fir/checkers/gen/org/jetbrains/kotlin/fir/analysis/diagnostics/FirErrors.kt index 4177ac9e146..1cf57d6f575 100644 --- a/compiler/fir/checkers/gen/org/jetbrains/kotlin/fir/analysis/diagnostics/FirErrors.kt +++ b/compiler/fir/checkers/gen/org/jetbrains/kotlin/fir/analysis/diagnostics/FirErrors.kt @@ -723,7 +723,7 @@ object FirErrors { val ILLEGAL_INLINE_PARAMETER_MODIFIER by error0(SourceElementPositioningStrategies.INLINE_PARAMETER_MODIFIER) val INLINE_SUSPEND_FUNCTION_TYPE_UNSUPPORTED by error0() val REDUNDANT_INLINE_SUSPEND_FUNCTION_TYPE by warning0(SourceElementPositioningStrategies.SUSPEND_MODIFIER) - val INEFFICIENT_EQUALS_OVERRIDING_IN_INLINE_CLASS by warning1(SourceElementPositioningStrategies.DECLARATION_SIGNATURE) + val INEFFICIENT_EQUALS_OVERRIDING_IN_INLINE_CLASS by warning1(SourceElementPositioningStrategies.DECLARATION_NAME) // Imports val CANNOT_ALL_UNDER_IMPORT_FROM_SINGLETON by error1(SourceElementPositioningStrategies.IMPORT_LAST_NAME) diff --git a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/declaration/FirInlineClassDeclarationChecker.kt b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/declaration/FirInlineClassDeclarationChecker.kt index 401b41303b2..2eb4dcc329e 100644 --- a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/declaration/FirInlineClassDeclarationChecker.kt +++ b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/declaration/FirInlineClassDeclarationChecker.kt @@ -20,6 +20,7 @@ import org.jetbrains.kotlin.fir.declarations.* import org.jetbrains.kotlin.fir.declarations.utils.* import org.jetbrains.kotlin.fir.expressions.toResolvedCallableSymbol import org.jetbrains.kotlin.fir.resolve.fullyExpandedType +import org.jetbrains.kotlin.fir.resolve.isEquals import org.jetbrains.kotlin.fir.resolve.lookupSuperTypes import org.jetbrains.kotlin.fir.symbols.impl.FirConstructorSymbol import org.jetbrains.kotlin.fir.symbols.impl.FirValueParameterSymbol @@ -204,16 +205,22 @@ object FirInlineClassDeclarationChecker : FirRegularClassChecker() { } if (context.languageVersionSettings.supportsFeature(LanguageFeature.CustomEqualsInInlineClasses)) { - val simpleFunctions = declaration.declarations.filterIsInstance() - simpleFunctions.singleOrNull() { it.overridesEqualsFromAny() }?.apply { - if (declaration.symbol.isInline && simpleFunctions.none { it.isTypedEqualsInInlineClass(context.session) }) { - reporter.reportOn( - source, - FirErrors.INEFFICIENT_EQUALS_OVERRIDING_IN_INLINE_CLASS, - declaration.name.asString(), - context - ) + var equalsFromAnyOverriding: FirSimpleFunction? = null + var typedEqualsIsDefined = false + declaration.declarations.forEach { + if (it !is FirSimpleFunction) { + return@forEach } + if (it.isEquals()) equalsFromAnyOverriding = it + if (it.isTypedEqualsInInlineClass(context.session)) typedEqualsIsDefined = true + } + if (equalsFromAnyOverriding != null && !typedEqualsIsDefined) { + reporter.reportOn( + equalsFromAnyOverriding!!.source, + FirErrors.INEFFICIENT_EQUALS_OVERRIDING_IN_INLINE_CLASS, + declaration.name.asString(), + context + ) } } } diff --git a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/declaration/declarationUtils.kt b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/declaration/declarationUtils.kt index 73662d274aa..4dd8343c070 100644 --- a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/declaration/declarationUtils.kt +++ b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/declaration/declarationUtils.kt @@ -121,17 +121,10 @@ fun FirClassSymbol<*>.primaryConstructorSymbol(): FirConstructorSymbol? { fun FirSimpleFunction.isTypedEqualsInInlineClass(session: FirSession): Boolean = containingClass()?.toFirRegularClassSymbol(session)?.run { - this@isTypedEqualsInInlineClass.contextReceivers.isEmpty() - && this@isTypedEqualsInInlineClass.receiverTypeRef == null - && this@isTypedEqualsInInlineClass.name == OperatorNameConventions.EQUALS - && this@isTypedEqualsInInlineClass.returnTypeRef.isBoolean - && isInline - && this@isTypedEqualsInInlineClass.valueParameters.size == 1 - && this@isTypedEqualsInInlineClass.valueParameters[0].returnTypeRef.coneType.classId == classId + with(this@isTypedEqualsInInlineClass) { + contextReceivers.isEmpty() && receiverTypeRef == null && name == OperatorNameConventions.EQUALS + && this@run.isInline && valueParameters.size == 1 && returnTypeRef.isBoolean + && valueParameters[0].returnTypeRef.coneType.classId == this@run.classId + } } ?: false -fun FirSimpleFunction.overridesEqualsFromAny(): Boolean { - return name == OperatorNameConventions.EQUALS && returnTypeRef.isBoolean - && valueParameters.size == 1 && valueParameters[0].returnTypeRef.isNullableAny - && contextReceivers.isEmpty() && receiverTypeRef == null -} \ No newline at end of file diff --git a/compiler/fir/fir2ir/tests-gen/org/jetbrains/kotlin/test/runners/codegen/FirBlackBoxCodegenTestGenerated.java b/compiler/fir/fir2ir/tests-gen/org/jetbrains/kotlin/test/runners/codegen/FirBlackBoxCodegenTestGenerated.java index 1bafb39c8fb..55af1ceaa8a 100644 --- a/compiler/fir/fir2ir/tests-gen/org/jetbrains/kotlin/test/runners/codegen/FirBlackBoxCodegenTestGenerated.java +++ b/compiler/fir/fir2ir/tests-gen/org/jetbrains/kotlin/test/runners/codegen/FirBlackBoxCodegenTestGenerated.java @@ -21467,6 +21467,12 @@ public class FirBlackBoxCodegenTestGenerated extends AbstractFirBlackBoxCodegenT runTest("compiler/testData/codegen/box/inlineClasses/inlineClassPropertyReferenceGetAndSetGeneric.kt", TransformersFunctions.getReplaceOptionalJvmInlineAnnotationWithReal()); } + @Test + @TestMetadata("inlineClassTypedEqualsGenerics.kt") + public void testInlineClassTypedEqualsGenerics() throws Exception { + runTest("compiler/testData/codegen/box/inlineClasses/inlineClassTypedEqualsGenerics.kt", TransformersFunctions.getReplaceOptionalJvmInlineAnnotationWithReal()); + } + @Test @TestMetadata("inlineClassUntypedEqualsOverriden.kt") public void testInlineClassUntypedEqualsOverriden() throws Exception { diff --git a/compiler/fir/semantics/src/org/jetbrains/kotlin/fir/resolve/DeclarationUtils.kt b/compiler/fir/semantics/src/org/jetbrains/kotlin/fir/resolve/DeclarationUtils.kt index 248bdda85e1..2266576fb95 100644 --- a/compiler/fir/semantics/src/org/jetbrains/kotlin/fir/resolve/DeclarationUtils.kt +++ b/compiler/fir/semantics/src/org/jetbrains/kotlin/fir/resolve/DeclarationUtils.kt @@ -91,6 +91,8 @@ val FirConstructorSymbol.isTypeAliasedConstructor: Boolean fun FirSimpleFunction.isEquals(): Boolean { if (name != OperatorNameConventions.EQUALS) return false if (valueParameters.size != 1) return false + if (contextReceivers.isNotEmpty()) return false + if (receiverTypeRef != null) return false val parameter = valueParameters.first() return parameter.returnTypeRef.isNullableAny } diff --git a/compiler/frontend/src/org/jetbrains/kotlin/diagnostics/Errors.java b/compiler/frontend/src/org/jetbrains/kotlin/diagnostics/Errors.java index 5ea2df3c2fe..e513f5d264f 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/diagnostics/Errors.java +++ b/compiler/frontend/src/org/jetbrains/kotlin/diagnostics/Errors.java @@ -428,8 +428,8 @@ public interface Errors { DiagnosticFactory0 VALUE_CLASS_CANNOT_BE_CLONEABLE = DiagnosticFactory0.create(ERROR); DiagnosticFactory0 INLINE_CLASS_DEPRECATED = DiagnosticFactory0.create(WARNING); DiagnosticFactory0 INLINE_CLASS_CANNOT_HAVE_CONTEXT_RECEIVERS = DiagnosticFactory0.create(ERROR); - DiagnosticFactory1 INEFFICIENT_EQUALS_OVERRIDING_IN_INLINE_CLASS = - DiagnosticFactory1.create(WARNING, DECLARATION_SIGNATURE); + DiagnosticFactory1 INEFFICIENT_EQUALS_OVERRIDING_IN_INLINE_CLASS = + DiagnosticFactory1.create(WARNING, DECLARATION_NAME); // Result class diff --git a/compiler/testData/codegen/box/inlineClasses/inlineClassTypedEqualsGenerics.kt b/compiler/testData/codegen/box/inlineClasses/inlineClassTypedEqualsGenerics.kt new file mode 100644 index 00000000000..54a8c6254e6 --- /dev/null +++ b/compiler/testData/codegen/box/inlineClasses/inlineClassTypedEqualsGenerics.kt @@ -0,0 +1,55 @@ +// WITH_STDLIB +// WORKS_WHEN_VALUE_CLASS +// LANGUAGE: +ValueClasses, +CustomEqualsInInlineClasses +// TARGET_BACKEND: JVM_IR + +OPTIONAL_JVM_INLINE_ANNOTATION +value class IC1(val x: T) { + fun equals(other: Int) = false + fun equals(other: IC1) = true +} + +class Generic(val x: T, val y: R) + +OPTIONAL_JVM_INLINE_ANNOTATION +value class IC2(val value: Generic) { + fun equals(other: IC1) = false + fun equals(other: IC2) = true +} + +OPTIONAL_JVM_INLINE_ANNOTATION +value class IC3(val value: T) { + fun equals(other: Int) = false + fun equals(other: IC3<*>) = true +} + +OPTIONAL_JVM_INLINE_ANNOTATION +value class IC4(val value: T) { + fun equals(other: String) = false + fun equals(other: IC4) = true +} + + +fun box() = when { + IC1(5.0) != IC1(3) -> "Fail 1.1" + (IC1(5.0) as Any) != IC1(3) -> "Fail 1.2" + IC1(5.0) != (IC1(3) as Any) -> "Fail 1.3" + (IC1(5.0) as Any) != (IC1(3) as Any) -> "Fail 1.4" + + IC2(Generic("aba", 5.0)) != IC2(Generic(3, 8)) -> "Fail 2.1" + (IC2(Generic("aba", 5.0)) as Any) != IC2(Generic(3, 8)) -> "Fail 2.2" + IC2(Generic("aba", 5.0)) != (IC2(Generic(3, 8)) as Any) -> "Fail 2.3" + (IC2(Generic("aba", 5.0)) as Any) != (IC2(Generic(3, 8)) as Any) -> "Fail 2.4" + + IC3("x") != IC3("y") -> "Fail 3.1" + (IC3("x") as Any) != IC3("y") -> "Fail 3.2" + IC3("x") != (IC3("y") as Any) -> "Fail 3.3" + (IC3("x") as Any) != (IC3("y") as Any) -> "Fail 3.4" + + IC4("aba") != IC4("caba") -> "Fail 4.1" + (IC4("aba") as Any) != IC4("caba") -> "Fail 4.2" + IC4("aba") != (IC4("caba") as Any) -> "Fail 4.3" + (IC4("aba") as Any) != (IC4("caba") as Any) -> "Fail 4.4" + + else -> "OK" +} \ No newline at end of file diff --git a/compiler/testData/diagnostics/tests/inlineClasses/illegalEqualsOverridingInInlineClass.kt b/compiler/testData/diagnostics/tests/inlineClasses/inefficientEqualsOverridingInInlineClass.kt similarity index 82% rename from compiler/testData/diagnostics/tests/inlineClasses/illegalEqualsOverridingInInlineClass.kt rename to compiler/testData/diagnostics/tests/inlineClasses/inefficientEqualsOverridingInInlineClass.kt index da15ce1074e..843d5ef127d 100644 --- a/compiler/testData/diagnostics/tests/inlineClasses/illegalEqualsOverridingInInlineClass.kt +++ b/compiler/testData/diagnostics/tests/inlineClasses/inefficientEqualsOverridingInInlineClass.kt @@ -5,7 +5,7 @@ @JvmInline value class IC1(val x: Int) { - override fun equals(other: Any?): Boolean { + override fun equals(other: Any?): Boolean { if (other !is IC1) { return false } diff --git a/compiler/testData/diagnostics/tests/inlineClasses/illegalEqualsOverridingInInlineClass.txt b/compiler/testData/diagnostics/tests/inlineClasses/inefficientEqualsOverridingInInlineClass.txt similarity index 100% rename from compiler/testData/diagnostics/tests/inlineClasses/illegalEqualsOverridingInInlineClass.txt rename to compiler/testData/diagnostics/tests/inlineClasses/inefficientEqualsOverridingInInlineClass.txt diff --git a/compiler/testData/diagnostics/tests/inlineClasses/reservedMembersAndConstructsInsideInlineClass.fir.kt b/compiler/testData/diagnostics/tests/inlineClasses/reservedMembersAndConstructsInsideInlineClass.fir.kt index e439297e146..a5f33a45d89 100644 --- a/compiler/testData/diagnostics/tests/inlineClasses/reservedMembersAndConstructsInsideInlineClass.fir.kt +++ b/compiler/testData/diagnostics/tests/inlineClasses/reservedMembersAndConstructsInsideInlineClass.fir.kt @@ -8,7 +8,7 @@ inline class IC1(val x: Any) { fun unbox() {} fun unbox(x: Any) {} - override fun equals(other: Any?): Boolean = true + override fun equals(other: Any?): Boolean = true override fun hashCode(): Int = 0 } diff --git a/compiler/testData/diagnostics/tests/inlineClasses/reservedMembersAndConstructsInsideInlineClass.kt b/compiler/testData/diagnostics/tests/inlineClasses/reservedMembersAndConstructsInsideInlineClass.kt index bb069f97926..9bb82074076 100644 --- a/compiler/testData/diagnostics/tests/inlineClasses/reservedMembersAndConstructsInsideInlineClass.kt +++ b/compiler/testData/diagnostics/tests/inlineClasses/reservedMembersAndConstructsInsideInlineClass.kt @@ -8,7 +8,7 @@ inline class IC1(val x: Any) { fun unbox() {} fun unbox(x: Any) {} - override fun equals(other: Any?): Boolean = true + override fun equals(other: Any?): Boolean = true override fun hashCode(): Int = 0 } diff --git a/compiler/testData/diagnostics/tests/valueClasses/reservedMembersAndConstructsInsideValueClass.fir.kt b/compiler/testData/diagnostics/tests/valueClasses/reservedMembersAndConstructsInsideValueClass.fir.kt index 05c21224ad9..bb3fd24e5c8 100644 --- a/compiler/testData/diagnostics/tests/valueClasses/reservedMembersAndConstructsInsideValueClass.fir.kt +++ b/compiler/testData/diagnostics/tests/valueClasses/reservedMembersAndConstructsInsideValueClass.fir.kt @@ -15,7 +15,7 @@ value class IC1(val x: Any) { fun unbox() {} fun unbox(x: Any) {} - override fun equals(other: Any?): Boolean = true + override fun equals(other: Any?): Boolean = true override fun hashCode(): Int = 0 } diff --git a/compiler/testData/diagnostics/tests/valueClasses/reservedMembersAndConstructsInsideValueClass.kt b/compiler/testData/diagnostics/tests/valueClasses/reservedMembersAndConstructsInsideValueClass.kt index c020ac716d9..738a040121f 100644 --- a/compiler/testData/diagnostics/tests/valueClasses/reservedMembersAndConstructsInsideValueClass.kt +++ b/compiler/testData/diagnostics/tests/valueClasses/reservedMembersAndConstructsInsideValueClass.kt @@ -15,7 +15,7 @@ value class IC1(val x: Any) { fun unbox() {} fun unbox(x: Any) {} - override fun equals(other: Any?): Boolean = true + override fun equals(other: Any?): Boolean = true override fun hashCode(): Int = 0 } diff --git a/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/DiagnosticTestGenerated.java b/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/DiagnosticTestGenerated.java index e8497f93beb..ee8b2ffe3b7 100644 --- a/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/DiagnosticTestGenerated.java +++ b/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/DiagnosticTestGenerated.java @@ -17861,9 +17861,9 @@ public class DiagnosticTestGenerated extends AbstractDiagnosticTest { } @Test - @TestMetadata("illegalEqualsOverridingInInlineClass.kt") - public void testIllegalEqualsOverridingInInlineClass() throws Exception { - runTest("compiler/testData/diagnostics/tests/inlineClasses/illegalEqualsOverridingInInlineClass.kt"); + @TestMetadata("inefficientEqualsOverridingInInlineClass.kt") + public void testInefficientEqualsOverridingInInlineClass() throws Exception { + runTest("compiler/testData/diagnostics/tests/inlineClasses/inefficientEqualsOverridingInInlineClass.kt"); } @Test diff --git a/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/IrBlackBoxCodegenTestGenerated.java b/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/IrBlackBoxCodegenTestGenerated.java index fe6e4560f2a..6e350b81c70 100644 --- a/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/IrBlackBoxCodegenTestGenerated.java +++ b/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/IrBlackBoxCodegenTestGenerated.java @@ -21467,6 +21467,12 @@ public class IrBlackBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTes runTest("compiler/testData/codegen/box/inlineClasses/inlineClassPropertyReferenceGetAndSetGeneric.kt", TransformersFunctions.getReplaceOptionalJvmInlineAnnotationWithReal()); } + @Test + @TestMetadata("inlineClassTypedEqualsGenerics.kt") + public void testInlineClassTypedEqualsGenerics() throws Exception { + runTest("compiler/testData/codegen/box/inlineClasses/inlineClassTypedEqualsGenerics.kt", TransformersFunctions.getReplaceOptionalJvmInlineAnnotationWithReal()); + } + @Test @TestMetadata("inlineClassUntypedEqualsOverriden.kt") public void testInlineClassUntypedEqualsOverriden() throws Exception { diff --git a/compiler/util/src/org/jetbrains/kotlin/config/LanguageVersionSettings.kt b/compiler/util/src/org/jetbrains/kotlin/config/LanguageVersionSettings.kt index 0b51deb83af..5679dfc1e8f 100644 --- a/compiler/util/src/org/jetbrains/kotlin/config/LanguageVersionSettings.kt +++ b/compiler/util/src/org/jetbrains/kotlin/config/LanguageVersionSettings.kt @@ -284,7 +284,7 @@ enum class LanguageFeature( DataObjects(KOTLIN_1_9), // KT-4107 ProhibitAccessToEnumCompanionMembersInEnumConstructorCall(KOTLIN_1_9, kind = BUG_FIX), // KT-49110 ReferencesToSyntheticJavaProperties(KOTLIN_1_9), // KT-8575 - CustomEqualsInInlineClasses(KOTLIN_1_9, kind = UNSTABLE_FEATURE), // KT-24874 + CustomEqualsInInlineClasses(KOTLIN_1_9), // KT-24874 // Disabled for indefinite time. See KT-53751 diff --git a/core/descriptors/src/org/jetbrains/kotlin/descriptors/descriptorUtil.kt b/core/descriptors/src/org/jetbrains/kotlin/descriptors/descriptorUtil.kt index 0e6cc16a657..5c579ed7cea 100644 --- a/core/descriptors/src/org/jetbrains/kotlin/descriptors/descriptorUtil.kt +++ b/core/descriptors/src/org/jetbrains/kotlin/descriptors/descriptorUtil.kt @@ -10,6 +10,7 @@ import org.jetbrains.kotlin.incremental.components.LookupLocation import org.jetbrains.kotlin.incremental.components.NoLookupLocation import org.jetbrains.kotlin.name.FqName import org.jetbrains.kotlin.resolve.DescriptorUtils +import org.jetbrains.kotlin.resolve.descriptorUtil.classId import org.jetbrains.kotlin.resolve.descriptorUtil.module import org.jetbrains.kotlin.resolve.isInlineClass import org.jetbrains.kotlin.types.KotlinType @@ -93,13 +94,12 @@ fun DeclarationDescriptor.containingPackage(): FqName? { object DeserializedDeclarationsFromSupertypeConflictDataKey : CallableDescriptor.UserDataKey -fun FunctionDescriptor.isTypedEqualsInInlineClass(): Boolean = name == OperatorNameConventions.EQUALS +fun FunctionDescriptor.isTypedEqualsInInlineClass() = name == OperatorNameConventions.EQUALS && (returnType?.isBoolean() ?: false) && containingDeclaration.isInlineClass() - && valueParameters.size == 1 && valueParameters[0].type == (containingDeclaration as? ClassDescriptor)?.defaultType + && valueParameters.size == 1 && valueParameters[0].type.constructor.declarationDescriptor.classId == (containingDeclaration as? ClassDescriptor)?.classId && contextReceiverParameters.isEmpty() && extensionReceiverParameter == null fun FunctionDescriptor.overridesEqualsFromAny(): Boolean = name == OperatorNameConventions.EQUALS - && (returnType?.isBoolean() ?: false) && valueParameters.size == 1 && valueParameters[0].type.isNullableAny() && contextReceiverParameters.isEmpty() && extensionReceiverParameter == null \ No newline at end of file