[IR] Optimize IrTransformer

Prevent unneeded casts and property reassignments
diff --git a/compiler/ir/ir.tree/gen/org/jetbrains/kotlin/ir/declarations/IrAnonymousInitializer.kt b/compiler/ir/ir.tree/gen/org/jetbrains/kotlin/ir/declarations/IrAnonymousInitializer.kt
index 6df1669..d0d1899 100644
--- a/compiler/ir/ir.tree/gen/org/jetbrains/kotlin/ir/declarations/IrAnonymousInitializer.kt
+++ b/compiler/ir/ir.tree/gen/org/jetbrains/kotlin/ir/declarations/IrAnonymousInitializer.kt
@@ -38,6 +38,11 @@
     }
 
     override fun <D> transformChildren(transformer: IrElementTransformer<D>, data: D) {
-        body = body.transform(transformer, data) as IrBlockBody
+        val body = this.body
+        body.transform(transformer, data).let { new ->
+            if (new !== body) {
+                this.body = new as IrBlockBody
+            }
+        }
     }
 }
diff --git a/compiler/ir/ir.tree/gen/org/jetbrains/kotlin/ir/declarations/IrClass.kt b/compiler/ir/ir.tree/gen/org/jetbrains/kotlin/ir/declarations/IrClass.kt
index 467d8b5..6f433ea 100644
--- a/compiler/ir/ir.tree/gen/org/jetbrains/kotlin/ir/declarations/IrClass.kt
+++ b/compiler/ir/ir.tree/gen/org/jetbrains/kotlin/ir/declarations/IrClass.kt
@@ -80,8 +80,18 @@
     }
 
     override fun <D> transformChildren(transformer: IrElementTransformer<D>, data: D) {
-        typeParameters = typeParameters.transformIfNeeded(transformer, data)
+        val typeParameters = this.typeParameters
+        typeParameters.transformIfNeeded(transformer, data).let { new ->
+            if (new !== typeParameters) {
+                this.typeParameters = new
+            }
+        }
         declarations.transformInPlace(transformer, data)
-        thisReceiver = thisReceiver?.transform(transformer, data)
+        val thisReceiver = this.thisReceiver
+        thisReceiver?.transform(transformer, data)?.let { new ->
+            if (new !== thisReceiver) {
+                this.thisReceiver = new
+            }
+        }
     }
 }
diff --git a/compiler/ir/ir.tree/gen/org/jetbrains/kotlin/ir/declarations/IrEnumEntry.kt b/compiler/ir/ir.tree/gen/org/jetbrains/kotlin/ir/declarations/IrEnumEntry.kt
index f3f997e..c678a09 100644
--- a/compiler/ir/ir.tree/gen/org/jetbrains/kotlin/ir/declarations/IrEnumEntry.kt
+++ b/compiler/ir/ir.tree/gen/org/jetbrains/kotlin/ir/declarations/IrEnumEntry.kt
@@ -39,7 +39,17 @@
     }
 
     override fun <D> transformChildren(transformer: IrElementTransformer<D>, data: D) {
-        initializerExpression = initializerExpression?.transform(transformer, data)
-        correspondingClass = correspondingClass?.transform(transformer, data) as IrClass?
+        val initializerExpression = this.initializerExpression
+        initializerExpression?.transform(transformer, data)?.let { new ->
+            if (new !== initializerExpression) {
+                this.initializerExpression = new
+            }
+        }
+        val correspondingClass = this.correspondingClass
+        correspondingClass?.transform(transformer, data)?.let { new ->
+            if (new !== correspondingClass) {
+                this.correspondingClass = new as IrClass?
+            }
+        }
     }
 }
diff --git a/compiler/ir/ir.tree/gen/org/jetbrains/kotlin/ir/declarations/IrField.kt b/compiler/ir/ir.tree/gen/org/jetbrains/kotlin/ir/declarations/IrField.kt
index fcaf30e..731ba63 100644
--- a/compiler/ir/ir.tree/gen/org/jetbrains/kotlin/ir/declarations/IrField.kt
+++ b/compiler/ir/ir.tree/gen/org/jetbrains/kotlin/ir/declarations/IrField.kt
@@ -46,6 +46,11 @@
     }
 
     override fun <D> transformChildren(transformer: IrElementTransformer<D>, data: D) {
-        initializer = initializer?.transform(transformer, data)
+        val initializer = this.initializer
+        initializer?.transform(transformer, data)?.let { new ->
+            if (new !== initializer) {
+                this.initializer = new
+            }
+        }
     }
 }
diff --git a/compiler/ir/ir.tree/gen/org/jetbrains/kotlin/ir/declarations/IrFile.kt b/compiler/ir/ir.tree/gen/org/jetbrains/kotlin/ir/declarations/IrFile.kt
index 737a0b94..d19e171 100644
--- a/compiler/ir/ir.tree/gen/org/jetbrains/kotlin/ir/declarations/IrFile.kt
+++ b/compiler/ir/ir.tree/gen/org/jetbrains/kotlin/ir/declarations/IrFile.kt
@@ -29,8 +29,14 @@
     override fun <R, D> accept(visitor: IrElementVisitor<R, D>, data: D): R =
         visitor.visitFile(this, data)
 
-    override fun <D> transform(transformer: IrElementTransformer<D>, data: D): IrFile =
-        accept(transformer, data) as IrFile
+    override fun <D> transform(transformer: IrElementTransformer<D>, data: D): IrFile {
+        val new = accept(transformer, data)
+        if (new === this)
+             return this
+        else
+             return new as IrFile
+    }
+
 
     override fun <D> acceptChildren(visitor: IrElementVisitor<Unit, D>, data: D) {
         declarations.forEach { it.accept(visitor, data) }
diff --git a/compiler/ir/ir.tree/gen/org/jetbrains/kotlin/ir/declarations/IrFunction.kt b/compiler/ir/ir.tree/gen/org/jetbrains/kotlin/ir/declarations/IrFunction.kt
index 7eb79ec..682290c 100644
--- a/compiler/ir/ir.tree/gen/org/jetbrains/kotlin/ir/declarations/IrFunction.kt
+++ b/compiler/ir/ir.tree/gen/org/jetbrains/kotlin/ir/declarations/IrFunction.kt
@@ -53,10 +53,35 @@
     }
 
     override fun <D> transformChildren(transformer: IrElementTransformer<D>, data: D) {
-        typeParameters = typeParameters.transformIfNeeded(transformer, data)
-        dispatchReceiverParameter = dispatchReceiverParameter?.transform(transformer, data)
-        extensionReceiverParameter = extensionReceiverParameter?.transform(transformer, data)
-        valueParameters = valueParameters.transformIfNeeded(transformer, data)
-        body = body?.transform(transformer, data)
+        val typeParameters = this.typeParameters
+        typeParameters.transformIfNeeded(transformer, data).let { new ->
+            if (new !== typeParameters) {
+                this.typeParameters = new
+            }
+        }
+        val dispatchReceiverParameter = this.dispatchReceiverParameter
+        dispatchReceiverParameter?.transform(transformer, data)?.let { new ->
+            if (new !== dispatchReceiverParameter) {
+                this.dispatchReceiverParameter = new
+            }
+        }
+        val extensionReceiverParameter = this.extensionReceiverParameter
+        extensionReceiverParameter?.transform(transformer, data)?.let { new ->
+            if (new !== extensionReceiverParameter) {
+                this.extensionReceiverParameter = new
+            }
+        }
+        val valueParameters = this.valueParameters
+        valueParameters.transformIfNeeded(transformer, data).let { new ->
+            if (new !== valueParameters) {
+                this.valueParameters = new
+            }
+        }
+        val body = this.body
+        body?.transform(transformer, data)?.let { new ->
+            if (new !== body) {
+                this.body = new
+            }
+        }
     }
 }
