Make `name` immutable
diff --git a/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/lower/inline/FunctionInlining.kt b/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/lower/inline/FunctionInlining.kt
index 19609b6..b847839 100644
--- a/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/lower/inline/FunctionInlining.kt
+++ b/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/lower/inline/FunctionInlining.kt
@@ -22,6 +22,7 @@
 import org.jetbrains.kotlin.ir.IrStatement
 import org.jetbrains.kotlin.ir.UNDEFINED_OFFSET
 import org.jetbrains.kotlin.ir.builders.declarations.buildFun
+import org.jetbrains.kotlin.ir.builders.declarations.withName
 import org.jetbrains.kotlin.ir.builders.irReturn
 import org.jetbrains.kotlin.ir.declarations.*
 import org.jetbrains.kotlin.ir.expressions.*
@@ -877,7 +878,7 @@
             )
 
             if (alwaysCreateTemporaryVariablesForArguments) {
-                variable.name = Name.identifier(parameter.name.asStringStripSpecialMarkers())
+                return variable.withName(Name.identifier(parameter.name.asStringStripSpecialMarkers()))
             }
 
             return variable
diff --git a/compiler/ir/backend.jvm/lower/src/org/jetbrains/kotlin/backend/jvm/lower/FakeLocalVariablesForIrInlinerLowering.kt b/compiler/ir/backend.jvm/lower/src/org/jetbrains/kotlin/backend/jvm/lower/FakeLocalVariablesForIrInlinerLowering.kt
index a04ac07..9b0467b 100644
--- a/compiler/ir/backend.jvm/lower/src/org/jetbrains/kotlin/backend/jvm/lower/FakeLocalVariablesForIrInlinerLowering.kt
+++ b/compiler/ir/backend.jvm/lower/src/org/jetbrains/kotlin/backend/jvm/lower/FakeLocalVariablesForIrInlinerLowering.kt
@@ -8,6 +8,8 @@
 import org.jetbrains.kotlin.backend.common.FileLoweringPass
 import org.jetbrains.kotlin.backend.common.ir.*
 import org.jetbrains.kotlin.backend.common.lower.createIrBuilder
+import org.jetbrains.kotlin.backend.common.lower.inline.INLINED_FUNCTION_ARGUMENTS
+import org.jetbrains.kotlin.backend.common.lower.inline.INLINED_FUNCTION_DEFAULT_ARGUMENTS
 import org.jetbrains.kotlin.backend.common.phaser.makeIrFilePhase
 import org.jetbrains.kotlin.backend.jvm.JvmBackendContext
 import org.jetbrains.kotlin.backend.jvm.irInlinerIsEnabled
@@ -17,17 +19,16 @@
 import org.jetbrains.kotlin.ir.IrElement
 import org.jetbrains.kotlin.ir.IrStatement
 import org.jetbrains.kotlin.ir.builders.createTmpVariable
+import org.jetbrains.kotlin.ir.builders.declarations.buildVariable
+import org.jetbrains.kotlin.ir.builders.declarations.withName
 import org.jetbrains.kotlin.ir.builders.irInt
 import org.jetbrains.kotlin.ir.declarations.*
 import org.jetbrains.kotlin.ir.expressions.IrBlock
+import org.jetbrains.kotlin.ir.expressions.IrComposite
+import org.jetbrains.kotlin.ir.expressions.IrExpression
 import org.jetbrains.kotlin.ir.expressions.IrInlinedFunctionBlock
-import org.jetbrains.kotlin.ir.util.inlineDeclaration
-import org.jetbrains.kotlin.ir.util.isFunctionInlining
-import org.jetbrains.kotlin.ir.util.isLambdaInlining
-import org.jetbrains.kotlin.ir.visitors.IrElementVisitor
-import org.jetbrains.kotlin.ir.visitors.IrElementVisitorVoid
-import org.jetbrains.kotlin.ir.visitors.acceptChildrenVoid
-import org.jetbrains.kotlin.ir.visitors.acceptVoid
+import org.jetbrains.kotlin.ir.util.*
+import org.jetbrains.kotlin.ir.visitors.*
 import org.jetbrains.kotlin.load.java.JvmAbi
 import org.jetbrains.kotlin.name.Name
 import org.jetbrains.kotlin.name.SpecialNames
