FirClassAnySynthesizedMemberScope.kt: make it a declared member scope

Related to KT-54844, KT-58926
This commit is contained in:
Mikhail Glukhikh
2023-05-26 09:04:31 +02:00
committed by Space Team
parent 0ea0346ec1
commit 668157eb41
15 changed files with 222 additions and 72 deletions
@@ -4195,6 +4195,12 @@ public class DiagnosticCompilerTestFirTestdataTestGenerated extends AbstractDiag
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/fir/analysis-tests/testData/resolve/scopes"), Pattern.compile("^([^.]+)\\.kt$"), null, true); KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/fir/analysis-tests/testData/resolve/scopes"), Pattern.compile("^([^.]+)\\.kt$"), null, true);
} }
@Test
@TestMetadata("delegatedDataClass.kt")
public void testDelegatedDataClass() throws Exception {
runTest("compiler/fir/analysis-tests/testData/resolve/scopes/delegatedDataClass.kt");
}
@Test @Test
@TestMetadata("explicitOverrideOfTwoMembers.kt") @TestMetadata("explicitOverrideOfTwoMembers.kt")
public void testExplicitOverrideOfTwoMembers() throws Exception { public void testExplicitOverrideOfTwoMembers() throws Exception {
@@ -4195,6 +4195,12 @@ public class LLFirPreresolvedReversedDiagnosticCompilerFirTestDataTestGenerated
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/fir/analysis-tests/testData/resolve/scopes"), Pattern.compile("^([^.]+)\\.kt$"), null, true); KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/fir/analysis-tests/testData/resolve/scopes"), Pattern.compile("^([^.]+)\\.kt$"), null, true);
} }
@Test
@TestMetadata("delegatedDataClass.kt")
public void testDelegatedDataClass() throws Exception {
runTest("compiler/fir/analysis-tests/testData/resolve/scopes/delegatedDataClass.kt");
}
@Test @Test
@TestMetadata("explicitOverrideOfTwoMembers.kt") @TestMetadata("explicitOverrideOfTwoMembers.kt")
public void testExplicitOverrideOfTwoMembers() throws Exception { public void testExplicitOverrideOfTwoMembers() throws Exception {
@@ -3699,6 +3699,11 @@ public class LazyBodyIsNotTouchedTestGenerated extends AbstractLazyBodyIsNotTouc
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/fir/analysis-tests/testData/resolve/scopes"), Pattern.compile("^([^.]+)\\.kt$"), null, true); KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/fir/analysis-tests/testData/resolve/scopes"), Pattern.compile("^([^.]+)\\.kt$"), null, true);
} }
@TestMetadata("delegatedDataClass.kt")
public void testDelegatedDataClass() throws Exception {
runTest("compiler/fir/analysis-tests/testData/resolve/scopes/delegatedDataClass.kt");
}
@TestMetadata("explicitOverrideOfTwoMembers.kt") @TestMetadata("explicitOverrideOfTwoMembers.kt")
public void testExplicitOverrideOfTwoMembers() throws Exception { public void testExplicitOverrideOfTwoMembers() throws Exception {
runTest("compiler/fir/analysis-tests/testData/resolve/scopes/explicitOverrideOfTwoMembers.kt"); runTest("compiler/fir/analysis-tests/testData/resolve/scopes/explicitOverrideOfTwoMembers.kt");
@@ -0,0 +1,42 @@
FILE: delegatedDataClass.kt
public abstract interface AnyNeighbor : R|kotlin/Any| {
public abstract override operator fun equals(other: R|kotlin/Any?|): R|kotlin/Boolean|
public abstract override fun hashCode(): R|kotlin/Int|
public abstract override fun toString(): R|kotlin/String|
}
public final class Impl : R|AnyNeighbor| {
public constructor(): R|Impl| {
super<R|kotlin/Any|>()
}
public open override operator fun equals(other: R|kotlin/Any?|): R|kotlin/Boolean| {
^equals Boolean(true)
}
public open override fun hashCode(): R|kotlin/Int| {
^hashCode Int(0)
}
public open override fun toString(): R|kotlin/String| {
^toString String()
}
}
public final data class Data : R|AnyNeighbor| {
public constructor(i: R|Impl|): R|Data| {
super<R|kotlin/Any|>()
}
private final field $$delegate_0: R|AnyNeighbor| = R|<local>/i|
public final val i: R|Impl| = R|<local>/i|
public get(): R|Impl|
public final operator fun component1(): R|Impl|
public final fun copy(i: R|Impl| = this@R|/Data|.R|/Data.i|): R|Data|
}
@@ -0,0 +1,25 @@
// SCOPE_DUMP: Data:equals, Data:hashCode, Data:toString
interface AnyNeighbor {
override fun equals(other: Any?): Boolean
override fun hashCode(): Int
override fun toString(): String
}
class Impl : AnyNeighbor {
override fun equals(other: Any?): Boolean {
return true
}
override fun hashCode(): Int {
return 0
}
override fun toString(): String {
return ""
}
}
data class Data(val i: Impl) : AnyNeighbor by i
@@ -0,0 +1,14 @@
Data:
[Delegated]: public open override operator fun equals(other: R|kotlin/Any?|): R|kotlin/Boolean| from Use site scope of /Data [id: 0]
[Source]: public abstract override operator fun equals(other: R|kotlin/Any?|): R|kotlin/Boolean| from Use site scope of /AnyNeighbor [id: 1]
[Library]: public open operator fun equals(other: R|kotlin/Any?|): R|kotlin/Boolean| from Use site scope of kotlin/Any [id: 2]
Data:
[Delegated]: public open override fun hashCode(): R|kotlin/Int| from Use site scope of /Data [id: 0]
[Source]: public abstract override fun hashCode(): R|kotlin/Int| from Use site scope of /AnyNeighbor [id: 1]
[Library]: public open fun hashCode(): R|kotlin/Int| from Use site scope of kotlin/Any [id: 2]
Data:
[Delegated]: public open override fun toString(): R|kotlin/String| from Use site scope of /Data [id: 0]
[Source]: public abstract override fun toString(): R|kotlin/String| from Use site scope of /AnyNeighbor [id: 1]
[Library]: public open fun toString(): R|kotlin/String| from Use site scope of kotlin/Any [id: 2]
@@ -4195,6 +4195,12 @@ public class FirLightTreeDiagnosticsTestGenerated extends AbstractFirLightTreeDi
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/fir/analysis-tests/testData/resolve/scopes"), Pattern.compile("^([^.]+)\\.kt$"), null, true); KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/fir/analysis-tests/testData/resolve/scopes"), Pattern.compile("^([^.]+)\\.kt$"), null, true);
} }
@Test
@TestMetadata("delegatedDataClass.kt")
public void testDelegatedDataClass() throws Exception {
runTest("compiler/fir/analysis-tests/testData/resolve/scopes/delegatedDataClass.kt");
}
@Test @Test
@TestMetadata("explicitOverrideOfTwoMembers.kt") @TestMetadata("explicitOverrideOfTwoMembers.kt")
public void testExplicitOverrideOfTwoMembers() throws Exception { public void testExplicitOverrideOfTwoMembers() throws Exception {
@@ -4195,6 +4195,12 @@ public class FirPsiDiagnosticTestGenerated extends AbstractFirPsiDiagnosticTest
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/fir/analysis-tests/testData/resolve/scopes"), Pattern.compile("^([^.]+)\\.kt$"), null, true); KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/fir/analysis-tests/testData/resolve/scopes"), Pattern.compile("^([^.]+)\\.kt$"), null, true);
} }
@Test
@TestMetadata("delegatedDataClass.kt")
public void testDelegatedDataClass() throws Exception {
runTest("compiler/fir/analysis-tests/testData/resolve/scopes/delegatedDataClass.kt");
}
@Test @Test
@TestMetadata("explicitOverrideOfTwoMembers.kt") @TestMetadata("explicitOverrideOfTwoMembers.kt")
public void testExplicitOverrideOfTwoMembers() throws Exception { public void testExplicitOverrideOfTwoMembers() throws Exception {
@@ -18411,6 +18411,12 @@ public class FirLightTreeBlackBoxCodegenTestGenerated extends AbstractFirLightTr
runTest("compiler/testData/codegen/box/fir/CustomThrowableMessage.kt"); runTest("compiler/testData/codegen/box/fir/CustomThrowableMessage.kt");
} }
@Test
@TestMetadata("delegatedAndDataTogether.kt")
public void testDelegatedAndDataTogether() throws Exception {
runTest("compiler/testData/codegen/box/fir/delegatedAndDataTogether.kt");
}
@Test @Test
@TestMetadata("differentSinceKotlin.kt") @TestMetadata("differentSinceKotlin.kt")
public void testDifferentSinceKotlin() throws Exception { public void testDifferentSinceKotlin() throws Exception {
@@ -18411,6 +18411,12 @@ public class FirPsiBlackBoxCodegenTestGenerated extends AbstractFirPsiBlackBoxCo
runTest("compiler/testData/codegen/box/fir/CustomThrowableMessage.kt"); runTest("compiler/testData/codegen/box/fir/CustomThrowableMessage.kt");
} }
@Test
@TestMetadata("delegatedAndDataTogether.kt")
public void testDelegatedAndDataTogether() throws Exception {
runTest("compiler/testData/codegen/box/fir/delegatedAndDataTogether.kt");
}
@Test @Test
@TestMetadata("differentSinceKotlin.kt") @TestMetadata("differentSinceKotlin.kt")
public void testDifferentSinceKotlin() throws Exception { public void testDifferentSinceKotlin() throws Exception {
@@ -45,7 +45,7 @@ class FirKotlinScopeProvider(
return scopeSession.getOrBuild(klass.symbol, USE_SITE) { return scopeSession.getOrBuild(klass.symbol, USE_SITE) {
val declaredScope = useSiteSession.declaredMemberScope(klass, memberRequiredPhase) val declaredScope = useSiteSession.declaredMemberScope(klass, memberRequiredPhase)
val decoratedDeclaredMemberScope = declaredMemberScopeDecorator( val possiblyDelegatedDeclaredMemberScope = declaredMemberScopeDecorator(
klass, klass,
declaredScope, declaredScope,
useSiteSession, useSiteSession,
@@ -58,29 +58,25 @@ class FirKotlinScopeProvider(
else else
FirDelegatedMemberScope(useSiteSession, scopeSession, klass, it, delegateFields) FirDelegatedMemberScope(useSiteSession, scopeSession, klass, it, delegateFields)
} }
val declaredMemberScopeWithPossiblySynthesizedMembers =
if (klass is FirRegularClass && !klass.isExpect && (klass.isData || klass.isInline)) {
// See also KT-58926 (we apply delegation first, and data/value classes after it)
FirClassAnySynthesizedMemberScope(useSiteSession, possiblyDelegatedDeclaredMemberScope, klass, scopeSession)
} else {
possiblyDelegatedDeclaredMemberScope
}
val scopes = lookupSuperTypes( val scopes = lookupSuperTypes(
klass, lookupInterfaces = true, deep = false, useSiteSession = useSiteSession, substituteTypes = true klass, lookupInterfaces = true, deep = false, useSiteSession = useSiteSession, substituteTypes = true
).mapNotNull { useSiteSuperType -> ).mapNotNull { useSiteSuperType ->
useSiteSuperType.scopeForSupertype(useSiteSession, scopeSession, klass, memberRequiredPhase = memberRequiredPhase) useSiteSuperType.scopeForSupertype(useSiteSession, scopeSession, klass, memberRequiredPhase = memberRequiredPhase)
} }
val useSiteMemberScope = FirClassUseSiteMemberScope( FirClassUseSiteMemberScope(
klass, klass,
useSiteSession, useSiteSession,
scopes, scopes,
decoratedDeclaredMemberScope, declaredMemberScopeWithPossiblySynthesizedMembers,
) )
if (klass is FirRegularClass && !klass.isExpect && (klass.isData || klass.isInline)) {
val lookupTag = klass.symbol.toLookupTag()
scopeSession.getOrBuild(lookupTag, AnySynthesizedScopeKey(lookupTag)) {
FirClassAnySynthesizedMemberScope(
useSiteSession, useSiteMemberScope, lookupTag,
klass.moduleData, klass.defaultType(), klass.source
)
}
} else {
useSiteMemberScope
}
} }
} }
@@ -6,12 +6,10 @@
package org.jetbrains.kotlin.fir.scopes.impl package org.jetbrains.kotlin.fir.scopes.impl
import org.jetbrains.kotlin.KtFakeSourceElementKind import org.jetbrains.kotlin.KtFakeSourceElementKind
import org.jetbrains.kotlin.KtSourceElement
import org.jetbrains.kotlin.descriptors.EffectiveVisibility import org.jetbrains.kotlin.descriptors.EffectiveVisibility
import org.jetbrains.kotlin.descriptors.Modality import org.jetbrains.kotlin.descriptors.Modality
import org.jetbrains.kotlin.descriptors.Visibilities import org.jetbrains.kotlin.descriptors.Visibilities
import org.jetbrains.kotlin.fakeElement import org.jetbrains.kotlin.fakeElement
import org.jetbrains.kotlin.fir.FirModuleData
import org.jetbrains.kotlin.fir.FirSession import org.jetbrains.kotlin.fir.FirSession
import org.jetbrains.kotlin.fir.FirSessionComponent import org.jetbrains.kotlin.fir.FirSessionComponent
import org.jetbrains.kotlin.fir.caches.FirCache import org.jetbrains.kotlin.fir.caches.FirCache
@@ -19,19 +17,22 @@ import org.jetbrains.kotlin.fir.caches.FirCachesFactory
import org.jetbrains.kotlin.fir.caches.createCache import org.jetbrains.kotlin.fir.caches.createCache
import org.jetbrains.kotlin.fir.caches.firCachesFactory import org.jetbrains.kotlin.fir.caches.firCachesFactory
import org.jetbrains.kotlin.fir.declarations.FirDeclarationOrigin import org.jetbrains.kotlin.fir.declarations.FirDeclarationOrigin
import org.jetbrains.kotlin.fir.declarations.FirRegularClass
import org.jetbrains.kotlin.fir.declarations.FirResolvePhase import org.jetbrains.kotlin.fir.declarations.FirResolvePhase
import org.jetbrains.kotlin.fir.declarations.FirSimpleFunction import org.jetbrains.kotlin.fir.declarations.FirSimpleFunction
import org.jetbrains.kotlin.fir.declarations.builder.FirSimpleFunctionBuilder import org.jetbrains.kotlin.fir.declarations.builder.FirSimpleFunctionBuilder
import org.jetbrains.kotlin.fir.declarations.builder.buildSimpleFunction import org.jetbrains.kotlin.fir.declarations.builder.buildSimpleFunction
import org.jetbrains.kotlin.fir.declarations.builder.buildValueParameter import org.jetbrains.kotlin.fir.declarations.builder.buildValueParameter
import org.jetbrains.kotlin.fir.declarations.impl.FirResolvedDeclarationStatusImpl import org.jetbrains.kotlin.fir.declarations.impl.FirResolvedDeclarationStatusImpl
import org.jetbrains.kotlin.fir.resolve.ScopeSession
import org.jetbrains.kotlin.fir.resolve.defaultType
import org.jetbrains.kotlin.fir.resolve.lookupSuperTypes
import org.jetbrains.kotlin.fir.resolve.substitution.ConeSubstitutor import org.jetbrains.kotlin.fir.resolve.substitution.ConeSubstitutor
import org.jetbrains.kotlin.fir.scopes.FirTypeScope import org.jetbrains.kotlin.fir.scopes.FirContainingNamesAwareScope
import org.jetbrains.kotlin.fir.scopes.ProcessorAction import org.jetbrains.kotlin.fir.scopes.scopeForSupertype
import org.jetbrains.kotlin.fir.symbols.ConeClassLikeLookupTag import org.jetbrains.kotlin.fir.symbols.ConeClassLikeLookupTag
import org.jetbrains.kotlin.fir.symbols.impl.* import org.jetbrains.kotlin.fir.symbols.impl.*
import org.jetbrains.kotlin.fir.symbols.lazyResolveToPhase import org.jetbrains.kotlin.fir.symbols.lazyResolveToPhase
import org.jetbrains.kotlin.fir.types.ConeClassLikeType
import org.jetbrains.kotlin.fir.types.impl.FirImplicitBooleanTypeRef import org.jetbrains.kotlin.fir.types.impl.FirImplicitBooleanTypeRef
import org.jetbrains.kotlin.fir.types.impl.FirImplicitIntTypeRef import org.jetbrains.kotlin.fir.types.impl.FirImplicitIntTypeRef
import org.jetbrains.kotlin.fir.types.impl.FirImplicitNullableAnyTypeRef import org.jetbrains.kotlin.fir.types.impl.FirImplicitNullableAnyTypeRef
@@ -41,86 +42,85 @@ import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.util.OperatorNameConventions import org.jetbrains.kotlin.util.OperatorNameConventions
import org.jetbrains.kotlin.utils.addToStdlib.shouldNotBeCalled import org.jetbrains.kotlin.utils.addToStdlib.shouldNotBeCalled
/**
* This declared scope wrapper is created for data/value classes and provides Any method stubs, if necessary
*/
class FirClassAnySynthesizedMemberScope( class FirClassAnySynthesizedMemberScope(
session: FirSession, session: FirSession,
private val useSiteMemberScope: FirClassUseSiteMemberScope, private val declaredMemberScope: FirContainingNamesAwareScope,
private val lookupTag: ConeClassLikeLookupTag, klass: FirRegularClass,
private val baseModuleData: FirModuleData, scopeSession: ScopeSession,
private val dispatchReceiverType: ConeClassLikeType, ) : FirContainingNamesAwareScope() {
classSource: KtSourceElement?, private val lookupTag = klass.symbol.toLookupTag()
) : FirTypeScope() {
private val baseModuleData = klass.moduleData
private val dispatchReceiverType = klass.defaultType()
private val synthesizedCache = session.synthesizedStorage.synthesizedCacheByScope.getValue(lookupTag, null) private val synthesizedCache = session.synthesizedStorage.synthesizedCacheByScope.getValue(lookupTag, null)
private val synthesizedOverrides = mutableMapOf<FirNamedFunctionSymbol, FirNamedFunctionSymbol>() private val synthesizedSource = klass.source?.fakeElement(KtFakeSourceElementKind.DataClassGeneratedMembers)
private val synthesizedSource = classSource?.fakeElement(KtFakeSourceElementKind.DataClassGeneratedMembers) private val superKlassScope = lookupSuperTypes(
klass, lookupInterfaces = false, deep = false, useSiteSession = session, substituteTypes = true
).firstOrNull()?.scopeForSupertype(session, scopeSession, klass, memberRequiredPhase = FirResolvePhase.TYPES)
override fun processClassifiersByNameWithSubstitution(name: Name, processor: (FirClassifierSymbol<*>, ConeSubstitutor) -> Unit) { override fun processClassifiersByNameWithSubstitution(name: Name, processor: (FirClassifierSymbol<*>, ConeSubstitutor) -> Unit) {
useSiteMemberScope.processClassifiersByNameWithSubstitution(name, processor) declaredMemberScope.processClassifiersByNameWithSubstitution(name, processor)
} }
override fun processDeclaredConstructors(processor: (FirConstructorSymbol) -> Unit) { override fun processDeclaredConstructors(processor: (FirConstructorSymbol) -> Unit) {
useSiteMemberScope.processDeclaredConstructors(processor) declaredMemberScope.processDeclaredConstructors(processor)
}
override fun processDirectOverriddenPropertiesWithBaseScope(
propertySymbol: FirPropertySymbol,
processor: (FirPropertySymbol, FirTypeScope) -> ProcessorAction
): ProcessorAction {
return useSiteMemberScope.processDirectOverriddenPropertiesWithBaseScope(propertySymbol, processor)
}
override fun processDirectOverriddenFunctionsWithBaseScope(
functionSymbol: FirNamedFunctionSymbol,
processor: (FirNamedFunctionSymbol, FirTypeScope) -> ProcessorAction,
): ProcessorAction {
val overridden = synthesizedOverrides[functionSymbol]
?: return useSiteMemberScope.processDirectOverriddenFunctionsWithBaseScope(functionSymbol, processor)
return processor(overridden, useSiteMemberScope)
} }
override fun getCallableNames(): Set<Name> { override fun getCallableNames(): Set<Name> {
return useSiteMemberScope.getCallableNames() return declaredMemberScope.getCallableNames()
} }
override fun getClassifierNames(): Set<Name> { override fun getClassifierNames(): Set<Name> {
return useSiteMemberScope.getClassifierNames() return declaredMemberScope.getClassifierNames()
} }
override fun processPropertiesByName(name: Name, processor: (FirVariableSymbol<*>) -> Unit) { override fun processPropertiesByName(name: Name, processor: (FirVariableSymbol<*>) -> Unit) {
useSiteMemberScope.processPropertiesByName(name, processor) declaredMemberScope.processPropertiesByName(name, processor)
} }
override fun processFunctionsByName(name: Name, processor: (FirNamedFunctionSymbol) -> Unit) { override fun processFunctionsByName(name: Name, processor: (FirNamedFunctionSymbol) -> Unit) {
if (name !in ANY_MEMBER_NAMES) { if (name !in ANY_MEMBER_NAMES) {
useSiteMemberScope.processFunctionsByName(name, processor) declaredMemberScope.processFunctionsByName(name, processor)
return return
} }
useSiteMemberScope.processFunctionsByName(name) { fromUseSiteScope -> var synthesizedFunctionIsNeeded = true
if (fromUseSiteScope.rawStatus.modality == Modality.FINAL) { declaredMemberScope.processFunctionsByName(name) process@{ fromDeclaredScope ->
processor(fromUseSiteScope) if (fromDeclaredScope.matchesSomeAnyMember(name)) {
} else { // TODO: should we handle fromDeclaredScope.origin == FirDeclarationOrigin.Delegated somehow?
val matchedSomeAnyMember = when (name) { // See also KT-58926
OperatorNameConventions.HASH_CODE, OperatorNameConventions.TO_STRING -> { synthesizedFunctionIsNeeded = false
fromUseSiteScope.valueParameterSymbols.isEmpty() && !fromUseSiteScope.isExtension && }
fromUseSiteScope.fir.contextReceivers.isEmpty() processor(fromDeclaredScope)
} }
else -> { if (!synthesizedFunctionIsNeeded) return
fromUseSiteScope.lazyResolveToPhase(FirResolvePhase.TYPES) superKlassScope?.processFunctionsByName(name) { fromSuperType ->
fromUseSiteScope.fir.isEquals() if (synthesizedFunctionIsNeeded) {
} if (fromSuperType.rawStatus.modality == Modality.FINAL && fromSuperType.matchesSomeAnyMember(name)) {
} synthesizedFunctionIsNeeded = false
val hasSameReceiver =
dispatchReceiverType.lookupTag == (fromUseSiteScope.dispatchReceiverType as? ConeClassLikeType)?.lookupTag
if (!matchedSomeAnyMember || hasSameReceiver) {
processor(fromUseSiteScope)
} else {
val synthesized = synthesizedCache.synthesizedFunctionAndOverrides.getValue(name, this)
synthesizedOverrides[synthesized] = fromUseSiteScope
processor(synthesized)
} }
} }
} }
if (!synthesizedFunctionIsNeeded) return
processor(synthesizedCache.synthesizedFunction.getValue(name, this))
}
private fun FirNamedFunctionSymbol.matchesSomeAnyMember(name: Name): Boolean {
return when (name) {
OperatorNameConventions.HASH_CODE, OperatorNameConventions.TO_STRING -> {
valueParameterSymbols.isEmpty() && !isExtension && fir.contextReceivers.isEmpty()
}
else -> {
lazyResolveToPhase(FirResolvePhase.TYPES)
fir.isEquals()
}
}
} }
internal fun generateSyntheticFunctionByName(name: Name): FirNamedFunctionSymbol = internal fun generateSyntheticFunctionByName(name: Name): FirNamedFunctionSymbol =
@@ -191,7 +191,7 @@ class FirSynthesizedStorage(val session: FirSession) : FirSessionComponent {
cachesFactory.createCache { _ -> SynthesizedCache(session.firCachesFactory) } cachesFactory.createCache { _ -> SynthesizedCache(session.firCachesFactory) }
class SynthesizedCache(cachesFactory: FirCachesFactory) { class SynthesizedCache(cachesFactory: FirCachesFactory) {
val synthesizedFunctionAndOverrides: FirCache<Name, FirNamedFunctionSymbol, FirClassAnySynthesizedMemberScope> = val synthesizedFunction: FirCache<Name, FirNamedFunctionSymbol, FirClassAnySynthesizedMemberScope> =
cachesFactory.createCache { name, scope -> scope.generateSyntheticFunctionByName(name) } cachesFactory.createCache { name, scope -> scope.generateSyntheticFunctionByName(name) }
} }
} }
@@ -0,0 +1,20 @@
// TARGET_BACKEND: JVM_IR
// ISSUE: KT-58926
fun box(): String {
val i1 = Impl()
val i2 = Impl()
val d1 = Data(i1, 1)
val d2 = Data(i2, 2)
return if (d1 != d2) "FAIL: should be equal" else "OK"
}
interface AnyNeighbor {
override fun equals(other: Any?): Boolean
}
class Impl : AnyNeighbor {
override fun equals(other: Any?): Boolean = true
}
data class Data(val i: Impl, val j: Int) : AnyNeighbor by i
@@ -18411,6 +18411,12 @@ public class IrBlackBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTes
runTest("compiler/testData/codegen/box/fir/CustomThrowableMessage.kt"); runTest("compiler/testData/codegen/box/fir/CustomThrowableMessage.kt");
} }
@Test
@TestMetadata("delegatedAndDataTogether.kt")
public void testDelegatedAndDataTogether() throws Exception {
runTest("compiler/testData/codegen/box/fir/delegatedAndDataTogether.kt");
}
@Test @Test
@TestMetadata("differentSinceKotlin.kt") @TestMetadata("differentSinceKotlin.kt")
public void testDifferentSinceKotlin() throws Exception { public void testDifferentSinceKotlin() throws Exception {
@@ -18411,6 +18411,12 @@ public class IrBlackBoxCodegenWithIrInlinerTestGenerated extends AbstractIrBlack
runTest("compiler/testData/codegen/box/fir/CustomThrowableMessage.kt"); runTest("compiler/testData/codegen/box/fir/CustomThrowableMessage.kt");
} }
@Test
@TestMetadata("delegatedAndDataTogether.kt")
public void testDelegatedAndDataTogether() throws Exception {
runTest("compiler/testData/codegen/box/fir/delegatedAndDataTogether.kt");
}
@Test @Test
@TestMetadata("differentSinceKotlin.kt") @TestMetadata("differentSinceKotlin.kt")
public void testDifferentSinceKotlin() throws Exception { public void testDifferentSinceKotlin() throws Exception {