diff --git a/compiler/ir/ir.tree/gen/org/jetbrains/kotlin/ir/declarations/IrLocalDelegatedProperty.kt b/compiler/ir/ir.tree/gen/org/jetbrains/kotlin/ir/declarations/IrLocalDelegatedProperty.kt
index f5ff3de..0f1fb5c 100644
--- a/compiler/ir/ir.tree/gen/org/jetbrains/kotlin/ir/declarations/IrLocalDelegatedProperty.kt
+++ b/compiler/ir/ir.tree/gen/org/jetbrains/kotlin/ir/declarations/IrLocalDelegatedProperty.kt
@@ -46,8 +46,23 @@
     }
 
     override fun <D> transformChildren(transformer: IrElementTransformer<D>, data: D) {
-        delegate = delegate.transform(transformer, data) as IrVariable
-        getter = getter.transform(transformer, data) as IrSimpleFunction
-        setter = setter?.transform(transformer, data) as IrSimpleFunction?
+        val delegate = this.delegate
+        delegate.transform(transformer, data).let { new ->
+            if (new !== delegate) {
+                this.delegate = new as IrVariable
+            }
+        }
+        val getter = this.getter
+        getter.transform(transformer, data).let { new ->
+            if (new !== getter) {
+                this.getter = new as IrSimpleFunction
+            }
+        }
+        val setter = this.setter
+        setter?.transform(transformer, data)?.let { new ->
+            if (new !== setter) {
+                this.setter = new as IrSimpleFunction?
+            }
+        }
     }
 }
diff --git a/compiler/ir/ir.tree/gen/org/jetbrains/kotlin/ir/declarations/IrModuleFragment.kt b/compiler/ir/ir.tree/gen/org/jetbrains/kotlin/ir/declarations/IrModuleFragment.kt
index fcc3638..72e6b95 100644
--- a/compiler/ir/ir.tree/gen/org/jetbrains/kotlin/ir/declarations/IrModuleFragment.kt
+++ b/compiler/ir/ir.tree/gen/org/jetbrains/kotlin/ir/declarations/IrModuleFragment.kt
@@ -41,8 +41,14 @@
     override fun <R, D> accept(visitor: IrElementVisitor<R, D>, data: D): R =
         visitor.visitModuleFragment(this, data)
 
-    override fun <D> transform(transformer: IrElementTransformer<D>, data: D): IrModuleFragment =
-        accept(transformer, data) as IrModuleFragment
+    override fun <D> transform(transformer: IrElementTransformer<D>, data: D): IrModuleFragment {
+        val new = accept(transformer, data)
+        if (new === this)
+             return this
+        else
+             return new as IrModuleFragment
+    }
+
 
     override fun <D> acceptChildren(visitor: IrElementVisitor<Unit, D>, data: D) {
         files.forEach { it.accept(visitor, data) }
diff --git a/compiler/ir/ir.tree/gen/org/jetbrains/kotlin/ir/declarations/IrProperty.kt b/compiler/ir/ir.tree/gen/org/jetbrains/kotlin/ir/declarations/IrProperty.kt
index 71fef29..8541508 100644
--- a/compiler/ir/ir.tree/gen/org/jetbrains/kotlin/ir/declarations/IrProperty.kt
+++ b/compiler/ir/ir.tree/gen/org/jetbrains/kotlin/ir/declarations/IrProperty.kt
@@ -53,8 +53,23 @@
     }
 
     override fun <D> transformChildren(transformer: IrElementTransformer<D>, data: D) {
-        backingField = backingField?.transform(transformer, data) as IrField?
-        getter = getter?.transform(transformer, data) as IrSimpleFunction?
-        setter = setter?.transform(transformer, data) as IrSimpleFunction?
+        val backingField = this.backingField
+        backingField?.transform(transformer, data)?.let { new ->
+            if (new !== backingField) {
+                this.backingField = new as IrField?
+            }
+        }
+        val getter = this.getter
+        getter?.transform(transformer, data)?.let { new ->
+            if (new !== getter) {
+                this.getter = new as IrSimpleFunction?
+            }
+        }
+        val setter = this.setter
+        setter?.transform(transformer, data)?.let { new ->
+            if (new !== setter) {
+                this.setter = new as IrSimpleFunction?
+            }
+        }
     }
 }
