[FIR2IR] Don't manually create IR for IntrinsicConstEvaluation if not needed
There is no need to create IR class for `@IntrinsicConstEvaluation` manually if it is present in sources ^KT-65415 Fixed
This commit is contained in:
committed by
Space Team
parent
7a383373b0
commit
555cf56d6d
+3
-3
@@ -513,7 +513,7 @@ class Fir2IrDeclarationStorage(
|
||||
predefinedOrigin: IrDeclarationOrigin? = null,
|
||||
isLocal: Boolean = false,
|
||||
): IrConstructor {
|
||||
val symbol = getIrConstructorSymbol(constructor.symbol, isLocal)
|
||||
val symbol = getIrConstructorSymbol(constructor.symbol, potentiallyExternal = !isLocal)
|
||||
return callablesGenerator.createIrConstructor(
|
||||
constructor,
|
||||
irParent(),
|
||||
@@ -527,13 +527,13 @@ class Fir2IrDeclarationStorage(
|
||||
constructorCache[constructor] = irConstructorSymbol
|
||||
}
|
||||
|
||||
fun getIrConstructorSymbol(firConstructorSymbol: FirConstructorSymbol, isLocal: Boolean = false): IrConstructorSymbol {
|
||||
fun getIrConstructorSymbol(firConstructorSymbol: FirConstructorSymbol, potentiallyExternal: Boolean = true): IrConstructorSymbol {
|
||||
val constructor = firConstructorSymbol.fir
|
||||
getCachedIrConstructorSymbol(constructor)?.let { return it }
|
||||
|
||||
// caching of created constructor is not called here, because `callablesGenerator` calls `cacheIrConstructor` by itself
|
||||
val symbol = IrConstructorSymbolImpl()
|
||||
if (!isLocal) {
|
||||
if (potentiallyExternal) {
|
||||
val irParent = findIrParent(constructor, fakeOverrideOwnerLookupTag = null)
|
||||
val isIntrinsicConstEvaluation =
|
||||
constructor.returnTypeRef.coneType.classId == StandardClassIds.Annotations.IntrinsicConstEvaluation
|
||||
|
||||
@@ -51,7 +51,7 @@ class Fir2IrTypeConverter(
|
||||
StandardClassIds.Double to irBuiltIns.doubleClass,
|
||||
StandardClassIds.Char to irBuiltIns.charClass,
|
||||
StandardClassIds.Array to irBuiltIns.arrayClass,
|
||||
StandardClassIds.Annotations.IntrinsicConstEvaluation to irBuiltIns.intrinsicConst
|
||||
StandardClassIds.Annotations.IntrinsicConstEvaluation to irBuiltIns.intrinsicConstSymbol
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
@@ -11,7 +11,9 @@ import org.jetbrains.kotlin.builtins.UnsignedType
|
||||
import org.jetbrains.kotlin.config.LanguageVersionSettings
|
||||
import org.jetbrains.kotlin.descriptors.Modality
|
||||
import org.jetbrains.kotlin.fir.FirSession
|
||||
import org.jetbrains.kotlin.fir.declarations.FirDeclarationOrigin
|
||||
import org.jetbrains.kotlin.fir.declarations.FirResolvePhase
|
||||
import org.jetbrains.kotlin.fir.declarations.constructors
|
||||
import org.jetbrains.kotlin.fir.descriptors.FirModuleDescriptor
|
||||
import org.jetbrains.kotlin.fir.resolve.providers.FirSymbolProvider
|
||||
import org.jetbrains.kotlin.fir.resolve.providers.symbolProvider
|
||||
@@ -125,40 +127,74 @@ class IrBuiltInsOverFir(
|
||||
override val stringClass: IrClassSymbol by lazy { loadClass(StandardClassIds.String) }
|
||||
override val stringType: IrType get() = stringClass.defaultTypeWithoutArguments
|
||||
|
||||
internal val intrinsicConst by lazy {
|
||||
/*
|
||||
* Old versions of stdlib may not contain @IntrinsicConstEvaluation (AV < 1.7), so in this case we should create annotation class manually
|
||||
*
|
||||
* Ideally, we should try to load it from FIR at first, but the thing is that this annotation is used for some generated builtin functions
|
||||
* (see init section below), so if Fir2IrLazyClass for this annotation is created, it will call for `components.fakeOverrideGenerator`,
|
||||
* which is not initialized by this moment
|
||||
* As a possible way to fix it we can move `init` section of builtins into the separate function for late initialization and call
|
||||
* for it after Fir2IrComponentsStorage is fully initialized
|
||||
*/
|
||||
val irClass = createIntrinsicConstEvaluationClass()
|
||||
private class IntrinsicConstAnnotation(val classSymbol: IrClassSymbol, val annotationCall: IrConstructorCall)
|
||||
|
||||
private val intrinsicConst: IntrinsicConstAnnotation by lazy {
|
||||
val firClassSymbol = session.symbolProvider.getClassLikeSymbolByClassId(
|
||||
StandardClassIds.Annotations.IntrinsicConstEvaluation
|
||||
) as FirRegularClassSymbol?
|
||||
|
||||
if (firClassSymbol != null) {
|
||||
/*
|
||||
* If @IntrinsicConstEvaluation is present in dependencies, we should manually cache relation between FIR and IR class
|
||||
* Without it classifier storage may create another IR class for @IntrinsicConstEvaluation, if it will be referenced
|
||||
* somewhere in the code
|
||||
*/
|
||||
@OptIn(LeakedDeclarationCaches::class)
|
||||
components.classifierStorage.cacheIrClass(firClassSymbol.fir, irClass)
|
||||
val (classSymbol, constructorSymbol) = when {
|
||||
firClassSymbol?.origin == FirDeclarationOrigin.Source -> {
|
||||
/**
|
||||
* If @IntrinsicConstEvaluation is present in sources, then we are compiling stdlib and there is no need to create IrClass
|
||||
* for it manually, as we will create it from the source FIR class
|
||||
*/
|
||||
val irClassSymbol = components.classifierStorage.getIrClassSymbol(firClassSymbol)
|
||||
val firConstructor = firClassSymbol.fir.constructors(session).single()
|
||||
val irConstructorSymbol = components.declarationStorage.getIrConstructorSymbol(firConstructor, potentiallyExternal = false)
|
||||
irClassSymbol to irConstructorSymbol
|
||||
}
|
||||
|
||||
else -> {
|
||||
/*
|
||||
* Old versions of stdlib may not contain @IntrinsicConstEvaluation (AV < 1.7), so in this case we should create annotation class manually
|
||||
*
|
||||
* Ideally, we should try to load it from FIR at first, but the thing is that this annotation is used for some generated builtin functions
|
||||
* (see init section below), so if Fir2IrLazyClass for this annotation is created, it will call for `components.fakeOverrideGenerator`,
|
||||
* which is not initialized by this moment
|
||||
* As a possible way to fix it we can move `init` section of builtins into the separate function for late initialization and call
|
||||
* for it after Fir2IrComponentsStorage is fully initialized
|
||||
*/
|
||||
val irClass = createIntrinsicConstEvaluationClass()
|
||||
if (firClassSymbol != null) {
|
||||
/*
|
||||
* If @IntrinsicConstEvaluation is present in dependencies, we should manually cache relation between FIR and IR class
|
||||
* Without it classifier storage may create another IR class for @IntrinsicConstEvaluation, if it will be referenced
|
||||
* somewhere in the code
|
||||
*/
|
||||
@OptIn(LeakedDeclarationCaches::class)
|
||||
components.classifierStorage.cacheIrClass(firClassSymbol.fir, irClass)
|
||||
}
|
||||
// class for intrinsicConst is created manually and it definitely is not a lazy class
|
||||
@OptIn(UnsafeDuringIrConstructionAPI::class)
|
||||
val constructor = irClass.constructors.single()
|
||||
irClass.symbol to constructor.symbol
|
||||
}
|
||||
}
|
||||
|
||||
irClass.symbol
|
||||
val annotationCall = IrConstructorCallImpl(
|
||||
startOffset = UNDEFINED_OFFSET,
|
||||
endOffset = UNDEFINED_OFFSET,
|
||||
type = IrSimpleTypeImpl(
|
||||
classifier = classSymbol,
|
||||
nullability = SimpleTypeNullability.DEFINITELY_NOT_NULL,
|
||||
arguments = emptyList(),
|
||||
annotations = emptyList()
|
||||
),
|
||||
constructorSymbol,
|
||||
typeArgumentsCount = 0,
|
||||
constructorTypeArgumentsCount = 0,
|
||||
valueArgumentsCount = 0,
|
||||
)
|
||||
|
||||
IntrinsicConstAnnotation(classSymbol, annotationCall)
|
||||
}
|
||||
|
||||
private val intrinsicConstAnnotation: IrConstructorCall by lazy {
|
||||
// class for intrinsicConst is created manually and it definitely is not a lazy class
|
||||
@OptIn(UnsafeDuringIrConstructionAPI::class)
|
||||
val constructor = intrinsicConst.constructors.single()
|
||||
IrConstructorCallImpl.Companion.fromSymbolOwner(intrinsicConst.defaultType, constructor)
|
||||
}
|
||||
internal val intrinsicConstSymbol: IrClassSymbol
|
||||
get() = intrinsicConst.classSymbol
|
||||
private val intrinsicConstAnnotation: IrConstructorCall
|
||||
get() = intrinsicConst.annotationCall
|
||||
|
||||
override val iteratorClass: IrClassSymbol by lazy { loadClass(StandardClassIds.Iterator) }
|
||||
override val arrayClass: IrClassSymbol by lazy { loadClass(StandardClassIds.Array) }
|
||||
|
||||
+1
-1
@@ -1,5 +1,5 @@
|
||||
// IGNORE_BACKEND_K1: JS_IR, JS_IR_ES6, WASM, NATIVE
|
||||
// IGNORE_BACKEND_K2: ANY
|
||||
// IGNORE_BACKEND_K2: JS_IR, JS_IR_ES6, WASM, NATIVE
|
||||
// non-jvm backends are ignored because of KT-66432
|
||||
// ISSUE: KT-65415, KT-66432
|
||||
|
||||
|
||||
Reference in New Issue
Block a user