[FIR2IR] Unwrap call-site substitution overrides

Generating IR declarations for use-site substitution overrides leads
to IR that is different from K1 as well as problems in signature
generation which relies on mangling. Use-site substitutions can contain
references to type parameters from the call-site which aren't handled
in mangling.

#KT-57022 Fixed
This commit is contained in:
Kirill Rakhman
2023-06-07 16:16:36 +02:00
committed by Space Team
parent bcdd85758e
commit 86836e69e9
10 changed files with 248 additions and 121 deletions
@@ -173,17 +173,24 @@ fun FirReference.toSymbolForCall(
explicitReceiver: FirExpression?,
preferGetter: Boolean = true,
isDelegate: Boolean = false,
isReference: Boolean = false
isReference: Boolean = false,
): IrSymbol? {
return when (this) {
is FirResolvedNamedReference ->
resolvedSymbol.toSymbolForCall(
is FirResolvedNamedReference -> {
var symbol = resolvedSymbol
if (symbol is FirCallableSymbol<*> && symbol.origin == FirDeclarationOrigin.SubstitutionOverride.CallSite) {
symbol = symbol.fir.unwrapUseSiteSubstitutionOverrides<FirCallableDeclaration>().symbol
}
symbol.toSymbolForCall(
dispatchReceiver,
preferGetter,
explicitReceiver,
isDelegate,
isReference
)
}
is FirThisReference -> {
when (val boundSymbol = boundSymbol) {
@@ -67,11 +67,11 @@ private object IsNewPlaceForBodyGeneration : FirDeclarationDataKey()
var FirRegularClass.isNewPlaceForBodyGeneration: Boolean? by FirDeclarationDataRegistry.data(IsNewPlaceForBodyGeneration)
val FirCallableDeclaration.isIntersectionOverride: Boolean get() = origin == FirDeclarationOrigin.IntersectionOverride
val FirCallableDeclaration.isSubstitutionOverride: Boolean get() = origin == FirDeclarationOrigin.SubstitutionOverride
val FirCallableDeclaration.isSubstitutionOverride: Boolean get() = origin is FirDeclarationOrigin.SubstitutionOverride
val FirCallableDeclaration.isSubstitutionOrIntersectionOverride: Boolean get() = isSubstitutionOverride || isIntersectionOverride
val FirCallableSymbol<*>.isIntersectionOverride: Boolean get() = origin == FirDeclarationOrigin.IntersectionOverride
val FirCallableSymbol<*>.isSubstitutionOverride: Boolean get() = origin == FirDeclarationOrigin.SubstitutionOverride
val FirCallableSymbol<*>.isSubstitutionOverride: Boolean get() = origin is FirDeclarationOrigin.SubstitutionOverride
val FirCallableSymbol<*>.isSubstitutionOrIntersectionOverride: Boolean get() = isSubstitutionOverride || isIntersectionOverride
inline val <reified D : FirCallableDeclaration> D.originalForSubstitutionOverride: D?
@@ -132,6 +132,16 @@ inline fun <reified D : FirCallableDeclaration> D.unwrapSubstitutionOverrides():
} while (true)
}
inline fun <reified D : FirCallableDeclaration> D.unwrapUseSiteSubstitutionOverrides(): D {
var current = this
do {
if (current.origin != FirDeclarationOrigin.SubstitutionOverride.CallSite) return current
val next = current.originalForSubstitutionOverride ?: return current
current = next
} while (true)
}
inline fun <reified S : FirCallableSymbol<*>> S.unwrapFakeOverrides(): S = fir.unwrapFakeOverrides().symbol as S
inline fun <reified S : FirCallableSymbol<*>> S.unwrapSubstitutionOverrides(): S = fir.unwrapSubstitutionOverrides().symbol as S