diff --git a/compiler/ir/ir.tree/gen/org/jetbrains/kotlin/ir/declarations/IrScript.kt b/compiler/ir/ir.tree/gen/org/jetbrains/kotlin/ir/declarations/IrScript.kt
index e9a961b..e17dcc1 100644
--- a/compiler/ir/ir.tree/gen/org/jetbrains/kotlin/ir/declarations/IrScript.kt
+++ b/compiler/ir/ir.tree/gen/org/jetbrains/kotlin/ir/declarations/IrScript.kt
@@ -64,10 +64,35 @@
 
     override fun <D> transformChildren(transformer: IrElementTransformer<D>, data: D) {
         statements.transformInPlace(transformer, data)
-        thisReceiver = thisReceiver?.transform(transformer, data)
-        explicitCallParameters = explicitCallParameters.transformIfNeeded(transformer, data)
-        implicitReceiversParameters = implicitReceiversParameters.transformIfNeeded(transformer, data)
-        providedPropertiesParameters = providedPropertiesParameters.transformIfNeeded(transformer, data)
-        earlierScriptsParameter = earlierScriptsParameter?.transform(transformer, data)
+        val thisReceiver = this.thisReceiver
+        thisReceiver?.transform(transformer, data)?.let { new ->
+            if (new !== thisReceiver) {
+                this.thisReceiver = new
+            }
+        }
+        val explicitCallParameters = this.explicitCallParameters
+        explicitCallParameters.transformIfNeeded(transformer, data).let { new ->
+            if (new !== explicitCallParameters) {
+                this.explicitCallParameters = new
+            }
+        }
+        val implicitReceiversParameters = this.implicitReceiversParameters
+        implicitReceiversParameters.transformIfNeeded(transformer, data).let { new ->
+            if (new !== implicitReceiversParameters) {
+                this.implicitReceiversParameters = new
+            }
+        }
+        val providedPropertiesParameters = this.providedPropertiesParameters
+        providedPropertiesParameters.transformIfNeeded(transformer, data).let { new ->
+            if (new !== providedPropertiesParameters) {
+                this.providedPropertiesParameters = new
+            }
+        }
+        val earlierScriptsParameter = this.earlierScriptsParameter
+        earlierScriptsParameter?.transform(transformer, data)?.let { new ->
+            if (new !== earlierScriptsParameter) {
+                this.earlierScriptsParameter = new
+            }
+        }
     }
 }
diff --git a/compiler/ir/ir.tree/gen/org/jetbrains/kotlin/ir/declarations/IrTypeAlias.kt b/compiler/ir/ir.tree/gen/org/jetbrains/kotlin/ir/declarations/IrTypeAlias.kt
index 43052e1..603c5f9 100644
--- a/compiler/ir/ir.tree/gen/org/jetbrains/kotlin/ir/declarations/IrTypeAlias.kt
+++ b/compiler/ir/ir.tree/gen/org/jetbrains/kotlin/ir/declarations/IrTypeAlias.kt
@@ -39,6 +39,11 @@
     }
 
     override fun <D> transformChildren(transformer: IrElementTransformer<D>, data: D) {
-        typeParameters = typeParameters.transformIfNeeded(transformer, data)
+        val typeParameters = this.typeParameters
+        typeParameters.transformIfNeeded(transformer, data).let { new ->
+            if (new !== typeParameters) {
+                this.typeParameters = new
+            }
+        }
     }
 }
diff --git a/compiler/ir/ir.tree/gen/org/jetbrains/kotlin/ir/declarations/IrTypeParameter.kt b/compiler/ir/ir.tree/gen/org/jetbrains/kotlin/ir/declarations/IrTypeParameter.kt
index 13a96b1..f8035d4 100644
--- a/compiler/ir/ir.tree/gen/org/jetbrains/kotlin/ir/declarations/IrTypeParameter.kt
+++ b/compiler/ir/ir.tree/gen/org/jetbrains/kotlin/ir/declarations/IrTypeParameter.kt
@@ -38,6 +38,12 @@
     override fun <R, D> accept(visitor: IrElementVisitor<R, D>, data: D): R =
         visitor.visitTypeParameter(this, data)
 
-    override fun <D> transform(transformer: IrElementTransformer<D>, data: D): IrTypeParameter =
-        accept(transformer, data) as IrTypeParameter
+    override fun <D> transform(transformer: IrElementTransformer<D>, data: D): IrTypeParameter {
+        val new = accept(transformer, data)
+        if (new === this)
+             return this
+        else
+             return new as IrTypeParameter
+    }
+
 }
diff --git a/compiler/ir/ir.tree/gen/org/jetbrains/kotlin/ir/declarations/IrValueParameter.kt b/compiler/ir/ir.tree/gen/org/jetbrains/kotlin/ir/declarations/IrValueParameter.kt
index b247b09..5139773 100644
--- a/compiler/ir/ir.tree/gen/org/jetbrains/kotlin/ir/declarations/IrValueParameter.kt
+++ b/compiler/ir/ir.tree/gen/org/jetbrains/kotlin/ir/declarations/IrValueParameter.kt
@@ -70,14 +70,25 @@
     override fun <R, D> accept(visitor: IrElementVisitor<R, D>, data: D): R =
         visitor.visitValueParameter(this, data)
 
-    override fun <D> transform(transformer: IrElementTransformer<D>, data: D): IrValueParameter =
-        accept(transformer, data) as IrValueParameter
+    override fun <D> transform(transformer: IrElementTransformer<D>, data: D): IrValueParameter {
+        val new = accept(transformer, data)
+        if (new === this)
+             return this
+        else
+             return new as IrValueParameter
+    }
+
 
     override fun <D> acceptChildren(visitor: IrElementVisitor<Unit, D>, data: D) {
         defaultValue?.accept(visitor, data)
     }
 
     override fun <D> transformChildren(transformer: IrElementTransformer<D>, data: D) {
-        defaultValue = defaultValue?.transform(transformer, data)
+        val defaultValue = this.defaultValue
+        defaultValue?.transform(transformer, data)?.let { new ->
+            if (new !== defaultValue) {
+                this.defaultValue = new
+            }
+        }
     }
 }
diff --git a/compiler/ir/ir.tree/gen/org/jetbrains/kotlin/ir/declarations/IrVariable.kt b/compiler/ir/ir.tree/gen/org/jetbrains/kotlin/ir/declarations/IrVariable.kt
index 841cec4..52f6b61 100644
--- a/compiler/ir/ir.tree/gen/org/jetbrains/kotlin/ir/declarations/IrVariable.kt
+++ b/compiler/ir/ir.tree/gen/org/jetbrains/kotlin/ir/declarations/IrVariable.kt
@@ -42,6 +42,11 @@
     }
 
     override fun <D> transformChildren(transformer: IrElementTransformer<D>, data: D) {
-        initializer = initializer?.transform(transformer, data)
+        val initializer = this.initializer
+        initializer?.transform(transformer, data)?.let { new ->
+            if (new !== initializer) {
+                this.initializer = new
+            }
+        }
     }
 }
