[K2] Avoid field inlining during FIR2IR phase

Before const inlining for fields, we actually want to remember a given
field in `InlineConstTracker`. We are doing it already in const
evaluation. So we just need to ignore const inlining in
`CallAndReferenceGenerator` and delegate it to const evaluation.

#KT-60737
This commit is contained in:
Ivan Kylchik
2023-08-25 11:41:50 +02:00
committed by Space Team
parent 9dd4241a70
commit 6048d52a97
2 changed files with 30 additions and 19 deletions
@@ -477,19 +477,11 @@ class CallAndReferenceGenerator(
}
}
is IrFieldSymbol -> if (visitor.annotationMode) {
val resolvedSymbol = calleeReference.toResolvedCallableSymbol() ?: error("should have resolvedSymbol")
val returnType = resolvedSymbol.resolvedReturnTypeRef.toIrType()
val firConstExpression = (resolvedSymbol.fir as FirVariable).initializer as? FirConstExpression<*>
?: error("should be FirConstExpression")
firConstExpression.toIrConst(returnType)
} else {
IrGetFieldImpl(
startOffset, endOffset, symbol, irType,
origin = IrStatementOrigin.GET_PROPERTY.takeIf { calleeReference !is FirDelegateFieldReference },
is IrFieldSymbol -> IrGetFieldImpl(
startOffset, endOffset, symbol, irType,
origin = IrStatementOrigin.GET_PROPERTY.takeIf { calleeReference !is FirDelegateFieldReference },
superQualifierSymbol = dispatchReceiver?.superQualifierSymbol()
)
}
)
is IrValueSymbol -> {
val variable = calleeReference.toResolvedVariableSymbol()!!.fir
@@ -27,6 +27,9 @@ import org.jetbrains.kotlin.ir.util.classId
import org.jetbrains.kotlin.ir.util.dump
import org.jetbrains.kotlin.ir.util.parentAsClass
import org.jetbrains.kotlin.ir.visitors.IrElementTransformer
import org.jetbrains.kotlin.ir.visitors.IrElementVisitorVoid
import org.jetbrains.kotlin.ir.visitors.acceptChildrenVoid
import org.jetbrains.kotlin.ir.visitors.acceptVoid
fun IrFile.transformConst(
interpreter: IrInterpreter,
@@ -146,17 +149,33 @@ internal abstract class IrConstTransformer(
)
if (result is IrConst<*>) {
val field = when (this) {
is IrGetField -> this.symbol.owner
is IrCall -> this.symbol.owner.property?.backingField
else -> null
}
if (field != null) inlineConstTracker?.reportOnIr(irFile, field, result)
reportInlinedJavaConst(result)
}
return if (failAsError) result.reportIfError(this) else result.warningIfError(this)
}
private fun IrExpression.reportInlinedJavaConst(result: IrConst<*>) {
this.acceptVoid(object : IrElementVisitorVoid {
override fun visitElement(element: IrElement) {
element.acceptChildrenVoid(this)
}
private fun report(field: IrField) {
inlineConstTracker?.reportOnIr(irFile, field, result)
}
override fun visitGetField(expression: IrGetField) {
report(expression.symbol.owner)
super.visitGetField(expression)
}
override fun visitCall(expression: IrCall) {
expression.symbol.owner.property?.backingField?.let { backingField -> report(backingField) }
super.visitCall(expression)
}
})
}
}
fun InlineConstTracker.reportOnIr(irFile: IrFile, field: IrField, value: IrConst<*>) {