From fe69b21aedfd745ec72f48d0b66acb12cd31ef0f Mon Sep 17 00:00:00 2001 From: Yan Zhulanow Date: Mon, 24 Oct 2022 15:35:38 +0900 Subject: [PATCH] [FE] Fix 'containingClassForStaticMemberAttr' for fake overrides (KTIJ-22808) --- .../api/fir/components/KtFirCallResolver.kt | 24 +++++++-- .../api/fir/resolver/AllCandidatesResolver.kt | 10 ++-- .../kotlin/fir/backend/ConversionUtils.kt | 20 +++++--- .../generators/ClassMemberGenerator.kt | 11 +++- .../generators/FakeOverrideGenerator.kt | 10 ++-- .../kotlin/fir/java/JavaScopeProvider.kt | 2 +- .../fir/resolve/scopes/JvmMappedScopes.kt | 1 + .../kotlin/fir/scopes/jvm/JvmMappedScope.kt | 7 ++- .../kotlin/fir/resolve/ScopeUtils.kt | 49 +++++++++++------- .../fir/scopes/FirKotlinScopeProvider.kt | 19 ++++--- .../scopes/impl/FirClassSubstitutionScope.kt | 14 +++-- .../scopes/impl/FirDelegatedMemberScope.kt | 2 + .../scopes/impl/FirFakeOverrideGenerator.kt | 51 ++++++++++++------- .../impl/FirTypeIntersectionScopeContext.kt | 7 ++- .../jetbrains/kotlin/fir/FirCallResolver.kt | 5 +- .../resolve/FirDefaultParametersResolver.kt | 2 +- .../resolve/calls/ConstructorProcessing.kt | 14 +++-- .../resolve/calls/tower/FirTowerResolver.kt | 8 +-- .../FirExpressionsResolveTransformer.kt | 4 +- 19 files changed, 176 insertions(+), 84 deletions(-) diff --git a/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/components/KtFirCallResolver.kt b/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/components/KtFirCallResolver.kt index 8479c4b1b18..fdcce36f039 100644 --- a/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/components/KtFirCallResolver.kt +++ b/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/components/KtFirCallResolver.kt @@ -26,6 +26,7 @@ import org.jetbrains.kotlin.analysis.api.symbols.* import org.jetbrains.kotlin.analysis.api.types.KtSubstitutor import org.jetbrains.kotlin.analysis.api.types.KtType import org.jetbrains.kotlin.analysis.low.level.api.fir.api.getOrBuildFir +import org.jetbrains.kotlin.analysis.low.level.api.fir.api.getOrBuildFirSafe import org.jetbrains.kotlin.analysis.low.level.api.fir.resolver.AllCandidatesResolver import org.jetbrains.kotlin.analysis.low.level.api.fir.util.errorWithFirSpecificEntries import org.jetbrains.kotlin.analysis.low.level.api.fir.util.withFirEntry @@ -73,6 +74,7 @@ import org.jetbrains.kotlin.utils.addToStdlib.safeAs import org.jetbrains.kotlin.analysis.utils.errors.buildErrorWithAttachment import org.jetbrains.kotlin.analysis.utils.errors.shouldIjPlatformExceptionBeRethrown import org.jetbrains.kotlin.analysis.utils.errors.withPsiEntry +import org.jetbrains.kotlin.fir.declarations.FirClass import org.jetbrains.kotlin.fir.diagnostics.FirDiagnosticHolder internal class KtFirCallResolver( @@ -966,11 +968,23 @@ internal class KtFirCallResolver( psi: KtElement, resolveFragmentOfCall: Boolean ): List { - val candidates = AllCandidatesResolver(analysisSession.useSiteSession).getAllCandidatesForDelegatedConstructor( - analysisSession.firResolveSession, - this, - psi - ) + fun findDerivedClass(psi: KtElement): KtClassOrObject? { + val parent = psi.parent + return when (psi) { + is KtConstructorDelegationCall -> ((parent as? KtSecondaryConstructor)?.parent as? KtClassBody)?.parent as? KtClassOrObject + is KtSuperTypeCallEntry -> (parent as? KtSuperTypeList)?.parent as? KtClassOrObject + is KtConstructorCalleeExpression -> (parent as? KtElement)?.let(::findDerivedClass) + else -> null + } + } + + val derivedClass = findDerivedClass(psi) + ?.getOrBuildFirSafe(firResolveSession) + ?: return emptyList() + + val candidates = AllCandidatesResolver(analysisSession.useSiteSession) + .getAllCandidatesForDelegatedConstructor(analysisSession.firResolveSession, this, derivedClass.symbol.toLookupTag(), psi) + return candidates.mapNotNull { convertToKtCallCandidateInfo( this, diff --git a/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/resolver/AllCandidatesResolver.kt b/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/resolver/AllCandidatesResolver.kt index 300da5b0af6..fc3d3f81b97 100644 --- a/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/resolver/AllCandidatesResolver.kt +++ b/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/resolver/AllCandidatesResolver.kt @@ -18,6 +18,7 @@ import org.jetbrains.kotlin.fir.resolve.calls.ResolutionContext import org.jetbrains.kotlin.fir.resolve.calls.tower.FirTowerResolver import org.jetbrains.kotlin.fir.resolve.transformers.body.resolve.FirBodyResolveTransformer import org.jetbrains.kotlin.fir.resolve.transformers.body.resolve.FirExpressionsResolveTransformer +import org.jetbrains.kotlin.fir.symbols.ConeClassLikeLookupTag import org.jetbrains.kotlin.fir.symbols.SymbolInternals import org.jetbrains.kotlin.fir.types.ConeClassLikeType import org.jetbrains.kotlin.fir.types.coneType @@ -71,6 +72,7 @@ class AllCandidatesResolver(private val firSession: FirSession) { fun getAllCandidatesForDelegatedConstructor( firResolveSession: LLFirResolveSession, delegatedConstructorCall: FirDelegatedConstructorCall, + derivedClassLookupTag: ConeClassLikeLookupTag, element: KtElement ): List { initializeBodyResolveContext(firResolveSession, element) @@ -78,10 +80,10 @@ class AllCandidatesResolver(private val firSession: FirSession) { val firFile = element.containingKtFile.getOrBuildFirFile(firResolveSession) val constructedType = delegatedConstructorCall.constructedTypeRef.coneType as ConeClassLikeType return bodyResolveComponents.context.withFile(firFile, bodyResolveComponents) { - bodyResolveComponents.callResolver.resolveDelegatingConstructorCall(delegatedConstructorCall, constructedType) - bodyResolveComponents.collector.allCandidates.map { - OverloadCandidate(it, isInBestCandidates = it in bodyResolveComponents.collector.bestCandidates()) - } + bodyResolveComponents.callResolver + .resolveDelegatingConstructorCall(delegatedConstructorCall, constructedType, derivedClassLookupTag) + bodyResolveComponents.collector.allCandidates + .map { OverloadCandidate(it, isInBestCandidates = it in bodyResolveComponents.collector.bestCandidates()) } } } diff --git a/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/ConversionUtils.kt b/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/ConversionUtils.kt index 3715ed0943f..24fee225f41 100644 --- a/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/ConversionUtils.kt +++ b/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/ConversionUtils.kt @@ -356,11 +356,16 @@ internal tailrec fun FirCallableSymbol<*>.unwrapSubstitutionAndIntersectionOverr } context(Fir2IrComponents) -internal tailrec fun FirCallableSymbol<*>.unwrapCallRepresentative(root: FirCallableSymbol<*> = this): FirCallableSymbol<*> { +internal tailrec fun FirCallableSymbol<*>.unwrapCallRepresentative( + owner: ConeClassLikeLookupTag? = containingClassLookupTag() +): FirCallableSymbol<*> { val fir = fir + if (fir is FirConstructor) { val originalForTypeAlias = fir.originalConstructorIfTypeAlias - if (originalForTypeAlias != null) return originalForTypeAlias.symbol.unwrapCallRepresentative(this) + if (originalForTypeAlias != null) { + return originalForTypeAlias.symbol.unwrapCallRepresentative(owner) + } } if (fir.isIntersectionOverride) { @@ -370,17 +375,18 @@ internal tailrec fun FirCallableSymbol<*>.unwrapCallRepresentative(root: FirCall // interface C : A, B // for C.foo we've got an IR fake override // for {A & B} we don't have such an IR declaration, so we're unwrapping it if (fir.dispatchReceiverType is ConeIntersectionType) { - return fir.baseForIntersectionOverride!!.symbol.unwrapCallRepresentative(this) + return fir.baseForIntersectionOverride!!.symbol.unwrapCallRepresentative(owner) } return this } - val overriddenSymbol = fir.originalForSubstitutionOverride?.takeIf { - it.containingClassLookupTag() == root.containingClassLookupTag() - }?.symbol ?: return this + val originalForOverride = fir.originalForSubstitutionOverride + if (originalForOverride != null && originalForOverride.containingClassLookupTag() == owner) { + return originalForOverride.symbol.unwrapCallRepresentative(owner) + } - return overriddenSymbol.unwrapCallRepresentative(this) + return this } context(Fir2IrComponents) diff --git a/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/generators/ClassMemberGenerator.kt b/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/generators/ClassMemberGenerator.kt index 12d09803630..b1408474a21 100644 --- a/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/generators/ClassMemberGenerator.kt +++ b/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/generators/ClassMemberGenerator.kt @@ -8,6 +8,7 @@ package org.jetbrains.kotlin.fir.backend.generators import org.jetbrains.kotlin.descriptors.ClassKind import org.jetbrains.kotlin.descriptors.Visibilities import org.jetbrains.kotlin.fir.backend.* +import org.jetbrains.kotlin.fir.containingClassLookupTag import org.jetbrains.kotlin.fir.declarations.* import org.jetbrains.kotlin.fir.declarations.impl.FirDefaultPropertyGetter import org.jetbrains.kotlin.fir.declarations.impl.FirDefaultPropertySetter @@ -22,6 +23,7 @@ import org.jetbrains.kotlin.fir.extensions.declarationGenerators import org.jetbrains.kotlin.fir.extensions.extensionService import org.jetbrains.kotlin.fir.extensions.generatedMembers import org.jetbrains.kotlin.fir.extensions.generatedNestedClassifiers +import org.jetbrains.kotlin.fir.getOwnerLookupTag import org.jetbrains.kotlin.fir.resolve.fullyExpandedType import org.jetbrains.kotlin.fir.resolvedSymbol import org.jetbrains.kotlin.fir.symbols.impl.FirConstructorSymbol @@ -339,7 +341,14 @@ internal class ClassMemberGenerator( startOffset, endOffset, constructedIrType, "Cannot find delegated constructor call" ) } - val constructorSymbol = referencedSymbol.unwrapCallRepresentative() as FirConstructorSymbol + + // Unwrap substitution overrides from both derived class and a super class + val constructorSymbol = referencedSymbol + .unwrapCallRepresentative(referencedSymbol.containingClassLookupTag()) + .unwrapCallRepresentative((referencedSymbol.resolvedReturnType as? ConeClassLikeType)?.lookupTag) + + check(constructorSymbol is FirConstructorSymbol) + val firDispatchReceiver = dispatchReceiver return convertWithOffsets { startOffset, endOffset -> val irConstructorSymbol = declarationStorage.getIrFunctionSymbol(constructorSymbol) as IrConstructorSymbol diff --git a/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/generators/FakeOverrideGenerator.kt b/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/generators/FakeOverrideGenerator.kt index 7234c27aace..efa56ea5c7a 100644 --- a/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/generators/FakeOverrideGenerator.kt +++ b/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/generators/FakeOverrideGenerator.kt @@ -118,6 +118,7 @@ class FakeOverrideGenerator( val symbol = FirFakeOverrideGenerator.createSymbolForSubstitutionOverride(callableSymbol, firClass.symbol.classId) FirFakeOverrideGenerator.createSubstitutionOverrideFunction( session, symbol, firFunction, + derivedClassLookupTag = firClass.symbol.toLookupTag(), newDispatchReceiverType = firClass.defaultType(), isExpect = (firClass as? FirRegularClass)?.isExpect == true ) @@ -145,6 +146,7 @@ class FakeOverrideGenerator( FirFakeOverrideGenerator.createSymbolForSubstitutionOverride(callableSymbol, firClass.symbol.classId) FirFakeOverrideGenerator.createSubstitutionOverrideProperty( session, symbolForOverride, firProperty, + derivedClassLookupTag = firClass.symbol.toLookupTag(), newDispatchReceiverType = firClass.defaultType(), isExpect = (firClass as? FirRegularClass)?.isExpect == true ) @@ -169,11 +171,11 @@ class FakeOverrideGenerator( { field, irParent, _, _, _ -> declarationStorage.createIrField(field, irParent) }, - createFakeOverrideSymbol = { firField, callableSymbol -> + createFakeOverrideSymbol = { firField, _ -> FirFakeOverrideGenerator.createSubstitutionOverrideField( - session, firField, callableSymbol, + session, firField, + derivedClassLookupTag = firClass.symbol.toLookupTag(), newReturnType = firField.returnTypeRef.coneType, - derivedClassId = firClass.symbol.classId ) }, baseStaticFieldSymbols, @@ -324,6 +326,7 @@ class FakeOverrideGenerator( createFakeOverrideSymbol = { firFunction, callableSymbol -> FirFakeOverrideGenerator.createSubstitutionOverrideFunction( session, callableSymbol, firFunction, + derivedClassLookupTag = klass.symbol.toLookupTag(), newDispatchReceiverType = klass.defaultType(), isExpect = (klass as? FirRegularClass)?.isExpect == true ) @@ -342,6 +345,7 @@ class FakeOverrideGenerator( createFakeOverrideSymbol = { firProperty, callableSymbol -> FirFakeOverrideGenerator.createSubstitutionOverrideProperty( session, callableSymbol, firProperty, + derivedClassLookupTag = klass.symbol.toLookupTag(), newDispatchReceiverType = klass.defaultType(), isExpect = (klass as? FirRegularClass)?.isExpect == true ) diff --git a/compiler/fir/java/src/org/jetbrains/kotlin/fir/java/JavaScopeProvider.kt b/compiler/fir/java/src/org/jetbrains/kotlin/fir/java/JavaScopeProvider.kt index cd400190fd4..d84f9def10f 100644 --- a/compiler/fir/java/src/org/jetbrains/kotlin/fir/java/JavaScopeProvider.kt +++ b/compiler/fir/java/src/org/jetbrains/kotlin/fir/java/JavaScopeProvider.kt @@ -93,7 +93,7 @@ object JavaScopeProvider : FirScopeProvider() { ) val superTypeScopes = superTypes.mapNotNull { - it.scopeForSupertype(useSiteSession, scopeSession, subClass = regularClass) + it.scopeForSupertype(useSiteSession, scopeSession, regularClass) } JavaClassUseSiteMemberScope( diff --git a/compiler/fir/java/src/org/jetbrains/kotlin/fir/resolve/scopes/JvmMappedScopes.kt b/compiler/fir/java/src/org/jetbrains/kotlin/fir/resolve/scopes/JvmMappedScopes.kt index 5aacf562a4d..33c893b70e2 100644 --- a/compiler/fir/java/src/org/jetbrains/kotlin/fir/resolve/scopes/JvmMappedScopes.kt +++ b/compiler/fir/java/src/org/jetbrains/kotlin/fir/resolve/scopes/JvmMappedScopes.kt @@ -81,6 +81,7 @@ private fun wrapSubstitutionScopeIfNeed( session, useSiteMemberScope, PLATFORM_TYPE_PARAMETERS_SUBSTITUTION_SCOPE_KEY, substitutor, dispatchReceiverTypeForSubstitutedMembers = derivedClass.defaultType(), skipPrivateMembers = true, + derivedClassLookupTag = derivedClass.symbol.toLookupTag() ) } } diff --git a/compiler/fir/java/src/org/jetbrains/kotlin/fir/scopes/jvm/JvmMappedScope.kt b/compiler/fir/java/src/org/jetbrains/kotlin/fir/scopes/jvm/JvmMappedScope.kt index ecfec4f2642..71971e32e67 100644 --- a/compiler/fir/java/src/org/jetbrains/kotlin/fir/scopes/jvm/JvmMappedScope.kt +++ b/compiler/fir/java/src/org/jetbrains/kotlin/fir/scopes/jvm/JvmMappedScope.kt @@ -7,7 +7,6 @@ package org.jetbrains.kotlin.fir.scopes.jvm import org.jetbrains.kotlin.builtins.jvm.JvmBuiltInsSignatures import org.jetbrains.kotlin.fir.FirSession -import org.jetbrains.kotlin.fir.containingClassForStaticMemberAttr import org.jetbrains.kotlin.fir.declarations.FirClass import org.jetbrains.kotlin.fir.declarations.FirRegularClass import org.jetbrains.kotlin.fir.declarations.utils.classId @@ -81,6 +80,7 @@ class JvmMappedScope( FirFakeOverrideGenerator.createCopyForFirFunction( newSymbol, baseFunction = symbol.fir, + derivedClassLookupTag = firKotlinClass.symbol.toLookupTag(), session, symbol.fir.origin, newDispatchReceiverType = kotlinDispatchReceiverType, @@ -125,6 +125,7 @@ class JvmMappedScope( newSymbol, session, oldConstructor, + derivedClassLookupTag = firKotlinClass.symbol.toLookupTag(), symbol.fir.origin, newDispatchReceiverType = null, newReturnType = substitutor.substituteOrSelf(oldConstructor.returnTypeRef.coneType), @@ -133,9 +134,7 @@ class JvmMappedScope( newContextReceiverTypes = emptyList(), isExpect = false, fakeOverrideSubstitution = null - ).apply { - containingClassForStaticMemberAttr = firKotlinClass.symbol.toLookupTag() - } + ) newSymbol } } diff --git a/compiler/fir/providers/src/org/jetbrains/kotlin/fir/resolve/ScopeUtils.kt b/compiler/fir/providers/src/org/jetbrains/kotlin/fir/resolve/ScopeUtils.kt index 01b82519c2e..c425a1802ff 100644 --- a/compiler/fir/providers/src/org/jetbrains/kotlin/fir/resolve/ScopeUtils.kt +++ b/compiler/fir/providers/src/org/jetbrains/kotlin/fir/resolve/ScopeUtils.kt @@ -16,6 +16,7 @@ import org.jetbrains.kotlin.fir.scopes.impl.FirScopeWithFakeOverrideTypeCalculat import org.jetbrains.kotlin.fir.scopes.impl.FirTypeIntersectionScope import org.jetbrains.kotlin.fir.scopes.impl.dynamicMembersStorage import org.jetbrains.kotlin.fir.scopes.impl.getOrBuildScopeForIntegerConstantOperatorType +import org.jetbrains.kotlin.fir.symbols.ConeClassLikeLookupTag import org.jetbrains.kotlin.fir.symbols.impl.ConeClassLikeLookupTagImpl import org.jetbrains.kotlin.fir.symbols.impl.FirClassSymbol import org.jetbrains.kotlin.fir.symbols.impl.FirTypeParameterSymbol @@ -43,6 +44,14 @@ fun FirSmartCastExpression.smartcastScope( return FirUnstableSmartcastTypeScope(smartcastScope, originalScope) } +fun ConeClassLikeType.delegatingConstructorScope( + useSiteSession: FirSession, + scopeSession: ScopeSession, + derivedClassLookupTag: ConeClassLikeLookupTag? +): FirTypeScope? { + return classScope(useSiteSession, scopeSession, FirResolvePhase.DECLARATIONS, derivedClassLookupTag) +} + fun ConeKotlinType.scope( useSiteSession: FirSession, scopeSession: ScopeSession, @@ -56,23 +65,7 @@ fun ConeKotlinType.scope( private fun ConeKotlinType.scope(useSiteSession: FirSession, scopeSession: ScopeSession, requiredPhase: FirResolvePhase): FirTypeScope? { return when (this) { is ConeErrorType -> null - is ConeClassLikeType -> { - val fullyExpandedType = fullyExpandedType(useSiteSession) - val fir = fullyExpandedType.lookupTag.toSymbol(useSiteSession)?.fir as? FirClass ?: return null - - fir.symbol.lazyResolveToPhase(requiredPhase) - - val substitutor = when { - attributes.contains(CompilerConeAttributes.RawType) -> ConeRawScopeSubstitutor(useSiteSession) - else -> substitutorByMap( - createSubstitution(fir.typeParameters, fullyExpandedType, useSiteSession), - useSiteSession, - ) - } - - fir.scopeForClass(substitutor, useSiteSession, scopeSession) - } - + is ConeClassLikeType -> classScope(useSiteSession, scopeSession, requiredPhase, derivedClassLookupTag = null) is ConeTypeParameterType -> { val symbol = lookupTag.symbol scopeSession.getOrBuild(symbol, TYPE_PARAMETER_SCOPE_KEY) { @@ -103,6 +96,28 @@ private fun ConeKotlinType.scope(useSiteSession: FirSession, scopeSession: Scope } } +private fun ConeClassLikeType.classScope( + useSiteSession: FirSession, + scopeSession: ScopeSession, + requiredPhase: FirResolvePhase, + derivedClassLookupTag: ConeClassLikeLookupTag? +): FirTypeScope? { + val fullyExpandedType = fullyExpandedType(useSiteSession) + val fir = fullyExpandedType.lookupTag.toSymbol(useSiteSession)?.fir as? FirClass ?: return null + + fir.symbol.lazyResolveToPhase(requiredPhase) + + val substitutor = when { + attributes.contains(CompilerConeAttributes.RawType) -> ConeRawScopeSubstitutor(useSiteSession) + else -> substitutorByMap( + createSubstitution(fir.typeParameters, fullyExpandedType, useSiteSession), + useSiteSession, + ) + } + + return fir.scopeForClass(substitutor, useSiteSession, scopeSession, derivedClassLookupTag) +} + private fun ConeClassLikeType.obtainFirOfClass(useSiteSession: FirSession, requiredPhase: FirResolvePhase): FirClass? { val fullyExpandedType = fullyExpandedType(useSiteSession) val fir = fullyExpandedType.lookupTag.toSymbol(useSiteSession)?.fir as? FirClass ?: return null diff --git a/compiler/fir/providers/src/org/jetbrains/kotlin/fir/scopes/FirKotlinScopeProvider.kt b/compiler/fir/providers/src/org/jetbrains/kotlin/fir/scopes/FirKotlinScopeProvider.kt index 2c3ae93fc04..e342bb1f6ce 100644 --- a/compiler/fir/providers/src/org/jetbrains/kotlin/fir/scopes/FirKotlinScopeProvider.kt +++ b/compiler/fir/providers/src/org/jetbrains/kotlin/fir/scopes/FirKotlinScopeProvider.kt @@ -107,19 +107,21 @@ fun FirClassSymbol<*>.unsubstitutedScope( fun FirClass.scopeForClass( substitutor: ConeSubstitutor, useSiteSession: FirSession, - scopeSession: ScopeSession + scopeSession: ScopeSession, + derivedClassLookupTag: ConeClassLikeLookupTag? ): FirTypeScope = scopeForClassImpl( substitutor, useSiteSession, scopeSession, skipPrivateMembers = false, classFirDispatchReceiver = this, // TODO: why it's always false? - isFromExpectClass = false + isFromExpectClass = false, + derivedClassLookupTag = derivedClassLookupTag ) fun ConeKotlinType.scopeForSupertype( useSiteSession: FirSession, scopeSession: ScopeSession, - subClass: FirClass, + derivedClass: FirClass, ): FirTypeScope? { if (this !is ConeClassLikeType) return null if (this is ConeErrorType) return null @@ -136,8 +138,9 @@ fun ConeKotlinType.scopeForSupertype( useSiteSession, scopeSession, skipPrivateMembers = true, - classFirDispatchReceiver = subClass, - isFromExpectClass = (subClass as? FirRegularClass)?.isExpect == true + classFirDispatchReceiver = derivedClass, + isFromExpectClass = (derivedClass as? FirRegularClass)?.isExpect == true, + derivedClassLookupTag = derivedClass.symbol.toLookupTag() ) } @@ -153,7 +156,8 @@ private fun FirClass.scopeForClassImpl( scopeSession: ScopeSession, skipPrivateMembers: Boolean, classFirDispatchReceiver: FirClass, - isFromExpectClass: Boolean + isFromExpectClass: Boolean, + derivedClassLookupTag: ConeClassLikeLookupTag? ): FirTypeScope { val basicScope = unsubstitutedScope(useSiteSession, scopeSession, withForcedTypeCalculator = false) if (substitutor == ConeSubstitutor.Empty) return basicScope @@ -168,7 +172,8 @@ private fun FirClass.scopeForClassImpl( key, substitutor, substitutor.substituteOrSelf(classFirDispatchReceiver.defaultType()).lowerBoundIfFlexible() as ConeClassLikeType, skipPrivateMembers, - makeExpect = isFromExpectClass + makeExpect = isFromExpectClass, + derivedClassLookupTag ?: classFirDispatchReceiver.symbol.toLookupTag() ) } } diff --git a/compiler/fir/providers/src/org/jetbrains/kotlin/fir/scopes/impl/FirClassSubstitutionScope.kt b/compiler/fir/providers/src/org/jetbrains/kotlin/fir/scopes/impl/FirClassSubstitutionScope.kt index 80e87214fb3..f179b1e0adf 100644 --- a/compiler/fir/providers/src/org/jetbrains/kotlin/fir/scopes/impl/FirClassSubstitutionScope.kt +++ b/compiler/fir/providers/src/org/jetbrains/kotlin/fir/scopes/impl/FirClassSubstitutionScope.kt @@ -20,6 +20,7 @@ import org.jetbrains.kotlin.fir.resolve.substitution.chain import org.jetbrains.kotlin.fir.scopes.FakeOverrideSubstitution import org.jetbrains.kotlin.fir.scopes.FirTypeScope import org.jetbrains.kotlin.fir.scopes.ProcessorAction +import org.jetbrains.kotlin.fir.symbols.ConeClassLikeLookupTag import org.jetbrains.kotlin.fir.symbols.FirBasedSymbol import org.jetbrains.kotlin.fir.symbols.impl.* import org.jetbrains.kotlin.fir.symbols.lazyResolveToPhase @@ -34,7 +35,8 @@ class FirClassSubstitutionScope( private val substitutor: ConeSubstitutor, private val dispatchReceiverTypeForSubstitutedMembers: ConeClassLikeType, private val skipPrivateMembers: Boolean, - private val makeExpect: Boolean = false + private val makeExpect: Boolean = false, + private val derivedClassLookupTag: ConeClassLikeLookupTag ) : FirTypeScope() { private val substitutionOverrideCache = session.substitutionOverrideStorage.substitutionOverrideCacheByScope.getValue(key, null) @@ -142,6 +144,7 @@ class FirClassSubstitutionScope( session, symbolForOverride, member, + derivedClassLookupTag = derivedClassLookupTag, newDispatchReceiverType ?: dispatchReceiverTypeForSubstitutedMembers, isExpect = makeExpect, ) @@ -158,6 +161,7 @@ class FirClassSubstitutionScope( session, symbolForOverride, member, + derivedClassLookupTag, newDispatchReceiverType ?: dispatchReceiverTypeForSubstitutedMembers, newReceiverType, newContextReceiverTypes, @@ -202,6 +206,7 @@ class FirClassSubstitutionScope( symbolForOverride, session, constructor, + derivedClassLookupTag, FirDeclarationOrigin.SubstitutionOverride, newDispatchReceiverType, // Constructors' return types are expected to be non-flexible (i.e., non raw) @@ -240,6 +245,7 @@ class FirClassSubstitutionScope( session, symbolForOverride, member, + derivedClassLookupTag = derivedClassLookupTag, newDispatchReceiverType ?: dispatchReceiverTypeForSubstitutedMembers, isExpect = makeExpect, ) @@ -252,6 +258,7 @@ class FirClassSubstitutionScope( session, symbolForOverride, member, + derivedClassLookupTag, newDispatchReceiverType ?: dispatchReceiverTypeForSubstitutedMembers, newReceiverType, newContextReceiverTypes, @@ -310,9 +317,7 @@ class FirClassSubstitutionScope( // TODO: do we have fields with implicit type? val newReturnType = returnType?.substitute() ?: return original - return FirFakeOverrideGenerator.createSubstitutionOverrideField( - session, member, original, newReturnType, newOwnerClassId - ) + return FirFakeOverrideGenerator.createSubstitutionOverrideField(session, member, derivedClassLookupTag, newReturnType) } fun createSubstitutionOverrideSyntheticProperty(original: FirSyntheticPropertySymbol): FirSyntheticPropertySymbol { @@ -347,6 +352,7 @@ class FirClassSubstitutionScope( return FirFakeOverrideGenerator.createSubstitutionOverrideSyntheticProperty( session, member, + derivedClassLookupTag, original, substitutor.substituteOrSelf(dispatchReceiverTypeForSubstitutedMembers) as ConeSimpleKotlinType?, newContextReceiverTypes, diff --git a/compiler/fir/providers/src/org/jetbrains/kotlin/fir/scopes/impl/FirDelegatedMemberScope.kt b/compiler/fir/providers/src/org/jetbrains/kotlin/fir/scopes/impl/FirDelegatedMemberScope.kt index 64a82716200..a7a5fa26adf 100644 --- a/compiler/fir/providers/src/org/jetbrains/kotlin/fir/scopes/impl/FirDelegatedMemberScope.kt +++ b/compiler/fir/providers/src/org/jetbrains/kotlin/fir/scopes/impl/FirDelegatedMemberScope.kt @@ -92,6 +92,7 @@ class FirDelegatedMemberScope( functionSymbol.callableId, ), original, + derivedClassLookupTag = null, session, FirDeclarationOrigin.Delegated, newDispatchReceiverType = dispatchReceiverType, @@ -161,6 +162,7 @@ class FirDelegatedMemberScope( propertySymbol.callableId ), original, + derivedClassLookupTag = null, session, FirDeclarationOrigin.Delegated, newModality = Modality.OPEN, diff --git a/compiler/fir/providers/src/org/jetbrains/kotlin/fir/scopes/impl/FirFakeOverrideGenerator.kt b/compiler/fir/providers/src/org/jetbrains/kotlin/fir/scopes/impl/FirFakeOverrideGenerator.kt index 0f39feed08b..192c57800a6 100644 --- a/compiler/fir/providers/src/org/jetbrains/kotlin/fir/scopes/impl/FirFakeOverrideGenerator.kt +++ b/compiler/fir/providers/src/org/jetbrains/kotlin/fir/scopes/impl/FirFakeOverrideGenerator.kt @@ -20,6 +20,7 @@ import org.jetbrains.kotlin.fir.resolve.substitution.ConeSubstitutor import org.jetbrains.kotlin.fir.resolve.substitution.substitutorByMap import org.jetbrains.kotlin.fir.scopes.FakeOverrideSubstitution import org.jetbrains.kotlin.fir.scopes.fakeOverrideSubstitution +import org.jetbrains.kotlin.fir.symbols.ConeClassLikeLookupTag import org.jetbrains.kotlin.fir.symbols.FirBasedSymbol import org.jetbrains.kotlin.fir.symbols.impl.* import org.jetbrains.kotlin.fir.types.* @@ -36,6 +37,7 @@ object FirFakeOverrideGenerator { session: FirSession, symbolForSubstitutionOverride: FirNamedFunctionSymbol, baseFunction: FirSimpleFunction, + derivedClassLookupTag: ConeClassLikeLookupTag?, newDispatchReceiverType: ConeSimpleKotlinType?, newReceiverType: ConeKotlinType? = null, newContextReceiverTypes: List? = null, @@ -46,8 +48,8 @@ object FirFakeOverrideGenerator { fakeOverrideSubstitution: FakeOverrideSubstitution? = null ): FirNamedFunctionSymbol { createSubstitutionOverrideFunction( - symbolForSubstitutionOverride, session, baseFunction, newDispatchReceiverType, newReceiverType, newContextReceiverTypes, - newReturnType, newParameterTypes, newTypeParameters, isExpect, fakeOverrideSubstitution + symbolForSubstitutionOverride, session, baseFunction, derivedClassLookupTag, newDispatchReceiverType, newReceiverType, + newContextReceiverTypes, newReturnType, newParameterTypes, newTypeParameters, isExpect, fakeOverrideSubstitution ) return symbolForSubstitutionOverride } @@ -64,6 +66,7 @@ object FirFakeOverrideGenerator { fakeOverrideSymbol: FirNamedFunctionSymbol, session: FirSession, baseFunction: FirSimpleFunction, + derivedClassLookupTag: ConeClassLikeLookupTag?, newDispatchReceiverType: ConeSimpleKotlinType?, newReceiverType: ConeKotlinType?, newContextReceiverTypes: List?, @@ -78,6 +81,7 @@ object FirFakeOverrideGenerator { return createCopyForFirFunction( fakeOverrideSymbol, baseFunction, + derivedClassLookupTag = derivedClassLookupTag, session, FirDeclarationOrigin.SubstitutionOverride, isExpect, @@ -90,15 +94,13 @@ object FirFakeOverrideGenerator { fakeOverrideSubstitution = fakeOverrideSubstitution ).apply { originalForSubstitutionOverrideAttr = baseFunction - if (isStatic) { - containingClassForStaticMemberAttr = (newDispatchReceiverType as? ConeClassLikeType)?.lookupTag - } } } fun createCopyForFirFunction( newSymbol: FirNamedFunctionSymbol, baseFunction: FirSimpleFunction, + derivedClassLookupTag: ConeClassLikeLookupTag?, session: FirSession, origin: FirDeclarationOrigin, isExpect: Boolean = baseFunction.isExpect, @@ -128,6 +130,8 @@ object FirFakeOverrideGenerator { newReceiverType, newContextReceiverTypes, newReturnType, fakeOverrideSubstitution, newSymbol ).filterIsInstance() deprecationsProvider = baseFunction.deprecationsProvider + }.apply { + containingClassForStaticMemberAttr = derivedClassLookupTag.takeIf { shouldOverrideSetContainingClass(baseFunction) } } } @@ -135,6 +139,7 @@ object FirFakeOverrideGenerator { fakeOverrideSymbol: FirConstructorSymbol, session: FirSession, baseConstructor: FirConstructor, + derivedClassLookupTag: ConeClassLikeLookupTag?, origin: FirDeclarationOrigin, newDispatchReceiverType: ConeSimpleKotlinType?, newReturnType: ConeKotlinType?, @@ -179,6 +184,7 @@ object FirFakeOverrideGenerator { deprecationsProvider = baseConstructor.deprecationsProvider }.apply { originalForSubstitutionOverrideAttr = baseConstructor + containingClassForStaticMemberAttr = derivedClassLookupTag.takeIf { shouldOverrideSetContainingClass(baseConstructor) } } } @@ -303,6 +309,7 @@ object FirFakeOverrideGenerator { session: FirSession, symbolForSubstitutionOverride: FirPropertySymbol, baseProperty: FirProperty, + derivedClassLookupTag: ConeClassLikeLookupTag, newDispatchReceiverType: ConeSimpleKotlinType?, newReceiverType: ConeKotlinType? = null, newContextReceiverTypes: List? = null, @@ -312,14 +319,11 @@ object FirFakeOverrideGenerator { fakeOverrideSubstitution: FakeOverrideSubstitution? = null ): FirPropertySymbol { createCopyForFirProperty( - symbolForSubstitutionOverride, baseProperty, session, FirDeclarationOrigin.SubstitutionOverride, isExpect, - newDispatchReceiverType, newTypeParameters, newReceiverType, newContextReceiverTypes, newReturnType, + symbolForSubstitutionOverride, baseProperty, derivedClassLookupTag, session, FirDeclarationOrigin.SubstitutionOverride, + isExpect, newDispatchReceiverType, newTypeParameters, newReceiverType, newContextReceiverTypes, newReturnType, fakeOverrideSubstitution = fakeOverrideSubstitution ).apply { originalForSubstitutionOverrideAttr = baseProperty - if (isStatic) { - containingClassForStaticMemberAttr = (newDispatchReceiverType as? ConeClassLikeType)?.lookupTag - } } return symbolForSubstitutionOverride } @@ -335,6 +339,7 @@ object FirFakeOverrideGenerator { fun createCopyForFirProperty( newSymbol: FirPropertySymbol, baseProperty: FirProperty, + derivedClassLookupTag: ConeClassLikeLookupTag?, session: FirSession, origin: FirDeclarationOrigin, isExpect: Boolean = baseProperty.isExpect, @@ -370,6 +375,8 @@ object FirFakeOverrideGenerator { fakeOverrideSubstitution ) deprecationsProvider = baseProperty.deprecationsProvider + }.apply { + containingClassForStaticMemberAttr = derivedClassLookupTag.takeIf { shouldOverrideSetContainingClass(baseProperty) } } } @@ -485,13 +492,10 @@ object FirFakeOverrideGenerator { fun createSubstitutionOverrideField( session: FirSession, baseField: FirField, - baseSymbol: FirFieldSymbol, - newReturnType: ConeKotlinType?, - derivedClassId: ClassId? + derivedClassLookupTag: ConeClassLikeLookupTag, + newReturnType: ConeKotlinType? ): FirFieldSymbol { - val symbol = FirFieldSymbol( - CallableId(derivedClassId ?: baseSymbol.callableId.classId!!, baseField.name) - ) + val symbol = FirFieldSymbol(CallableId(derivedClassLookupTag.classId, baseField.name)) buildField { moduleData = session.moduleData this.symbol = symbol @@ -509,9 +513,7 @@ object FirFakeOverrideGenerator { dispatchReceiverType = baseField.dispatchReceiverType }.apply { originalForSubstitutionOverrideAttr = baseField - if (isStatic && derivedClassId != null) { - containingClassForStaticMemberAttr = ConeClassLikeLookupTagImpl(derivedClassId) - } + containingClassForStaticMemberAttr = derivedClassLookupTag.takeIf { shouldOverrideSetContainingClass(baseField) } } return symbol } @@ -519,6 +521,7 @@ object FirFakeOverrideGenerator { fun createSubstitutionOverrideSyntheticProperty( session: FirSession, baseProperty: FirSyntheticProperty, + derivedClassLookupTag: ConeClassLikeLookupTag, baseSymbol: FirSyntheticPropertySymbol, newDispatchReceiverType: ConeSimpleKotlinType?, newContextReceiverTypes: List?, @@ -532,6 +535,7 @@ object FirFakeOverrideGenerator { getterSymbol, session, baseProperty.getter.delegate, + derivedClassLookupTag, newDispatchReceiverType, newReceiverType = null, newContextReceiverTypes, @@ -546,6 +550,7 @@ object FirFakeOverrideGenerator { setterSymbol, session, baseSetter.delegate, + derivedClassLookupTag, newDispatchReceiverType, newReceiverType = null, newContextReceiverTypes, @@ -562,6 +567,8 @@ object FirFakeOverrideGenerator { delegateSetter = setter status = baseProperty.status deprecationsProvider = getDeprecationsProviderFromAccessors(getter, setter, session.firCachesFactory) + }.apply { + containingClassForStaticMemberAttr = derivedClassLookupTag.takeIf { shouldOverrideSetContainingClass(baseProperty) } }.symbol } @@ -620,6 +627,12 @@ object FirFakeOverrideGenerator { ) } + private fun shouldOverrideSetContainingClass(baseDeclaration: FirCallableDeclaration): Boolean { + return baseDeclaration is FirConstructor + || baseDeclaration.isStatic + || baseDeclaration.containingClassForStaticMemberAttr != null + } + private sealed class Maybe { class Value(val value: A) : Maybe() object Nothing : Maybe() diff --git a/compiler/fir/providers/src/org/jetbrains/kotlin/fir/scopes/impl/FirTypeIntersectionScopeContext.kt b/compiler/fir/providers/src/org/jetbrains/kotlin/fir/scopes/impl/FirTypeIntersectionScopeContext.kt index 5b4fe896d2f..699b28d12ae 100644 --- a/compiler/fir/providers/src/org/jetbrains/kotlin/fir/scopes/impl/FirTypeIntersectionScopeContext.kt +++ b/compiler/fir/providers/src/org/jetbrains/kotlin/fir/scopes/impl/FirTypeIntersectionScopeContext.kt @@ -361,7 +361,9 @@ class FirTypeIntersectionScopeContext( ) val newSymbol = FirIntersectionOverrideFunctionSymbol(callableId, overrides) FirFakeOverrideGenerator.createCopyForFirFunction( - newSymbol, keyFir, session, FirDeclarationOrigin.IntersectionOverride, keyFir.isExpect, + newSymbol, keyFir, + derivedClassLookupTag = null, + session, FirDeclarationOrigin.IntersectionOverride, keyFir.isExpect, newModality = newModality, newVisibility = newVisibility, newDispatchReceiverType = dispatchReceiverType, @@ -386,7 +388,8 @@ class FirTypeIntersectionScopeContext( ) val newSymbol = FirIntersectionOverridePropertySymbol(callableId, overrides) FirFakeOverrideGenerator.createCopyForFirProperty( - newSymbol, keyFir, session, FirDeclarationOrigin.IntersectionOverride, + newSymbol, keyFir, derivedClassLookupTag = null, session, + FirDeclarationOrigin.IntersectionOverride, newModality = newModality, newVisibility = newVisibility, newDispatchReceiverType = dispatchReceiverType, diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/FirCallResolver.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/FirCallResolver.kt index f947b7d7e61..5c1e2c44f2c 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/FirCallResolver.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/FirCallResolver.kt @@ -36,6 +36,7 @@ import org.jetbrains.kotlin.fir.resolve.transformers.body.resolve.FirAbstractBod import org.jetbrains.kotlin.fir.resolve.transformers.body.resolve.FirExpressionsResolveTransformer import org.jetbrains.kotlin.fir.resolve.transformers.body.resolve.resultType import org.jetbrains.kotlin.fir.scopes.unsubstitutedScope +import org.jetbrains.kotlin.fir.symbols.ConeClassLikeLookupTag import org.jetbrains.kotlin.fir.symbols.impl.* import org.jetbrains.kotlin.fir.types.* import org.jetbrains.kotlin.fir.types.builder.buildResolvedTypeRef @@ -470,7 +471,8 @@ class FirCallResolver( fun resolveDelegatingConstructorCall( delegatedConstructorCall: FirDelegatedConstructorCall, - constructedType: ConeClassLikeType? + constructedType: ConeClassLikeType?, + derivedClassLookupTag: ConeClassLikeLookupTag ): FirDelegatedConstructorCall { val name = SpecialNames.INIT val symbol = constructedType?.lookupTag?.toSymbol(components.session) @@ -507,6 +509,7 @@ class FirCallResolver( val result = towerResolver.runResolverForDelegatingConstructor( callInfo, constructedType, + derivedClassLookupTag, transformer.resolutionContext ) diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/FirDefaultParametersResolver.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/FirDefaultParametersResolver.kt index 249ad50ad86..24675417649 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/FirDefaultParametersResolver.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/FirDefaultParametersResolver.kt @@ -31,7 +31,7 @@ class FirDefaultParametersResolver : FirSessionComponent { // imported from object case is FirAbstractImportingScope -> { val containingClass = function.getContainingClass(session) ?: return false - containingClass.scopeForClass(ConeSubstitutor.Empty, session, scopeSession) + containingClass.scopeForClass(ConeSubstitutor.Empty, session, scopeSession, derivedClassLookupTag = null) } else -> return false } diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/ConstructorProcessing.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/ConstructorProcessing.kt index fe6e60d5efe..0b63b809261 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/ConstructorProcessing.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/ConstructorProcessing.kt @@ -209,6 +209,7 @@ private fun FirTypeAliasSymbol.findSAMConstructorForTypeAlias( return FirFakeOverrideGenerator.createSubstitutionOverrideFunction( session, symbolForOverride, samConstructorForClass, + derivedClassLookupTag = null, newDispatchReceiverType = null, newReceiverType = null, newContextReceiverTypes, @@ -262,10 +263,15 @@ private fun processConstructors( } is FirClassSymbol -> { val firClass = matchedSymbol.fir as FirClass - if (firClass.classKind == ClassKind.INTERFACE) null - else firClass.scopeForClass( - substitutor, session, bodyResolveComponents.scopeSession - ) + when (firClass.classKind) { + ClassKind.INTERFACE -> null + else -> firClass.scopeForClass( + substitutor, + session, + bodyResolveComponents.scopeSession, + derivedClassLookupTag = null + ) + } } } diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/tower/FirTowerResolver.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/tower/FirTowerResolver.kt index 46d18a07559..743bc9fc4c0 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/tower/FirTowerResolver.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/tower/FirTowerResolver.kt @@ -10,8 +10,8 @@ import org.jetbrains.kotlin.fir.expressions.FirResolvedQualifier import org.jetbrains.kotlin.fir.references.FirSuperReference import org.jetbrains.kotlin.fir.resolve.BodyResolveComponents import org.jetbrains.kotlin.fir.resolve.calls.* -import org.jetbrains.kotlin.fir.resolve.scope -import org.jetbrains.kotlin.fir.scopes.FakeOverrideTypeCalculator +import org.jetbrains.kotlin.fir.resolve.delegatingConstructorScope +import org.jetbrains.kotlin.fir.symbols.ConeClassLikeLookupTag import org.jetbrains.kotlin.fir.types.ConeClassLikeType import org.jetbrains.kotlin.fir.types.typeContext import org.jetbrains.kotlin.resolve.calls.tasks.ExplicitReceiverKind @@ -91,10 +91,12 @@ class FirTowerResolver( fun runResolverForDelegatingConstructor( info: CallInfo, constructedType: ConeClassLikeType, + derivedClassLookupTag: ConeClassLikeLookupTag, context: ResolutionContext ): CandidateCollector { val outerType = components.outerClassManager.outerType(constructedType) - val scope = constructedType.scope(components.session, components.scopeSession, FakeOverrideTypeCalculator.DoNothing) ?: return collector + val scope = constructedType.delegatingConstructorScope(components.session, components.scopeSession, derivedClassLookupTag) + ?: return collector val dispatchReceiver = if (outerType != null) diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/body/resolve/FirExpressionsResolveTransformer.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/body/resolve/FirExpressionsResolveTransformer.kt index 82981405443..c76440c86aa 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/body/resolve/FirExpressionsResolveTransformer.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/body/resolve/FirExpressionsResolveTransformer.kt @@ -1144,7 +1144,9 @@ open class FirExpressionsResolveTransformer(transformer: FirAbstractBodyResolveT else -> null } - val resolvedCall = callResolver.resolveDelegatingConstructorCall(delegatedConstructorCall, constructorType) + val resolvedCall = callResolver + .resolveDelegatingConstructorCall(delegatedConstructorCall, constructorType, containingClass.symbol.toLookupTag()) + if (reference is FirThisReference && reference.boundSymbol == null) { resolvedCall.dispatchReceiver.typeRef.coneTypeSafe()?.lookupTag?.toSymbol(session)?.let { reference.replaceBoundSymbol(it)