diff --git a/compiler/ir/ir.tree/gen/org/jetbrains/kotlin/ir/expressions/IrBody.kt b/compiler/ir/ir.tree/gen/org/jetbrains/kotlin/ir/expressions/IrBody.kt
index 9b9c809..9d1d564 100644
--- a/compiler/ir/ir.tree/gen/org/jetbrains/kotlin/ir/expressions/IrBody.kt
+++ b/compiler/ir/ir.tree/gen/org/jetbrains/kotlin/ir/expressions/IrBody.kt
@@ -18,6 +18,12 @@
  * Generated from: [org.jetbrains.kotlin.ir.generator.IrTree.body]
  */
 abstract class IrBody : IrElementBase(), IrElement {
-    override fun <D> transform(transformer: IrElementTransformer<D>, data: D): IrBody =
-        accept(transformer, data) as IrBody
+    override fun <D> transform(transformer: IrElementTransformer<D>, data: D): IrBody {
+        val new = accept(transformer, data)
+        if (new === this)
+             return this
+        else
+             return new as IrBody
+    }
+
 }
diff --git a/compiler/ir/ir.tree/gen/org/jetbrains/kotlin/ir/expressions/IrBranch.kt b/compiler/ir/ir.tree/gen/org/jetbrains/kotlin/ir/expressions/IrBranch.kt
index e451115..2dc7f52 100644
--- a/compiler/ir/ir.tree/gen/org/jetbrains/kotlin/ir/expressions/IrBranch.kt
+++ b/compiler/ir/ir.tree/gen/org/jetbrains/kotlin/ir/expressions/IrBranch.kt
@@ -26,8 +26,14 @@
     override fun <R, D> accept(visitor: IrElementVisitor<R, D>, data: D): R =
         visitor.visitBranch(this, data)
 
-    override fun <D> transform(transformer: IrElementTransformer<D>, data: D): IrBranch =
-        accept(transformer, data) as IrBranch
+    override fun <D> transform(transformer: IrElementTransformer<D>, data: D): IrBranch {
+        val new = accept(transformer, data)
+        if (new === this)
+             return this
+        else
+             return new as IrBranch
+    }
+
 
     override fun <D> acceptChildren(visitor: IrElementVisitor<Unit, D>, data: D) {
         condition.accept(visitor, data)
@@ -35,7 +41,17 @@
     }
 
     override fun <D> transformChildren(transformer: IrElementTransformer<D>, data: D) {
-        condition = condition.transform(transformer, data)
-        result = result.transform(transformer, data)
+        val condition = this.condition
+        condition.transform(transformer, data).let { new ->
+            if (new !== condition) {
+                this.condition = new
+            }
+        }
+        val result = this.result
+        result.transform(transformer, data).let { new ->
+            if (new !== result) {
+                this.result = new
+            }
+        }
     }
 }
diff --git a/compiler/ir/ir.tree/gen/org/jetbrains/kotlin/ir/expressions/IrCatch.kt b/compiler/ir/ir.tree/gen/org/jetbrains/kotlin/ir/expressions/IrCatch.kt
index d1688d7..71a02f8 100644
--- a/compiler/ir/ir.tree/gen/org/jetbrains/kotlin/ir/expressions/IrCatch.kt
+++ b/compiler/ir/ir.tree/gen/org/jetbrains/kotlin/ir/expressions/IrCatch.kt
@@ -27,8 +27,14 @@
     override fun <R, D> accept(visitor: IrElementVisitor<R, D>, data: D): R =
         visitor.visitCatch(this, data)
 
-    override fun <D> transform(transformer: IrElementTransformer<D>, data: D): IrCatch =
-        accept(transformer, data) as IrCatch
+    override fun <D> transform(transformer: IrElementTransformer<D>, data: D): IrCatch {
+        val new = accept(transformer, data)
+        if (new === this)
+             return this
+        else
+             return new as IrCatch
+    }
+
 
     override fun <D> acceptChildren(visitor: IrElementVisitor<Unit, D>, data: D) {
         catchParameter.accept(visitor, data)
@@ -36,7 +42,17 @@
     }
 
     override fun <D> transformChildren(transformer: IrElementTransformer<D>, data: D) {
-        catchParameter = catchParameter.transform(transformer, data) as IrVariable
-        result = result.transform(transformer, data)
+        val catchParameter = this.catchParameter
+        catchParameter.transform(transformer, data).let { new ->
+            if (new !== catchParameter) {
+                this.catchParameter = new as IrVariable
+            }
+        }
+        val result = this.result
+        result.transform(transformer, data).let { new ->
+            if (new !== result) {
+                this.result = new
+            }
+        }
     }
 }
diff --git a/compiler/ir/ir.tree/gen/org/jetbrains/kotlin/ir/expressions/IrConstantPrimitive.kt b/compiler/ir/ir.tree/gen/org/jetbrains/kotlin/ir/expressions/IrConstantPrimitive.kt
index 17e5266..5e46d48 100644
--- a/compiler/ir/ir.tree/gen/org/jetbrains/kotlin/ir/expressions/IrConstantPrimitive.kt
+++ b/compiler/ir/ir.tree/gen/org/jetbrains/kotlin/ir/expressions/IrConstantPrimitive.kt
@@ -27,6 +27,11 @@
     }
 
     override fun <D> transformChildren(transformer: IrElementTransformer<D>, data: D) {
-        value = value.transform(transformer, data) as IrConst<*>
+        val value = this.value
+        value.transform(transformer, data).let { new ->
+            if (new !== value) {
+                this.value = new as IrConst<*>
+            }
+        }
     }
 }
diff --git a/compiler/ir/ir.tree/gen/org/jetbrains/kotlin/ir/expressions/IrDoWhileLoop.kt b/compiler/ir/ir.tree/gen/org/jetbrains/kotlin/ir/expressions/IrDoWhileLoop.kt
index 34351e5..2b7242b 100644
--- a/compiler/ir/ir.tree/gen/org/jetbrains/kotlin/ir/expressions/IrDoWhileLoop.kt
+++ b/compiler/ir/ir.tree/gen/org/jetbrains/kotlin/ir/expressions/IrDoWhileLoop.kt
@@ -26,7 +26,17 @@
     }
 
     override fun <D> transformChildren(transformer: IrElementTransformer<D>, data: D) {
-        body = body?.transform(transformer, data)
-        condition = condition.transform(transformer, data)
+        val body = this.body
+        body?.transform(transformer, data)?.let { new ->
+            if (new !== body) {
+                this.body = new
+            }
+        }
+        val condition = this.condition
+        condition.transform(transformer, data).let { new ->
+            if (new !== condition) {
+                this.condition = new
+            }
+        }
     }
 }
