[FIR] fix resolve contract violation from scopes

We cannot call lazy resolve to STATUS phase from scopes as scopes may be accessed on a STATUS phase or earlier

^KT-54890
^KTIJ-23587 fixed
This commit is contained in:
Ilya Kirillov
2022-12-28 09:59:12 +01:00
committed by teamcity
parent 0d1e7e83b5
commit 1bbcae5ed2
311 changed files with 108 additions and 347 deletions
@@ -176,7 +176,12 @@ private fun processConstructors(
is FirTypeAliasSymbol -> {
matchedSymbol.lazyResolveToPhase(FirResolvePhase.TYPES)
val type = matchedSymbol.fir.expandedTypeRef.coneTypeUnsafe<ConeClassLikeType>().fullyExpandedType(session)
val basicScope = type.scope(session, bodyResolveComponents.scopeSession, FakeOverrideTypeCalculator.DoNothing)
val basicScope = type.scope(
session,
bodyResolveComponents.scopeSession,
FakeOverrideTypeCalculator.DoNothing,
requiredPhase = FirResolvePhase.STATUS
)
val outerType = bodyResolveComponents.outerClassManager.outerType(type)
@@ -9,6 +9,7 @@ import org.jetbrains.kotlin.descriptors.ClassKind
import org.jetbrains.kotlin.descriptors.Modality
import org.jetbrains.kotlin.descriptors.isClass
import org.jetbrains.kotlin.fir.declarations.FirCallableDeclaration
import org.jetbrains.kotlin.fir.declarations.FirResolvePhase
import org.jetbrains.kotlin.fir.declarations.FirVariable
import org.jetbrains.kotlin.fir.declarations.utils.modality
import org.jetbrains.kotlin.fir.dispatchReceiverClassLookupTagOrNull
@@ -128,16 +129,14 @@ private inline fun BodyResolveComponents.resolveSupertypesByMembers(
private fun BodyResolveComponents.getFunctionMembers(type: ConeKotlinType, name: Name): Collection<FirCallableDeclaration> =
buildList {
type.scope(session, scopeSession, FakeOverrideTypeCalculator.DoNothing)?.processFunctionsByName(name) {
add(it.fir)
}
type.scope(session, scopeSession, FakeOverrideTypeCalculator.DoNothing, requiredPhase = FirResolvePhase.STATUS)
?.processFunctionsByName(name) { add(it.fir) }
}
private fun BodyResolveComponents.getPropertyMembers(type: ConeKotlinType, name: Name): Collection<FirCallableDeclaration> =
buildList {
type.scope(session, scopeSession, FakeOverrideTypeCalculator.DoNothing)?.processPropertiesByName(name) {
addIfNotNull(it.fir as? FirVariable)
}
type.scope(session, scopeSession, FakeOverrideTypeCalculator.DoNothing, requiredPhase = FirResolvePhase.STATUS)
?.processPropertiesByName(name) { addIfNotNull(it.fir as? FirVariable) }
}
@@ -6,10 +6,7 @@
package org.jetbrains.kotlin.fir.resolve.calls.tower
import org.jetbrains.kotlin.fir.*
import org.jetbrains.kotlin.fir.declarations.ContextReceiverGroup
import org.jetbrains.kotlin.fir.declarations.FirCallableDeclaration
import org.jetbrains.kotlin.fir.declarations.FirConstructor
import org.jetbrains.kotlin.fir.declarations.getAnnotationByClassId
import org.jetbrains.kotlin.fir.declarations.*
import org.jetbrains.kotlin.fir.declarations.utils.isInner
import org.jetbrains.kotlin.fir.declarations.utils.isStatic
import org.jetbrains.kotlin.fir.expressions.FirExpression
@@ -92,7 +89,12 @@ class MemberScopeTowerLevel(
?.takeIf { it.isStable }
?.originalExpression?.typeRef
?.coneType
?.scope(session, scopeSession, bodyResolveComponents.returnTypeCalculator.fakeOverrideTypeCalculator)
?.scope(
session,
scopeSession,
bodyResolveComponents.returnTypeCalculator.fakeOverrideTypeCalculator,
requiredPhase = FirResolvePhase.STATUS
)
if (scopeWithoutSmartcast == null) {
consumeCandidates(output, candidates)
} else {
@@ -123,7 +125,12 @@ class MemberScopeTowerLevel(
if (dispatchReceiverType.isRaw()) {
typeForSyntheticScope = dispatchReceiverType.convertToNonRawVersion()
useSiteForSyntheticScope =
typeForSyntheticScope.scope(session, scopeSession, FakeOverrideTypeCalculator.DoNothing)
typeForSyntheticScope.scope(
session,
scopeSession,
FakeOverrideTypeCalculator.DoNothing,
requiredPhase = FirResolvePhase.STATUS
)
?: error("No scope for flexible type scope, while it's not null for $dispatchReceiverType")
} else {
typeForSyntheticScope = dispatchReceiverType
@@ -9,6 +9,7 @@ import org.jetbrains.kotlin.KtFakeSourceElementKind
import org.jetbrains.kotlin.fakeElement
import org.jetbrains.kotlin.fir.FirElement
import org.jetbrains.kotlin.fir.FirSession
import org.jetbrains.kotlin.fir.declarations.FirResolvePhase
import org.jetbrains.kotlin.fir.expressions.FirConstExpression
import org.jetbrains.kotlin.fir.expressions.FirExpression
import org.jetbrains.kotlin.fir.expressions.FirIntegerLiteralOperatorCall
@@ -50,7 +51,8 @@ class IntegerLiteralAndOperatorApproximationTransformer(
private val toULongSymbol by lazy { findConversionFunction(session.builtinTypes.uIntType, TO_U_LONG)}
private fun findConversionFunction(receiverType: FirImplicitBuiltinTypeRef, name: Name): FirNamedFunctionSymbol {
return receiverType.type.scope(session, scopeSession, FakeOverrideTypeCalculator.DoNothing)!!.getFunctions(name).single()
return receiverType.type.scope(session, scopeSession, FakeOverrideTypeCalculator.DoNothing, requiredPhase = FirResolvePhase.STATUS)!!
.getFunctions(name).single()
}
override fun <E : FirElement> transformElement(element: E, data: ConeKotlinType?): E {
@@ -633,7 +633,8 @@ object FirExpectActualResolver {
scopeSession: ScopeSession,
session: FirSession = moduleData.session
): Collection<FirBasedSymbol<*>> {
val scope = defaultType().scope(useSiteSession = session, scopeSession, FakeOverrideTypeCalculator.DoNothing)
val scope = defaultType()
.scope(useSiteSession = session, scopeSession, FakeOverrideTypeCalculator.DoNothing, requiredPhase = FirResolvePhase.STATUS)
?: return emptyList()
return mutableListOf<FirBasedSymbol<*>>().apply {
for (name in scope.getCallableNames()) {
@@ -660,7 +661,13 @@ object FirExpectActualResolver {
}
private fun FirClassSymbol<*>.getMembers(name: Name, scopeSession: ScopeSession): Collection<FirCallableSymbol<*>> {
val scope = defaultType().scope(useSiteSession = moduleData.session, scopeSession, FakeOverrideTypeCalculator.DoNothing)
val scope = defaultType()
.scope(
useSiteSession = moduleData.session,
scopeSession,
FakeOverrideTypeCalculator.DoNothing,
requiredPhase = FirResolvePhase.STATUS
)
?: return emptyList()
return mutableListOf<FirCallableSymbol<*>>().apply {
scope.getMembersTo(this, name)