@@ -43,7 +44,7 @@
 )
 
 internal class FakeLocalVariablesForIrInlinerLowering(
-    override val context: JvmBackendContext
+    override val context: JvmBackendContext,
 ) : IrElementVisitorVoid, FakeInliningLocalVariables<IrInlinedFunctionBlock>, FileLoweringPass {
     private val inlinedStack = mutableListOf<IrInlinedFunctionBlock>()
     private var container: IrDeclaration? = null
@@ -102,7 +103,7 @@
     }
 }
 
-private class LocalVariablesProcessor : IrElementVisitor<Unit, LocalVariablesProcessor.Data> {
+private class LocalVariablesProcessor : IrElementTransformer<LocalVariablesProcessor.Data> {
     data class Data(val processingOriginalDeclarations: Boolean)
 
     private val inlinedStack = mutableListOf<IrInlinedFunctionBlock>()
@@ -113,19 +114,15 @@
         inlinedStack.removeLast()
     }
 
-    override fun visitElement(element: IrElement, data: Data) {
-        element.acceptChildren(this, data)
-    }
-
-    override fun visitClass(declaration: IrClass, data: Data) {
+    override fun visitClass(declaration: IrClass, data: Data): IrStatement {
         if (declaration.originalBeforeInline != null) {
             // Don't take into account regenerated classes
             return super.visitClass(declaration, data.copy(processingOriginalDeclarations = false))
         }
-        super.visitClass(declaration, data)
+        return super.visitClass(declaration, data)
     }
 
-    override fun visitBlock(expression: IrBlock, data: Data) {
+    override fun visitBlock(expression: IrBlock, data: Data): IrExpression {
         if (expression !is IrInlinedFunctionBlock) {
             return super.visitBlock(expression, data)
         }
@@ -133,19 +130,20 @@
         if (expression.isLambdaInlining()) {
             val argument = expression.inlinedElement as IrAttributeContainer
             val callee = inlinedStack.extractDeclarationWhereGivenElementWasInlined(argument)
-            if (callee == null || callee != inlinedStack.lastOrNull()) return
+            if (callee == null || callee != inlinedStack.lastOrNull()) return expression
         }
 
-        super.visitBlock(expression, data)
-
-        expression.insertInStackAndProcess {
-            getOriginalStatementsFromInlinedBlock().forEach {
-                it.accept(this@LocalVariablesProcessor, data.copy(processingOriginalDeclarations = true))
+        return super.visitBlock(expression, data).also {
+            expression.insertInStackAndProcess {
+                getOriginalStatementsFromInlinedBlock().forEach {
+                    it.accept(this@LocalVariablesProcessor, data.copy(processingOriginalDeclarations = true))
+                }
             }
         }
     }
 
-    override fun visitVariable(declaration: IrVariable, data: Data) {
+
+    override fun visitVariable(declaration: IrVariable, data: Data): IrStatement {
         if (!data.processingOriginalDeclarations) return super.visitVariable(declaration, data)
 
         val varName = declaration.name.asString()
@@ -157,8 +155,9 @@
             varSuffix.isNotEmpty() && varName == SpecialNames.THIS.asStringStripSpecialMarkers() -> "this_"
             else -> varName
         }
-        declaration.name = Name.identifier(newName + varSuffix)
-        super.visitVariable(declaration, data)
+        val transformed = super.visitVariable(declaration, data)
+        require(transformed is IrVariable) { "Expected IrVariable, but got ${transformed.render()}" }
+        return transformed.withName(Name.identifier(newName + varSuffix))
     }
 }
 
@@ -173,14 +172,16 @@
         }
 
         super.visitBlock(expression)
-        expression.getAdditionalStatementsFromInlinedBlock().forEach {
-            it.processFunctionParameter(expression)
-        }
+        expression.statements
+            .filterIsInstance<IrComposite>()
+            .filter { it.origin == INLINED_FUNCTION_ARGUMENTS || it.origin == INLINED_FUNCTION_DEFAULT_ARGUMENTS }
+            .forEach {
+                it.statements.transformInPlace { statement -> statement.processFunctionParameter(expression) }
+            }
     }
 
-    private fun IrStatement.processFunctionParameter(inlinedBlock: IrInlinedFunctionBlock) {
-        if (this !is IrVariable || !this.isTmpForInline) return
-
+    private fun IrStatement.processFunctionParameter(inlinedBlock: IrInlinedFunctionBlock): IrStatement {
+        if (this !is IrVariable || !this.isTmpForInline) return this
         val varName = this.name.asString().substringAfterLast("_")
         val varNewName = when {
             this.origin == IrDeclarationOrigin.IR_TEMPORARY_VARIABLE_FOR_INLINED_EXTENSION_RECEIVER -> {
@@ -190,7 +191,7 @@
             varName == SpecialNames.THIS.asStringStripSpecialMarkers() -> "this_"
             else -> varName
         }
-        this.name = Name.identifier(varNewName + INLINE_FUN_VAR_SUFFIX)
         this.origin = IrDeclarationOrigin.DEFINED
+        return this.withName(Name.identifier(varNewName + INLINE_FUN_VAR_SUFFIX))
     }
 }
diff --git a/compiler/ir/backend.jvm/lower/src/org/jetbrains/kotlin/backend/jvm/lower/RenameFieldsLowering.kt b/compiler/ir/backend.jvm/lower/src/org/jetbrains/kotlin/backend/jvm/lower/RenameFieldsLowering.kt
index dea11b8..c791041 100644
--- a/compiler/ir/backend.jvm/lower/src/org/jetbrains/kotlin/backend/jvm/lower/RenameFieldsLowering.kt
+++ b/compiler/ir/backend.jvm/lower/src/org/jetbrains/kotlin/backend/jvm/lower/RenameFieldsLowering.kt
@@ -8,8 +8,11 @@
 import org.jetbrains.kotlin.backend.common.ClassLoweringPass
 import org.jetbrains.kotlin.backend.common.CommonBackendContext
 import org.jetbrains.kotlin.backend.common.phaser.makeIrFilePhase
+import org.jetbrains.kotlin.ir.builders.declarations.withName
 import org.jetbrains.kotlin.ir.declarations.IrClass
+import org.jetbrains.kotlin.ir.declarations.IrField
 import org.jetbrains.kotlin.ir.util.fields
+import org.jetbrains.kotlin.ir.util.transformInPlace
 import org.jetbrains.kotlin.name.Name
 
 internal val renameFieldsPhase = makeIrFilePhase<CommonBackendContext>(
@@ -38,13 +41,25 @@
         }
 
         val count = hashMapOf<Name, Int>()
-        for (field in fields) {
+
+        val originalToTransformedField = fields.associateWith { field ->
             val oldName = field.name
             val index = count[oldName] ?: 0
-            if (index != 0 && !field.visibility.isPublicAPI) {
-                field.name = Name.identifier("$oldName$$index")
+            val transformedField = if (index != 0 && !field.visibility.isPublicAPI) {
+                field.withName(Name.identifier("$oldName$$index"))
+            } else {
+                field
             }
             count[oldName] = index + 1
+            transformedField
+        }
+
+        irClass.declarations.transformInPlace {
+            if (it is IrField) {
+                originalToTransformedField[it] ?: it
+            } else {
+                it
+            }
         }
     }
 }
diff --git a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/MemoizedInlineClassReplacements.kt b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/MemoizedInlineClassReplacements.kt
index 18d540e..8f2d973 100644
--- a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/MemoizedInlineClassReplacements.kt
+++ b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/MemoizedInlineClassReplacements.kt
@@ -16,6 +16,7 @@
 import org.jetbrains.kotlin.ir.IrBuiltIns
 import org.jetbrains.kotlin.ir.builders.declarations.addValueParameter
 import org.jetbrains.kotlin.ir.builders.declarations.buildFun
+import org.jetbrains.kotlin.ir.builders.declarations.withName
 import org.jetbrains.kotlin.ir.declarations.*
 import org.jetbrains.kotlin.ir.types.impl.IrSimpleTypeImpl
 import org.jetbrains.kotlin.ir.types.impl.IrStarProjectionImpl
@@ -31,7 +32,7 @@
 class MemoizedInlineClassReplacements(
     private val mangleReturnTypes: Boolean,
     irFactory: IrFactory,
-    context: JvmBackendContext
+    context: JvmBackendContext,
 ) : MemoizedValueClassAbstractReplacements(irFactory, context, LockBasedStorageManager("inline-class-replacements")) {
 
     val originalFunctionForStaticReplacement: MutableMap<IrFunction, IrFunction> = ConcurrentHashMap()
@@ -63,10 +64,11 @@
                 // Mangle all functions in the body of an inline class
                 (it.parent as? IrClass)?.isSingleFieldValueClass == true ->
                     when {
-                        it.isValueClassTypedEquals -> createStaticReplacement(it).also {
-                            it.name = InlineClassDescriptorResolver.SPECIALIZED_EQUALS_NAME
-                            specializedEqualsCache.computeIfAbsent(it.parentAsClass) { it }
-                        }
+                        it.isValueClassTypedEquals -> createStaticReplacement(it)
+                            .withName(InlineClassDescriptorResolver.SPECIALIZED_EQUALS_NAME)
+                            .also {
+                                specializedEqualsCache.computeIfAbsent(it.parentAsClass) { it }
+                            }
 
                         it.isRemoveAtSpecialBuiltinStub() ->
                             null
@@ -218,7 +220,7 @@
         function: IrFunction,
         replacementOrigin: IrDeclarationOrigin,
         noFakeOverride: Boolean = false,
-        body: IrFunction.() -> Unit
+        body: IrFunction.() -> Unit,
     ): IrSimpleFunction {
         val useOldManglingScheme = context.config.useOldManglingSchemeForFunctionsWithInlineClassesInSignatures
         val replacement = buildReplacementInner(function, replacementOrigin, noFakeOverride, useOldManglingScheme, body)
diff --git a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/MemoizedMultiFieldValueClassReplacements.kt b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/MemoizedMultiFieldValueClassReplacements.kt
index 8c9fe3a..2f6e025 100644
--- a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/MemoizedMultiFieldValueClassReplacements.kt
+++ b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/MemoizedMultiFieldValueClassReplacements.kt
@@ -14,6 +14,7 @@
 import org.jetbrains.kotlin.ir.builders.IrBlockBuilder
 import org.jetbrains.kotlin.ir.builders.declarations.addValueParameter
 import org.jetbrains.kotlin.ir.builders.declarations.buildConstructor
+import org.jetbrains.kotlin.ir.builders.declarations.withName
 import org.jetbrains.kotlin.ir.builders.irComposite
 import org.jetbrains.kotlin.ir.builders.irExprBody
 import org.jetbrains.kotlin.ir.builders.irGet
@@ -35,7 +36,7 @@
  */
 class MemoizedMultiFieldValueClassReplacements(
     irFactory: IrFactory,
-    context: JvmBackendContext
+    context: JvmBackendContext,
 ) : MemoizedValueClassAbstractReplacements(irFactory, context, LockBasedStorageManager("multi-field-value-class-replacements")) {
 
     val originalFunctionForStaticReplacement: MutableMap<IrFunction, IrFunction> = ConcurrentHashMap()
@@ -262,9 +263,8 @@
                         function.isMultiFieldValueClassFieldGetter -> null
 
                 (function.parent as? IrClass)?.isMultiFieldValueClass == true -> when {
-                    function.isValueClassTypedEquals -> createStaticReplacement(function).also {
-                        it.name = InlineClassDescriptorResolver.SPECIALIZED_EQUALS_NAME
-                    }
+                    function.isValueClassTypedEquals -> createStaticReplacement(function)
+                        .withName(InlineClassDescriptorResolver.SPECIALIZED_EQUALS_NAME)
 
                     function.isRemoveAtSpecialBuiltinStub() ->
                         null
@@ -394,7 +394,7 @@
         irBuilder: IrBlockBuilder,
         targetFunction: IrFunction,
         sourceFunction: IrFunction,
-        getArgument: (sourceParameter: IrValueParameter, targetParameterType: IrType) -> IrExpression?
+        getArgument: (sourceParameter: IrValueParameter, targetParameterType: IrType) -> IrExpression?,
     ): Map<IrValueParameter, IrExpression?> {
         val targetStructure = bindingNewFunctionToParameterTemplateStructure[targetFunction]
             ?: targetFunction.explicitParameters.map { RegularMapping(it) }
@@ -469,7 +469,7 @@
     @OptIn(ExperimentalStdlibApi::class)
     private fun verifyStructureCompatibility(
         targetStructure: List<RemappedParameter>,
-        sourceStructure: List<RemappedParameter>
+        sourceStructure: List<RemappedParameter>,
     ) {
         for ((targetParameterStructure, sourceParameterStructure) in targetStructure zip sourceStructure) {
             if (targetParameterStructure is MultiFieldValueClassMapping && sourceParameterStructure is MultiFieldValueClassMapping) {
diff --git a/compiler/ir/ir.tree/gen/org/jetbrains/kotlin/ir/declarations/IrDeclarationWithName.kt b/compiler/ir/ir.tree/gen/org/jetbrains/kotlin/ir/declarations/IrDeclarationWithName.kt
index a8c6f7c..1e581a6 100644
--- a/compiler/ir/ir.tree/gen/org/jetbrains/kotlin/ir/declarations/IrDeclarationWithName.kt
+++ b/compiler/ir/ir.tree/gen/org/jetbrains/kotlin/ir/declarations/IrDeclarationWithName.kt
@@ -16,5 +16,5 @@
  * Generated from: [org.jetbrains.kotlin.ir.generator.IrTree.declarationWithName]
  */
 interface IrDeclarationWithName : IrDeclaration {
-    var name: Name
+    val name: Name
 }
diff --git a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/builders/declarations/declarationBuilders.kt b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/builders/declarations/declarationBuilders.kt
index 051712db..c84bc3c 100644
--- a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/builders/declarations/declarationBuilders.kt
+++ b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/builders/declarations/declarationBuilders.kt
@@ -91,7 +91,7 @@
 fun IrClass.addField(
     fieldName: String,
     fieldType: IrType,
-    fieldVisibility: DescriptorVisibility = DescriptorVisibilities.PRIVATE
+    fieldVisibility: DescriptorVisibility = DescriptorVisibilities.PRIVATE,
 ): IrField =
     addField(Name.identifier(fieldName), fieldType, fieldVisibility)
 
@@ -258,7 +258,7 @@
     isInline: Boolean = false,
     origin: IrDeclarationOrigin = IrDeclarationOrigin.DEFINED,
     startOffset: Int = UNDEFINED_OFFSET,
-    endOffset: Int = UNDEFINED_OFFSET
+    endOffset: Int = UNDEFINED_OFFSET,
 ): IrSimpleFunction =
     addFunction {
         this.startOffset = startOffset
@@ -298,7 +298,7 @@
     origin: IrDeclarationOrigin,
     type: IrType,
     startOffset: Int = parent.startOffset,
-    endOffset: Int = parent.endOffset
+    endOffset: Int = parent.endOffset,
 ): IrValueParameter
         where D : IrDeclaration, D : IrDeclarationParent =
     parent.factory.createValueParameter(
@@ -409,6 +409,37 @@
         this.superTypes.add(upperBound)
     }
 
+fun IrSimpleFunction.withName(name: Name) = factory.buildFun {
+    updateFrom(this@withName)
+    this.name = name
+    returnType = this@withName.returnType
+}.apply {
+    parent = this@withName.parent
+    metadata = this@withName.metadata
+    valueParameters = this@withName.valueParameters
+    typeParameters = this@withName.typeParameters
+    dispatchReceiverParameter = this@withName.dispatchReceiverParameter
+    extensionReceiverParameter = this@withName.extensionReceiverParameter
+    contextReceiverParametersCount = this@withName.contextReceiverParametersCount
+    body = this@withName.body
+    overriddenSymbols = this@withName.overriddenSymbols
+    attributeOwnerId = this@withName.attributeOwnerId
+    originalBeforeInline = this@withName.originalBeforeInline
+    correspondingPropertySymbol = this@withName.correspondingPropertySymbol
+}
+
+fun IrVariable.withName(name: Name) =
+    buildVariable(parent, startOffset, endOffset, origin, name, type, isVar, isConst, isLateinit).also { it.initializer = initializer }
+
+fun IrField.withName(name: Name) = factory.buildField {
+    this.name = name
+    updateFrom(this@withName)
+}.apply {
+    parent = this@withName.parent
+    initializer = this@withName.initializer
+    correspondingPropertySymbol = this@withName.correspondingPropertySymbol
+}
+
 fun buildVariable(
     parent: IrDeclarationParent?,
     startOffset: Int,
diff --git a/compiler/ir/ir.tree/tree-generator/src/org/jetbrains/kotlin/ir/generator/IrTree.kt b/compiler/ir/ir.tree/tree-generator/src/org/jetbrains/kotlin/ir/generator/IrTree.kt
index 8418b42..5297007 100644
--- a/compiler/ir/ir.tree/tree-generator/src/org/jetbrains/kotlin/ir/generator/IrTree.kt
+++ b/compiler/ir/ir.tree/tree-generator/src/org/jetbrains/kotlin/ir/generator/IrTree.kt
@@ -125,7 +125,7 @@
     val declarationWithName: ElementConfig by element(Declaration) {
         parent(declaration)
 
-        +field("name", type<Name>())
+        +field("name", type<Name>(), mutable = false)
     }
     val possiblyExternalDeclaration: ElementConfig by element(Declaration) {
         parent(declarationWithName)