diff --git a/compiler/ir/ir.tree/gen/org/jetbrains/kotlin/ir/expressions/IrDynamicMemberExpression.kt b/compiler/ir/ir.tree/gen/org/jetbrains/kotlin/ir/expressions/IrDynamicMemberExpression.kt
index 9d24a7a..7138c3a 100644
--- a/compiler/ir/ir.tree/gen/org/jetbrains/kotlin/ir/expressions/IrDynamicMemberExpression.kt
+++ b/compiler/ir/ir.tree/gen/org/jetbrains/kotlin/ir/expressions/IrDynamicMemberExpression.kt
@@ -29,6 +29,11 @@
     }
 
     override fun <D> transformChildren(transformer: IrElementTransformer<D>, data: D) {
-        receiver = receiver.transform(transformer, data)
+        val receiver = this.receiver
+        receiver.transform(transformer, data).let { new ->
+            if (new !== receiver) {
+                this.receiver = new
+            }
+        }
     }
 }
diff --git a/compiler/ir/ir.tree/gen/org/jetbrains/kotlin/ir/expressions/IrDynamicOperatorExpression.kt b/compiler/ir/ir.tree/gen/org/jetbrains/kotlin/ir/expressions/IrDynamicOperatorExpression.kt
index bf09f46..107ab8e 100644
--- a/compiler/ir/ir.tree/gen/org/jetbrains/kotlin/ir/expressions/IrDynamicOperatorExpression.kt
+++ b/compiler/ir/ir.tree/gen/org/jetbrains/kotlin/ir/expressions/IrDynamicOperatorExpression.kt
@@ -33,7 +33,12 @@
     }
 
     override fun <D> transformChildren(transformer: IrElementTransformer<D>, data: D) {
-        receiver = receiver.transform(transformer, data)
+        val receiver = this.receiver
+        receiver.transform(transformer, data).let { new ->
+            if (new !== receiver) {
+                this.receiver = new
+            }
+        }
         arguments.transformInPlace(transformer, data)
     }
 }
diff --git a/compiler/ir/ir.tree/gen/org/jetbrains/kotlin/ir/expressions/IrElseBranch.kt b/compiler/ir/ir.tree/gen/org/jetbrains/kotlin/ir/expressions/IrElseBranch.kt
index a236b14..8721d0a 100644
--- a/compiler/ir/ir.tree/gen/org/jetbrains/kotlin/ir/expressions/IrElseBranch.kt
+++ b/compiler/ir/ir.tree/gen/org/jetbrains/kotlin/ir/expressions/IrElseBranch.kt
@@ -20,6 +20,12 @@
     override fun <R, D> accept(visitor: IrElementVisitor<R, D>, data: D): R =
         visitor.visitElseBranch(this, data)
 
-    override fun <D> transform(transformer: IrElementTransformer<D>, data: D): IrElseBranch =
-        accept(transformer, data) as IrElseBranch
+    override fun <D> transform(transformer: IrElementTransformer<D>, data: D): IrElseBranch {
+        val new = accept(transformer, data)
+        if (new === this)
+             return this
+        else
+             return new as IrElseBranch
+    }
+
 }
diff --git a/compiler/ir/ir.tree/gen/org/jetbrains/kotlin/ir/expressions/IrErrorCallExpression.kt b/compiler/ir/ir.tree/gen/org/jetbrains/kotlin/ir/expressions/IrErrorCallExpression.kt
index de7ab12..18fe95f 100644
--- a/compiler/ir/ir.tree/gen/org/jetbrains/kotlin/ir/expressions/IrErrorCallExpression.kt
+++ b/compiler/ir/ir.tree/gen/org/jetbrains/kotlin/ir/expressions/IrErrorCallExpression.kt
@@ -31,7 +31,12 @@
     }
 
     override fun <D> transformChildren(transformer: IrElementTransformer<D>, data: D) {
-        explicitReceiver = explicitReceiver?.transform(transformer, data)
+        val explicitReceiver = this.explicitReceiver
+        explicitReceiver?.transform(transformer, data)?.let { new ->
+            if (new !== explicitReceiver) {
+                this.explicitReceiver = new
+            }
+        }
         arguments.transformInPlace(transformer, data)
     }
 }
diff --git a/compiler/ir/ir.tree/gen/org/jetbrains/kotlin/ir/expressions/IrExpression.kt b/compiler/ir/ir.tree/gen/org/jetbrains/kotlin/ir/expressions/IrExpression.kt
index 619d58f..0ed1c96 100644
--- a/compiler/ir/ir.tree/gen/org/jetbrains/kotlin/ir/expressions/IrExpression.kt
+++ b/compiler/ir/ir.tree/gen/org/jetbrains/kotlin/ir/expressions/IrExpression.kt
@@ -26,6 +26,12 @@
 
     abstract var type: IrType
 
-    override fun <D> transform(transformer: IrElementTransformer<D>, data: D): IrExpression =
-        accept(transformer, data) as IrExpression
+    override fun <D> transform(transformer: IrElementTransformer<D>, data: D): IrExpression {
+        val new = accept(transformer, data)
+        if (new === this)
+             return this
+        else
+             return new as IrExpression
+    }
+
 }
diff --git a/compiler/ir/ir.tree/gen/org/jetbrains/kotlin/ir/expressions/IrExpressionBody.kt b/compiler/ir/ir.tree/gen/org/jetbrains/kotlin/ir/expressions/IrExpressionBody.kt
index 304257b..83704eb 100644
--- a/compiler/ir/ir.tree/gen/org/jetbrains/kotlin/ir/expressions/IrExpressionBody.kt
+++ b/compiler/ir/ir.tree/gen/org/jetbrains/kotlin/ir/expressions/IrExpressionBody.kt
@@ -25,14 +25,25 @@
     override fun <R, D> accept(visitor: IrElementVisitor<R, D>, data: D): R =
         visitor.visitExpressionBody(this, data)
 
-    override fun <D> transform(transformer: IrElementTransformer<D>, data: D): IrExpressionBody =
-        accept(transformer, data) as IrExpressionBody
+    override fun <D> transform(transformer: IrElementTransformer<D>, data: D): IrExpressionBody {
+        val new = accept(transformer, data)
+        if (new === this)
+             return this
+        else
+             return new as IrExpressionBody
+    }
+
 
     override fun <D> acceptChildren(visitor: IrElementVisitor<Unit, D>, data: D) {
         expression.accept(visitor, data)
     }
 
     override fun <D> transformChildren(transformer: IrElementTransformer<D>, data: D) {
-        expression = expression.transform(transformer, data)
+        val expression = this.expression
+        expression.transform(transformer, data).let { new ->
+            if (new !== expression) {
+                this.expression = new
+            }
+        }
     }
 }
