[JVM IR] KTIJ-24335 Fix stub generation of deduplicated built-ins

- Some built-in symbols like `OptIn` haven't been created yet by the
  time `irBuiltIns` is bound to `SymbolTableWithBuiltInsDeduplication`.
  This caused an issue where `DeclarationStubGenerator` would get the
  built-in symbol from `referenceClass`, but still stub for the original
  duplicate `descriptor` and its associated own symbol. Because
  `generateClassStub` would check `referenceClass.isBound` for the
  built-in symbol, `isBound` was never checked for the duplicate symbol
  and thus a "symbol already bound" exception occurred if
  `generateClassStub` was invoked twice for a duplicate `descriptor`.
- The solution takes the descriptor from the `IrClassSymbol` returned
  by `referenceClass`.
This commit is contained in:
Marco Pennekamp
2023-01-20 14:05:45 +01:00
committed by Space Team
parent f11ea92601
commit d1df6391db
2 changed files with 36 additions and 21 deletions
@@ -31,8 +31,8 @@ class SymbolTableWithBuiltInsDeduplication(
irFactory: IrFactory,
) : SymbolTable(signaturer, irFactory) {
/**
* As long as [IrBuiltIns] aren't bound, the symbol table will operate like [SymbolTable], as it must be assumed that built-ins are
* still being created.
* As long as [IrBuiltIns] aren't bound, the symbol table will operate like [SymbolTable], as the initialization of built-ins requires
* a symbol table.
*/
private var irBuiltIns: IrBuiltInsOverDescriptors? = null
@@ -44,6 +44,14 @@ class SymbolTableWithBuiltInsDeduplication(
}
}
/**
* Gets or creates the [IrClassSymbol] for [descriptor], or for the built-in descriptor with the same name if [descriptor] is a
* duplicate built-in.
*
* Note that not all built-in symbols may have been bound or created by the time [irBuiltIns] has been bound. However, [referenceClass]
* will create a symbol in such a case (via `super.referenceClass`) and [org.jetbrains.kotlin.ir.util.DeclarationStubGenerator] will
* create a stub for the symbol if [referenceClass] was invoked from the stub generator.
*/
@ObsoleteDescriptorBasedAPI
override fun referenceClass(descriptor: ClassDescriptor): IrClassSymbol {
val irBuiltIns = this.irBuiltIns ?: return super.referenceClass(descriptor)