From 6c6cf9977b829b00b4f5b46044a06c364ca794e2 Mon Sep 17 00:00:00 2001 From: Yan Zhulanow Date: Tue, 25 Jul 2023 20:25:38 +0900 Subject: [PATCH] [fir2ir] Disable resolve contract check in FIR/IR builtins In the compiler, 'FirLazyDeclarationResolver' assumes 'lazyResolveToPhase()' appear only during code analysis. So there is a check that requires calls to be wrapped with 'startResolvingPhase()' and 'finishResolvingPhase()'. Checkers and backend are run on fully analyzed code, so there is no need in calling 'lazyResolveToPhase()' in the first place. In the IDE, however, it's impossible to analyze all code in a project before running the backend. Generally, it's not a problem as files that are explicitly passed to the backend go through all FIR phases. 'IrBuiltInsOverFir', though, perform symbol lookups, so unresolved-yet declarations might appear. --- .../kotlin/fir/backend/IrBuiltInsOverFir.kt | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/IrBuiltInsOverFir.kt b/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/IrBuiltInsOverFir.kt index ca1930d1354..39d22683a5b 100644 --- a/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/IrBuiltInsOverFir.kt +++ b/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/IrBuiltInsOverFir.kt @@ -17,7 +17,9 @@ import org.jetbrains.kotlin.descriptors.Modality import org.jetbrains.kotlin.fir.declarations.FirResolvePhase import org.jetbrains.kotlin.fir.descriptors.FirModuleDescriptor import org.jetbrains.kotlin.fir.resolve.providers.symbolProvider +import org.jetbrains.kotlin.fir.symbols.FirBasedSymbol import org.jetbrains.kotlin.fir.symbols.impl.FirClassSymbol +import org.jetbrains.kotlin.fir.symbols.lazyDeclarationResolver import org.jetbrains.kotlin.fir.symbols.lazyResolveToPhase import org.jetbrains.kotlin.ir.BuiltInOperatorNames import org.jetbrains.kotlin.ir.IrBuiltIns @@ -735,7 +737,7 @@ class IrBuiltInsOverFir( private fun referenceClassByClassId(classId: ClassId): IrClassSymbol? { val firClassSymbol = components.session.symbolProvider.getClassLikeSymbolByClassId(classId) as? FirClassSymbol ?: return null - firClassSymbol.lazyResolveToPhase(FirResolvePhase.STATUS) + firClassSymbol.lazyResolveToPhaseWithoutContractCheck(FirResolvePhase.STATUS) return components.classifierStorage.getIrClassSymbol(firClassSymbol) } @@ -1200,13 +1202,23 @@ class IrBuiltInsOverFir( private fun findFunctions(packageName: FqName, name: Name): List { return components.session.symbolProvider.getTopLevelFunctionSymbols(packageName, name) - .onEach { it.lazyResolveToPhase(FirResolvePhase.STATUS) } + .onEach { it.lazyResolveToPhaseWithoutContractCheck(FirResolvePhase.STATUS) } .mapNotNull { components.declarationStorage.getIrFunctionSymbol(it) as? IrSimpleFunctionSymbol } } private fun findProperties(packageName: FqName, name: Name): List { return components.session.symbolProvider.getTopLevelPropertySymbols(packageName, name) - .onEach { it.lazyResolveToPhase(FirResolvePhase.STATUS) } + .onEach { it.lazyResolveToPhaseWithoutContractCheck(FirResolvePhase.STATUS) } .mapNotNull { components.declarationStorage.getIrPropertySymbol(it) as? IrPropertySymbol } } + + private fun FirBasedSymbol<*>.lazyResolveToPhaseWithoutContractCheck(toPhase: FirResolvePhase) { + val session = moduleData.session + + // In the compiler, the declaration should have been already resolved. + // In the IDE, the contract check is not active. + session.lazyDeclarationResolver.disableLazyResolveContractChecksInside { + lazyResolveToPhase(toPhase) + } + } }