diff --git a/compiler/ir/ir.tree/gen/org/jetbrains/kotlin/ir/expressions/IrFunctionExpression.kt b/compiler/ir/ir.tree/gen/org/jetbrains/kotlin/ir/expressions/IrFunctionExpression.kt
index a417992..da22662 100644
--- a/compiler/ir/ir.tree/gen/org/jetbrains/kotlin/ir/expressions/IrFunctionExpression.kt
+++ b/compiler/ir/ir.tree/gen/org/jetbrains/kotlin/ir/expressions/IrFunctionExpression.kt
@@ -30,6 +30,11 @@
     }
 
     override fun <D> transformChildren(transformer: IrElementTransformer<D>, data: D) {
-        function = function.transform(transformer, data) as IrSimpleFunction
+        val function = this.function
+        function.transform(transformer, data).let { new ->
+            if (new !== function) {
+                this.function = new as IrSimpleFunction
+            }
+        }
     }
 }
diff --git a/compiler/ir/ir.tree/gen/org/jetbrains/kotlin/ir/expressions/IrGetClass.kt b/compiler/ir/ir.tree/gen/org/jetbrains/kotlin/ir/expressions/IrGetClass.kt
index 14edb76..b9ab1f9 100644
--- a/compiler/ir/ir.tree/gen/org/jetbrains/kotlin/ir/expressions/IrGetClass.kt
+++ b/compiler/ir/ir.tree/gen/org/jetbrains/kotlin/ir/expressions/IrGetClass.kt
@@ -27,6 +27,11 @@
     }
 
     override fun <D> transformChildren(transformer: IrElementTransformer<D>, data: D) {
-        argument = argument.transform(transformer, data)
+        val argument = this.argument
+        argument.transform(transformer, data).let { new ->
+            if (new !== argument) {
+                this.argument = new
+            }
+        }
     }
 }
diff --git a/compiler/ir/ir.tree/gen/org/jetbrains/kotlin/ir/expressions/IrGetField.kt b/compiler/ir/ir.tree/gen/org/jetbrains/kotlin/ir/expressions/IrGetField.kt
index ab6b057..6e71799 100644
--- a/compiler/ir/ir.tree/gen/org/jetbrains/kotlin/ir/expressions/IrGetField.kt
+++ b/compiler/ir/ir.tree/gen/org/jetbrains/kotlin/ir/expressions/IrGetField.kt
@@ -25,6 +25,11 @@
     }
 
     override fun <D> transformChildren(transformer: IrElementTransformer<D>, data: D) {
-        receiver = receiver?.transform(transformer, data)
+        val receiver = this.receiver
+        receiver?.transform(transformer, data)?.let { new ->
+            if (new !== receiver) {
+                this.receiver = new
+            }
+        }
     }
 }
diff --git a/compiler/ir/ir.tree/gen/org/jetbrains/kotlin/ir/expressions/IrMemberAccessExpression.kt b/compiler/ir/ir.tree/gen/org/jetbrains/kotlin/ir/expressions/IrMemberAccessExpression.kt
index 8da28f0..62a67a4e 100644
--- a/compiler/ir/ir.tree/gen/org/jetbrains/kotlin/ir/expressions/IrMemberAccessExpression.kt
+++ b/compiler/ir/ir.tree/gen/org/jetbrains/kotlin/ir/expressions/IrMemberAccessExpression.kt
@@ -65,8 +65,18 @@
     }
 
     override fun <D> transformChildren(transformer: IrElementTransformer<D>, data: D) {
-        dispatchReceiver = dispatchReceiver?.transform(transformer, data)
-        extensionReceiver = extensionReceiver?.transform(transformer, data)
+        val dispatchReceiver = this.dispatchReceiver
+        dispatchReceiver?.transform(transformer, data)?.let { new ->
+            if (new !== dispatchReceiver) {
+                this.dispatchReceiver = new
+            }
+        }
+        val extensionReceiver = this.extensionReceiver
+        extensionReceiver?.transform(transformer, data)?.let { new ->
+            if (new !== extensionReceiver) {
+                this.extensionReceiver = new
+            }
+        }
         valueArguments.transformInPlace(transformer, data)
     }
 }
diff --git a/compiler/ir/ir.tree/gen/org/jetbrains/kotlin/ir/expressions/IrReturn.kt b/compiler/ir/ir.tree/gen/org/jetbrains/kotlin/ir/expressions/IrReturn.kt
index 6ed74d4..100281a 100644
--- a/compiler/ir/ir.tree/gen/org/jetbrains/kotlin/ir/expressions/IrReturn.kt
+++ b/compiler/ir/ir.tree/gen/org/jetbrains/kotlin/ir/expressions/IrReturn.kt
@@ -30,6 +30,11 @@
     }
 
     override fun <D> transformChildren(transformer: IrElementTransformer<D>, data: D) {
-        value = value.transform(transformer, data)
+        val value = this.value
+        value.transform(transformer, data).let { new ->
+            if (new !== value) {
+                this.value = new
+            }
+        }
     }
 }
diff --git a/compiler/ir/ir.tree/gen/org/jetbrains/kotlin/ir/expressions/IrSetField.kt b/compiler/ir/ir.tree/gen/org/jetbrains/kotlin/ir/expressions/IrSetField.kt
index 3685cbb..45fb648 100644
--- a/compiler/ir/ir.tree/gen/org/jetbrains/kotlin/ir/expressions/IrSetField.kt
+++ b/compiler/ir/ir.tree/gen/org/jetbrains/kotlin/ir/expressions/IrSetField.kt
@@ -28,7 +28,17 @@
     }
 
     override fun <D> transformChildren(transformer: IrElementTransformer<D>, data: D) {
-        receiver = receiver?.transform(transformer, data)
-        value = value.transform(transformer, data)
+        val receiver = this.receiver
+        receiver?.transform(transformer, data)?.let { new ->
+            if (new !== receiver) {
+                this.receiver = new
+            }
+        }
+        val value = this.value
+        value.transform(transformer, data).let { new ->
+            if (new !== value) {
+                this.value = new
+            }
+        }
     }
 }
diff --git a/compiler/ir/ir.tree/gen/org/jetbrains/kotlin/ir/expressions/IrSetValue.kt b/compiler/ir/ir.tree/gen/org/jetbrains/kotlin/ir/expressions/IrSetValue.kt
index 03b8d64..7fde2e3 100644
--- a/compiler/ir/ir.tree/gen/org/jetbrains/kotlin/ir/expressions/IrSetValue.kt
+++ b/compiler/ir/ir.tree/gen/org/jetbrains/kotlin/ir/expressions/IrSetValue.kt
@@ -27,6 +27,11 @@
     }
 
     override fun <D> transformChildren(transformer: IrElementTransformer<D>, data: D) {
-        value = value.transform(transformer, data)
+        val value = this.value
+        value.transform(transformer, data).let { new ->
+            if (new !== value) {
+                this.value = new
+            }
+        }
     }
 }
diff --git a/compiler/ir/ir.tree/gen/org/jetbrains/kotlin/ir/expressions/IrSpreadElement.kt b/compiler/ir/ir.tree/gen/org/jetbrains/kotlin/ir/expressions/IrSpreadElement.kt
index 107ed0b..d7f833e 100644
--- a/compiler/ir/ir.tree/gen/org/jetbrains/kotlin/ir/expressions/IrSpreadElement.kt
+++ b/compiler/ir/ir.tree/gen/org/jetbrains/kotlin/ir/expressions/IrSpreadElement.kt
@@ -23,14 +23,25 @@
     override fun <R, D> accept(visitor: IrElementVisitor<R, D>, data: D): R =
         visitor.visitSpreadElement(this, data)
 
-    override fun <D> transform(transformer: IrElementTransformer<D>, data: D): IrSpreadElement =
-        accept(transformer, data) as IrSpreadElement
+    override fun <D> transform(transformer: IrElementTransformer<D>, data: D): IrSpreadElement {
+        val new = accept(transformer, data)
+        if (new === this)
+             return this
+        else
+             return new as IrSpreadElement
+    }
+
 
     override fun <D> acceptChildren(visitor: IrElementVisitor<Unit, D>, data: D) {
         expression.accept(visitor, data)
     }
 
     override fun <D> transformChildren(transformer: IrElementTransformer<D>, data: D) {
-        expression = expression.transform(transformer, data)
+        val expression = this.expression
+        expression.transform(transformer, data).let { new ->
+            if (new !== expression) {
+                this.expression = new
+            }
+        }
     }
 }
diff --git a/compiler/ir/ir.tree/gen/org/jetbrains/kotlin/ir/expressions/IrSuspendableExpression.kt b/compiler/ir/ir.tree/gen/org/jetbrains/kotlin/ir/expressions/IrSuspendableExpression.kt
index 9b346b1..e4970bb 100644
--- a/compiler/ir/ir.tree/gen/org/jetbrains/kotlin/ir/expressions/IrSuspendableExpression.kt
+++ b/compiler/ir/ir.tree/gen/org/jetbrains/kotlin/ir/expressions/IrSuspendableExpression.kt
@@ -30,7 +30,17 @@
     }
 
     override fun <D> transformChildren(transformer: IrElementTransformer<D>, data: D) {
-        suspensionPointId = suspensionPointId.transform(transformer, data)
-        result = result.transform(transformer, data)
+        val suspensionPointId = this.suspensionPointId
+        suspensionPointId.transform(transformer, data).let { new ->
+            if (new !== suspensionPointId) {
+                this.suspensionPointId = new
+            }
+        }
+        val result = this.result
+        result.transform(transformer, data).let { new ->
+            if (new !== result) {
+                this.result = new
+            }
+        }
     }
 }
diff --git a/compiler/ir/ir.tree/gen/org/jetbrains/kotlin/ir/expressions/IrSuspensionPoint.kt b/compiler/ir/ir.tree/gen/org/jetbrains/kotlin/ir/expressions/IrSuspensionPoint.kt
index 74b2a1f..64af799 100644
--- a/compiler/ir/ir.tree/gen/org/jetbrains/kotlin/ir/expressions/IrSuspensionPoint.kt
+++ b/compiler/ir/ir.tree/gen/org/jetbrains/kotlin/ir/expressions/IrSuspensionPoint.kt
@@ -34,8 +34,23 @@
     }
 
     override fun <D> transformChildren(transformer: IrElementTransformer<D>, data: D) {
-        suspensionPointIdParameter = suspensionPointIdParameter.transform(transformer, data) as IrVariable
-        result = result.transform(transformer, data)
-        resumeResult = resumeResult.transform(transformer, data)
+        val suspensionPointIdParameter = this.suspensionPointIdParameter
+        suspensionPointIdParameter.transform(transformer, data).let { new ->
+            if (new !== suspensionPointIdParameter) {
+                this.suspensionPointIdParameter = new as IrVariable
+            }
+        }
+        val result = this.result
+        result.transform(transformer, data).let { new ->
+            if (new !== result) {
+                this.result = new
+            }
+        }
+        val resumeResult = this.resumeResult
+        resumeResult.transform(transformer, data).let { new ->
+            if (new !== resumeResult) {
+                this.resumeResult = new
+            }
+        }
     }
 }
diff --git a/compiler/ir/ir.tree/gen/org/jetbrains/kotlin/ir/expressions/IrThrow.kt b/compiler/ir/ir.tree/gen/org/jetbrains/kotlin/ir/expressions/IrThrow.kt
index c957856..b3276fd 100644
--- a/compiler/ir/ir.tree/gen/org/jetbrains/kotlin/ir/expressions/IrThrow.kt
+++ b/compiler/ir/ir.tree/gen/org/jetbrains/kotlin/ir/expressions/IrThrow.kt
@@ -27,6 +27,11 @@
     }
 
     override fun <D> transformChildren(transformer: IrElementTransformer<D>, data: D) {
-        value = value.transform(transformer, data)
+        val value = this.value
+        value.transform(transformer, data).let { new ->
+            if (new !== value) {
+                this.value = new
+            }
+        }
     }
 }
diff --git a/compiler/ir/ir.tree/gen/org/jetbrains/kotlin/ir/expressions/IrTry.kt b/compiler/ir/ir.tree/gen/org/jetbrains/kotlin/ir/expressions/IrTry.kt
index 93e8059..a33a018 100644
--- a/compiler/ir/ir.tree/gen/org/jetbrains/kotlin/ir/expressions/IrTry.kt
+++ b/compiler/ir/ir.tree/gen/org/jetbrains/kotlin/ir/expressions/IrTry.kt
@@ -34,8 +34,18 @@
     }
 
     override fun <D> transformChildren(transformer: IrElementTransformer<D>, data: D) {
-        tryResult = tryResult.transform(transformer, data)
+        val tryResult = this.tryResult
+        tryResult.transform(transformer, data).let { new ->
+            if (new !== tryResult) {
+                this.tryResult = new
+            }
+        }
         catches.transformInPlace(transformer, data)
-        finallyExpression = finallyExpression?.transform(transformer, data)
+        val finallyExpression = this.finallyExpression
+        finallyExpression?.transform(transformer, data)?.let { new ->
+            if (new !== finallyExpression) {
+                this.finallyExpression = new
+            }
+        }
     }
 }
diff --git a/compiler/ir/ir.tree/gen/org/jetbrains/kotlin/ir/expressions/IrTypeOperatorCall.kt b/compiler/ir/ir.tree/gen/org/jetbrains/kotlin/ir/expressions/IrTypeOperatorCall.kt
index 8bcfcd3..1ca5b83 100644
--- a/compiler/ir/ir.tree/gen/org/jetbrains/kotlin/ir/expressions/IrTypeOperatorCall.kt
+++ b/compiler/ir/ir.tree/gen/org/jetbrains/kotlin/ir/expressions/IrTypeOperatorCall.kt
@@ -32,6 +32,11 @@
     }
 
     override fun <D> transformChildren(transformer: IrElementTransformer<D>, data: D) {
-        argument = argument.transform(transformer, data)
+        val argument = this.argument
+        argument.transform(transformer, data).let { new ->
+            if (new !== argument) {
+                this.argument = new
+            }
+        }
     }
 }
diff --git a/compiler/ir/ir.tree/gen/org/jetbrains/kotlin/ir/expressions/IrWhileLoop.kt b/compiler/ir/ir.tree/gen/org/jetbrains/kotlin/ir/expressions/IrWhileLoop.kt
index 49435fc..44f4ac6 100644
--- a/compiler/ir/ir.tree/gen/org/jetbrains/kotlin/ir/expressions/IrWhileLoop.kt
+++ b/compiler/ir/ir.tree/gen/org/jetbrains/kotlin/ir/expressions/IrWhileLoop.kt
@@ -26,7 +26,17 @@
     }
 
     override fun <D> transformChildren(transformer: IrElementTransformer<D>, data: D) {
-        condition = condition.transform(transformer, data)
-        body = body?.transform(transformer, data)
+        val condition = this.condition
+        condition.transform(transformer, data).let { new ->
+            if (new !== condition) {
+                this.condition = new
+            }
+        }
+        val body = this.body
+        body?.transform(transformer, data)?.let { new ->
+            if (new !== body) {
+                this.body = new
+            }
+        }
     }
 }
diff --git a/compiler/ir/ir.tree/tree-generator/src/org/jetbrains/kotlin/ir/generator/print/ElementPrinter.kt b/compiler/ir/ir.tree/tree-generator/src/org/jetbrains/kotlin/ir/generator/print/ElementPrinter.kt
index 78f48d1..5773280 100644
--- a/compiler/ir/ir.tree/tree-generator/src/org/jetbrains/kotlin/ir/generator/print/ElementPrinter.kt
+++ b/compiler/ir/ir.tree/tree-generator/src/org/jetbrains/kotlin/ir/generator/print/ElementPrinter.kt
@@ -15,6 +15,7 @@
 import org.jetbrains.kotlin.ir.generator.model.ListField
 import org.jetbrains.kotlin.ir.generator.model.SingleField
 import org.jetbrains.kotlin.utils.SmartPrinter
+import org.jetbrains.kotlin.utils.withIndent
 import org.jetbrains.kotlin.generators.tree.ElementRef as GenericElementRef
 
 private val transformIfNeeded = ArbitraryImportable("$BASE_PACKAGE.util", "transformIfNeeded")
@@ -100,28 +101,42 @@
             if (!element.isRootElement) {
                 printBlock {
                     for (child in element.transformableChildren) {
-                        print(child.name)
-                        when (child) {
-                            is SingleField -> {
-                                print(" = ", child.name, child.call())
-                                print("transform(transformer, data)")
-                                val elementRef = child.typeRef as GenericElementRef<*>
-                                if (!elementRef.element.hasTransformMethod) {
-                                    print(" as ", elementRef.render())
-                                }
-                                println()
-                            }
-                            is ListField -> {
-                                if (child.isMutable) {
-                                    print(" = ", child.name, child.call())
+                        if (child is SingleField || child is org.jetbrains.kotlin.generators.tree.ListField && child.isMutable) {
+                            println("val ", child.name, " = ", "this.", child.name)
+                            print(child.name, child.call())
+
+                            when (child) {
+                                is ListField -> {
                                     addImport(transformIfNeeded)
-                                    println("transformIfNeeded(transformer, data)")
-                                } else {
-                                    addImport(transformInPlace)
-                                    print(child.call())
-                                    println("transformInPlace(transformer, data)")
+                                    print("transformIfNeeded(transformer, data)")
+                                }
+                                is SingleField -> {
+                                    print("transform(transformer, data)")
                                 }
                             }
+                            println(child.call(), "let { new ->")
+
+                            withIndent {
+                                print("if (new !== ${child.name})")
+                                printBlock {
+                                    print("this.", child.name, " = new")
+
+                                    if (child is SingleField) {
+                                        val elementRef = child.typeRef as GenericElementRef<*>
+                                        if (!elementRef.element.hasTransformMethod) {
+                                            print(" as ", elementRef.render())
+                                        }
+                                    }
+
+                                    println()
+                                }
+                            }
+                            println("}")
+                        } else if (child is ListField) {
+                            print(child.name)
+                            addImport(transformInPlace)
+                            print(child.call())
+                            println("transformInPlace(transformer, data)")
                         }
                     }
                 }
diff --git a/generators/tree-generator-common/src/org/jetbrains/kotlin/generators/tree/printer/printUtils.kt b/generators/tree-generator-common/src/org/jetbrains/kotlin/generators/tree/printer/printUtils.kt
index ab2ee26..a417a3e 100644
--- a/generators/tree-generator-common/src/org/jetbrains/kotlin/generators/tree/printer/printUtils.kt
+++ b/generators/tree-generator-common/src/org/jetbrains/kotlin/generators/tree/printer/printUtils.kt
@@ -301,9 +301,19 @@
         override = !element.isRootElement,
     )
     if (implementation != null) {
-        println(" =")
-        withIndent {
-            print(implementation, " as ", returnType.render())
+        if (returnType is TypeParameterRef) {
+            println(" =")
+            withIndent {
+                print(implementation, " as ", returnType.render())
+            }
+        } else {
+            printBlock {
+                println("val new = $implementation")
+                println("if (new === this)")
+                println("     return this")
+                println("else")
+                println("     return new as ${returnType.render()}")
+            }
         }
     }
     println()