From 13def12731a147c6927fab96ce3327d91a811cba Mon Sep 17 00:00:00 2001 From: pyos Date: Tue, 13 Oct 2020 14:33:24 +0200 Subject: [PATCH] IR: remove unnecessary calls to deepCopyWithSymbols to make it harder to hide incorrect uses. --- .../kotlin/backend/common/ir/IrUtils.kt | 6 ++- .../lower/DefaultArgumentStubGenerator.kt | 2 +- .../common/lower/RangeContainsLowering.kt | 17 +++--- .../common/lower/loops/HeaderProcessor.kt | 52 ++++++++----------- .../common/lower/loops/ProgressionType.kt | 13 +---- .../backend/common/lower/loops/Utils.kt | 29 ++++++----- .../handlers/DefaultProgressionHandler.kt | 13 +++-- .../lower/loops/handlers/StepHandler.kt | 44 ++++++++-------- .../jvm/lower/AddContinuationLowering.kt | 2 +- .../jvm/lower/GenerateMultifileFacades.kt | 3 +- .../lower/JvmDefaultConstructorLowering.kt | 4 +- .../jvm/lower/JvmInnerClassesSupport.kt | 4 +- .../lower/JvmOverloadsAnnotationLowering.kt | 4 +- .../jvm/lower/JvmStaticAnnotationLowering.kt | 9 ++-- 14 files changed, 94 insertions(+), 108 deletions(-) diff --git a/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/ir/IrUtils.kt b/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/ir/IrUtils.kt index e5807bd9d5b..2d6feb1f001 100644 --- a/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/ir/IrUtils.kt +++ b/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/ir/IrUtils.kt @@ -149,7 +149,7 @@ fun IrValueParameter.copyTo( descriptor.bind(it) it.parent = irFunction it.defaultValue = defaultValueCopy - it.annotations = annotations.map { it.deepCopyWithSymbols() } + it.copyAnnotationsFrom(this) } } @@ -229,6 +229,10 @@ private fun IrTypeParameter.copySuperTypesFrom(source: IrTypeParameter, srcToDst } } +fun IrMutableAnnotationContainer.copyAnnotationsFrom(source: IrAnnotationContainer) { + annotations += source.annotations.map { it.deepCopyWithSymbols(this as? IrDeclarationParent) } +} + // Copy value parameters, dispatch receiver, and extension receiver from source to value parameters of this function. // Type of dispatch receiver defaults to source's dispatch receiver. It is overridable in case the new function and the old one are used in // different contexts and expect different type of dispatch receivers. The overriding type should be assign compatible to the old type. diff --git a/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/lower/DefaultArgumentStubGenerator.kt b/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/lower/DefaultArgumentStubGenerator.kt index a67f57ba6f3..0237b3b1220 100644 --- a/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/lower/DefaultArgumentStubGenerator.kt +++ b/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/lower/DefaultArgumentStubGenerator.kt @@ -606,7 +606,7 @@ private fun IrFunction.generateDefaultsFunctionImpl( } // TODO some annotations are needed (e.g. @JvmStatic), others need different values (e.g. @JvmName), the rest are redundant. - newFunction.annotations = annotations.map { it.deepCopyWithSymbols() } + newFunction.copyAnnotationsFrom(this) return newFunction } diff --git a/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/lower/RangeContainsLowering.kt b/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/lower/RangeContainsLowering.kt index 942f65d1fdf..295785591a2 100644 --- a/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/lower/RangeContainsLowering.kt +++ b/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/lower/RangeContainsLowering.kt @@ -27,7 +27,6 @@ import org.jetbrains.kotlin.ir.expressions.IrExpression import org.jetbrains.kotlin.ir.expressions.IrStatementOrigin import org.jetbrains.kotlin.ir.symbols.IrSymbol import org.jetbrains.kotlin.ir.types.* -import org.jetbrains.kotlin.ir.util.deepCopyWithSymbols import org.jetbrains.kotlin.ir.util.defaultType import org.jetbrains.kotlin.ir.util.functions import org.jetbrains.kotlin.ir.visitors.transformChildrenVoid @@ -260,20 +259,20 @@ private class Transformer( additionalStatements.addIfNotNull(lowerVar) additionalStatements.addIfNotNull(upperVar) } - lowerExpression = tmpLowerExpression - upperExpression = tmpUpperExpression + lowerExpression = tmpLowerExpression.copy() + upperExpression = tmpUpperExpression.copy() useLowerClauseOnLeftSide = true } else if (lower.canHaveSideEffects && upper.canHaveSideEffects) { if (shouldUpperComeFirst) { val (upperVar, tmpUpperExpression) = createTemporaryVariableIfNecessary(upper, "containsUpper") additionalStatements.add(upperVar!!) lowerExpression = lower - upperExpression = tmpUpperExpression + upperExpression = tmpUpperExpression.copy() useLowerClauseOnLeftSide = true } else { val (lowerVar, tmpLowerExpression) = createTemporaryVariableIfNecessary(lower, "containsLower") additionalStatements.add(lowerVar!!) - lowerExpression = tmpLowerExpression + lowerExpression = tmpLowerExpression.copy() upperExpression = upper useLowerClauseOnLeftSide = false } @@ -309,27 +308,27 @@ private class Transformer( irCall(lowerCompFun).apply { putValueArgument(0, irInt(0)) putValueArgument(1, irCall(compareToFun).apply { - dispatchReceiver = argExpression + dispatchReceiver = argExpression.copy() putValueArgument(0, lowerExpression) }) } } else { irCall(lowerCompFun).apply { putValueArgument(0, lowerExpression) - putValueArgument(1, argExpression) + putValueArgument(1, argExpression.copy()) } } val upperClause = if (useCompareTo) { irCall(upperCompFun).apply { putValueArgument(0, irCall(compareToFun).apply { - dispatchReceiver = argExpression.deepCopyWithSymbols() + dispatchReceiver = argExpression.copy() putValueArgument(0, upperExpression) }) putValueArgument(1, irInt(0)) } } else { irCall(upperCompFun).apply { - putValueArgument(0, argExpression.deepCopyWithSymbols()) + putValueArgument(0, argExpression.copy()) putValueArgument(1, upperExpression) } } diff --git a/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/lower/loops/HeaderProcessor.kt b/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/lower/loops/HeaderProcessor.kt index 30bfaaacdab..8d994e425bd 100644 --- a/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/lower/loops/HeaderProcessor.kt +++ b/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/lower/loops/HeaderProcessor.kt @@ -13,15 +13,13 @@ import org.jetbrains.kotlin.ir.IrStatement import org.jetbrains.kotlin.ir.builders.* import org.jetbrains.kotlin.ir.declarations.IrDeclarationOrigin import org.jetbrains.kotlin.ir.declarations.IrVariable -import org.jetbrains.kotlin.ir.expressions.IrCall -import org.jetbrains.kotlin.ir.expressions.IrExpression -import org.jetbrains.kotlin.ir.expressions.IrLoop -import org.jetbrains.kotlin.ir.expressions.IrStatementOrigin +import org.jetbrains.kotlin.ir.expressions.* import org.jetbrains.kotlin.ir.expressions.impl.IrDoWhileLoopImpl import org.jetbrains.kotlin.ir.expressions.impl.IrWhileLoopImpl import org.jetbrains.kotlin.ir.symbols.IrSymbol import org.jetbrains.kotlin.ir.types.* import org.jetbrains.kotlin.ir.util.* +import org.jetbrains.kotlin.ir.visitors.IrElementTransformerVoid import org.jetbrains.kotlin.util.OperatorNameConventions /** @@ -68,14 +66,13 @@ internal abstract class NumericForLoopHeader( val inductionVariable: IrVariable protected val stepVariable: IrVariable? - val stepExpression: IrExpression - // Always copy `stepExpression` is it may be used multiple times. - get() = field.deepCopyWithSymbols() + val stepExpression: IrExpressionWithCopy protected val lastVariableIfCanCacheLast: IrVariable? protected val lastExpression: IrExpression - // Always copy `lastExpression` is it may be used in multiple conditions. - get() = field.deepCopyWithSymbols() + // If this is not `IrExpressionWithCopy`, then it is `.getSize()` built in `IndexedGetIterationHandler`. + // It is therefore safe to deep-copy as it does not contain any functions or classes. + get() = if (field is IrExpressionWithCopy) field.copy() else field.deepCopyWithSymbols() protected val symbols = context.ir.symbols @@ -105,11 +102,14 @@ internal abstract class NumericForLoopHeader( // TODO: Confirm if casting to non-nullable is still necessary val last = headerInfo.last.asElementType() - lastVariableIfCanCacheLast = if (headerInfo.canCacheLast) { - scope.createTmpVariable(last, nameHint = "last") - } else null - - lastExpression = if (headerInfo.canCacheLast) irGet(lastVariableIfCanCacheLast!!) else last + if (headerInfo.canCacheLast) { + val (variable, expression) = createTemporaryVariableIfNecessary(last, nameHint = "last") + lastVariableIfCanCacheLast = variable + lastExpression = expression.copy() + } else { + lastVariableIfCanCacheLast = null + lastExpression = last + } val (tmpStepVar, tmpStepExpression) = createTemporaryVariableIfNecessary( @@ -146,7 +146,7 @@ internal abstract class NumericForLoopHeader( inductionVariable.symbol, irCallOp( plusFun.symbol, plusFun.returnType, irGet(inductionVariable), - stepExpression, IrStatementOrigin.PLUSEQ + stepExpression.copy(), IrStatementOrigin.PLUSEQ ), IrStatementOrigin.PLUSEQ ) } @@ -225,14 +225,14 @@ internal abstract class NumericForLoopHeader( context.oror( context.andand( irCall(builtIns.greaterFunByOperandType.getValue(stepClass.symbol)).apply { - putValueArgument(0, stepExpression) + putValueArgument(0, stepExpression.copy()) putValueArgument(1, zeroStepExpression()) }, conditionForIncreasing() ), context.andand( irCall(builtIns.lessFunByOperandType.getValue(stepClass.symbol)).apply { - putValueArgument(0, stepExpression) + putValueArgument(0, stepExpression.copy()) putValueArgument(1, zeroStepExpression()) }, conditionForDecreasing() @@ -351,19 +351,17 @@ internal class ProgressionLoopHeader( } } -private class InitializerCallReplacer(symbolRemapper: SymbolRemapper, typeRemapper: TypeRemapper, val replacementCall: IrCall) : - DeepCopyIrTreeWithSymbols(symbolRemapper, typeRemapper) { +private class InitializerCallReplacer(val replacementCall: IrCall) : IrElementTransformerVoid() { var initializerCall: IrCall? = null override fun visitCall(expression: IrCall): IrCall { - if (initializerCall == null) { - initializerCall = expression - return replacementCall - } else { + if (initializerCall != null) { throw IllegalStateException( "Multiple initializer calls found. First: ${initializerCall!!.render()}\nSecond: ${expression.render()}" ) } + initializerCall = expression + return replacementCall } } @@ -390,9 +388,7 @@ internal class IndexedGetLoopHeader( } // The call could be wrapped in an IMPLICIT_NOTNULL type-cast (see comment in ForLoopsLowering.gatherLoopVariableInfo()). // Find and replace the call to preserve any type-casts. - loopVariable?.initializer = loopVariable?.initializer?.deepCopyWithSymbols { symbolRemapper, typeRemapper -> - InitializerCallReplacer(symbolRemapper, typeRemapper, get) - } + loopVariable?.initializer = loopVariable?.initializer?.transform(InitializerCallReplacer(get), null) // Even if there is no loop variable, we always want to call `get()` as it may have side-effects. // The un-lowered loop always calls `get()` on each iteration. listOf(loopVariable ?: get) + incrementInductionVariable(this) @@ -589,9 +585,7 @@ internal class IterableLoopHeader( } // The call could be wrapped in an IMPLICIT_NOTNULL type-cast (see comment in ForLoopsLowering.gatherLoopVariableInfo()). // Find and replace the call to preserve any type-casts. - loopVariable?.initializer = loopVariable?.initializer?.deepCopyWithSymbols { symbolRemapper, typeRemapper -> - InitializerCallReplacer(symbolRemapper, typeRemapper, next) - } + loopVariable?.initializer = loopVariable?.initializer?.transform(InitializerCallReplacer(next), null) // Even if there is no loop variable, we always want to call `next()` for iterables and sequences. listOf(loopVariable ?: next.coerceToUnitIfNeeded(next.type, context.irBuiltIns)) } diff --git a/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/lower/loops/ProgressionType.kt b/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/lower/loops/ProgressionType.kt index b2d71ded126..da92c8a3820 100644 --- a/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/lower/loops/ProgressionType.kt +++ b/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/lower/loops/ProgressionType.kt @@ -31,8 +31,6 @@ internal sealed class ProgressionType( val maxValueAsLong: Long, val getProgressionLastElementFunction: IrSimpleFunctionSymbol? ) { - abstract fun DeclarationIrBuilder.minValueExpression(): IrExpression - abstract fun DeclarationIrBuilder.zeroStepExpression(): IrExpression fun IrExpression.asElementType() = castIfNecessary(elementClass) @@ -63,7 +61,6 @@ internal class IntProgressionType(symbols: Symbols) : // Uses `getProgressionLastElement(Int, Int, Int): Int` getProgressionLastElementFunction = symbols.getProgressionLastElementByReturnType[symbols.int] ) { - override fun DeclarationIrBuilder.minValueExpression() = irInt(Int.MIN_VALUE) override fun DeclarationIrBuilder.zeroStepExpression() = irInt(0) } @@ -77,7 +74,6 @@ internal class LongProgressionType(symbols: Symbols) : // Uses `getProgressionLastElement(Long, Long, Long): Long` getProgressionLastElementFunction = symbols.getProgressionLastElementByReturnType[symbols.long] ) { - override fun DeclarationIrBuilder.minValueExpression() = irLong(Long.MIN_VALUE) override fun DeclarationIrBuilder.zeroStepExpression() = irLong(0) } @@ -91,7 +87,6 @@ internal class CharProgressionType(symbols: Symbols) : // Uses `getProgressionLastElement(Int, Int, Int): Int` getProgressionLastElementFunction = symbols.getProgressionLastElementByReturnType[symbols.int] ) { - override fun DeclarationIrBuilder.minValueExpression() = irChar(Char.MIN_VALUE) override fun DeclarationIrBuilder.zeroStepExpression() = irInt(0) } @@ -175,7 +170,7 @@ internal abstract class UnsignedProgressionType( } } -internal class UIntProgressionType(symbols: Symbols, allowUnsignedBounds: Boolean) : +internal class UIntProgressionType(symbols: Symbols, allowUnsignedBounds: Boolean) : UnsignedProgressionType( symbols, elementClass = if (allowUnsignedBounds) symbols.uInt!!.owner else symbols.int.owner, @@ -187,13 +182,11 @@ internal class UIntProgressionType(symbols: Symbols, allo unsignedType = symbols.uInt!!.defaultType, unsignedConversionFunction = symbols.toUIntByExtensionReceiver.getValue(symbols.int) ) { - @OptIn(ExperimentalUnsignedTypes::class) - override fun DeclarationIrBuilder.minValueExpression() = irInt(UInt.MIN_VALUE.toInt(), elementClass.defaultType) override fun DeclarationIrBuilder.zeroStepExpression() = irInt(0) } -internal class ULongProgressionType(symbols: Symbols, private val allowUnsignedBounds: Boolean) : +internal class ULongProgressionType(symbols: Symbols, allowUnsignedBounds: Boolean) : UnsignedProgressionType( symbols, elementClass = if (allowUnsignedBounds) symbols.uLong!!.owner else symbols.long.owner, @@ -205,8 +198,6 @@ internal class ULongProgressionType(symbols: Symbols, priv unsignedType = symbols.uLong!!.defaultType, unsignedConversionFunction = symbols.toULongByExtensionReceiver.getValue(symbols.long) ) { - @OptIn(ExperimentalUnsignedTypes::class) - override fun DeclarationIrBuilder.minValueExpression() = irLong(ULong.MIN_VALUE.toLong(), elementClass.defaultType) override fun DeclarationIrBuilder.zeroStepExpression() = irLong(0) } diff --git a/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/lower/loops/Utils.kt b/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/lower/loops/Utils.kt index 5492078fb6f..83f38b6f83e 100644 --- a/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/lower/loops/Utils.kt +++ b/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/lower/loops/Utils.kt @@ -10,10 +10,7 @@ import org.jetbrains.kotlin.ir.builders.createTmpVariable import org.jetbrains.kotlin.ir.builders.irGet import org.jetbrains.kotlin.ir.declarations.IrClass import org.jetbrains.kotlin.ir.declarations.IrVariable -import org.jetbrains.kotlin.ir.expressions.IrConst -import org.jetbrains.kotlin.ir.expressions.IrConstKind -import org.jetbrains.kotlin.ir.expressions.IrExpression -import org.jetbrains.kotlin.ir.expressions.IrGetValue +import org.jetbrains.kotlin.ir.expressions.* import org.jetbrains.kotlin.ir.expressions.impl.IrCallImpl import org.jetbrains.kotlin.ir.expressions.impl.IrConstImpl import org.jetbrains.kotlin.ir.types.IrType @@ -73,16 +70,20 @@ internal fun IrExpression.decrement(): IrExpression { } internal val IrExpression.canHaveSideEffects: Boolean - get() = this !is IrConst<*> && this !is IrGetValue + get() = this !is IrExpressionWithCopy + +private fun Any?.toLong(): Long? = + when (this) { + is Number -> toLong() + is Char -> toLong() + else -> null + } + +internal val IrExpressionWithCopy.constLongValue: Long? + get() = if (this is IrConst<*>) value.toLong() else null internal val IrExpression.constLongValue: Long? - get() = if (this is IrConst<*>) { - when (val value = this.value) { - is Number -> value.toLong() - is Char -> value.toLong() - else -> null - } - } else null + get() = if (this is IrConst<*>) value.toLong() else null /** * If [expression] can have side effects ([IrExpression.canHaveSideEffects]), this function creates a temporary local variable for that @@ -93,8 +94,8 @@ internal val IrExpression.constLongValue: Long? internal fun DeclarationIrBuilder.createTemporaryVariableIfNecessary( expression: IrExpression, nameHint: String? = null, irType: IrType? = null, isMutable: Boolean = false -): Pair = - if (expression.canHaveSideEffects) { +): Pair = + if (expression !is IrExpressionWithCopy) { scope.createTmpVariable(expression, nameHint = nameHint, irType = irType, isMutable = isMutable).let { Pair(it, irGet(it)) } } else { Pair(null, expression) diff --git a/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/lower/loops/handlers/DefaultProgressionHandler.kt b/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/lower/loops/handlers/DefaultProgressionHandler.kt index d46abf4ed23..fd39c8eff54 100644 --- a/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/lower/loops/handlers/DefaultProgressionHandler.kt +++ b/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/lower/loops/handlers/DefaultProgressionHandler.kt @@ -14,7 +14,6 @@ import org.jetbrains.kotlin.ir.expressions.IrExpression import org.jetbrains.kotlin.ir.symbols.IrSymbol import org.jetbrains.kotlin.ir.types.defaultType import org.jetbrains.kotlin.ir.types.getClass -import org.jetbrains.kotlin.ir.util.deepCopyWithSymbols import org.jetbrains.kotlin.ir.util.getPropertyGetter /** Builds a [HeaderInfo] for progressions not handled by more specialized handlers. */ @@ -34,27 +33,27 @@ internal class DefaultProgressionHandler(private val context: CommonBackendConte with(context.createIrBuilder(scopeOwner, expression.startOffset, expression.endOffset)) { // Directly use the `first/last/step` properties of the progression. val (progressionVar, progressionExpression) = createTemporaryVariableIfNecessary(expression, nameHint = "progression") - val progressionClass = progressionExpression.type.getClass()!! + val progressionClass = expression.type.getClass()!! val first = irCall(progressionClass.symbol.getPropertyGetter("first")!!).apply { - dispatchReceiver = progressionExpression + dispatchReceiver = progressionExpression.copy() } val last = irCall(progressionClass.symbol.getPropertyGetter("last")!!).apply { - dispatchReceiver = progressionExpression.deepCopyWithSymbols() + dispatchReceiver = progressionExpression.copy() } // *Ranges (e.g., IntRange) have step == 1 and is always increasing. - val isRange = progressionExpression.type in rangeClassesTypes + val isRange = expression.type in rangeClassesTypes val step = if (isRange) { irInt(1) } else { irCall(progressionClass.symbol.getPropertyGetter("step")!!).apply { - dispatchReceiver = progressionExpression.deepCopyWithSymbols() + dispatchReceiver = progressionExpression.copy() } } val direction = if (isRange) ProgressionDirection.INCREASING else ProgressionDirection.UNKNOWN ProgressionHeaderInfo( - ProgressionType.fromIrType(progressionExpression.type, symbols, allowUnsignedBounds)!!, + ProgressionType.fromIrType(expression.type, symbols, allowUnsignedBounds)!!, first, last, step, diff --git a/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/lower/loops/handlers/StepHandler.kt b/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/lower/loops/handlers/StepHandler.kt index 1ee3346764e..c2cfbb494b6 100644 --- a/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/lower/loops/handlers/StepHandler.kt +++ b/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/lower/loops/handlers/StepHandler.kt @@ -16,11 +16,11 @@ import org.jetbrains.kotlin.ir.builders.* import org.jetbrains.kotlin.ir.declarations.IrVariable import org.jetbrains.kotlin.ir.expressions.IrCall import org.jetbrains.kotlin.ir.expressions.IrExpression +import org.jetbrains.kotlin.ir.expressions.IrExpressionWithCopy import org.jetbrains.kotlin.ir.symbols.IrSymbol import org.jetbrains.kotlin.ir.types.defaultType import org.jetbrains.kotlin.ir.types.isInt import org.jetbrains.kotlin.ir.types.isLong -import org.jetbrains.kotlin.ir.util.deepCopyWithSymbols import org.jetbrains.kotlin.ir.util.defaultType import org.jetbrains.kotlin.name.FqName import kotlin.math.absoluteValue @@ -75,12 +75,11 @@ internal class StepHandler( // We insert a similar check in the lowered form only if necessary. val stepType = data.stepClass.defaultType val stepCompFun = context.irBuiltIns.lessOrEqualFunByOperandType.getValue(data.stepClass.symbol) - val zeroStep = data.run { zeroStepExpression() } val throwIllegalStepExceptionCall = { irCall(context.irBuiltIns.illegalArgumentExceptionSymbol).apply { val exceptionMessage = irConcat() exceptionMessage.addArgument(irString("Step must be positive, was: ")) - exceptionMessage.addArgument(stepArgExpression.deepCopyWithSymbols()) + exceptionMessage.addArgument(stepArgExpression.copy()) exceptionMessage.addArgument(irString(".")) putValueArgument(0, exceptionMessage) } @@ -90,8 +89,8 @@ internal class StepHandler( stepArgValueAsLong == null -> { // Step argument is not a constant. In this case, we check if step <= 0. val stepNonPositiveCheck = irCall(stepCompFun).apply { - putValueArgument(0, stepArgExpression.deepCopyWithSymbols()) - putValueArgument(1, zeroStep.deepCopyWithSymbols()) + putValueArgument(0, stepArgExpression.copy()) + putValueArgument(1, data.run { zeroStepExpression() }) } irIfThen( context.irBuiltIns.unitType, @@ -119,7 +118,8 @@ internal class StepHandler( ProgressionDirection.INCREASING -> stepArgExpression ProgressionDirection.DECREASING -> { if (stepArgVar == null) { - stepArgExpression.negate() + stepNegation = scope.createTmpVariable(stepArgExpression.copy().negate()) + irGet(stepNegation) } else { // Step is already stored in a variable, just negate it. stepNegation = irSet(stepArgVar.symbol, irGet(stepArgVar).negate()) @@ -133,8 +133,8 @@ internal class StepHandler( val (tmpNestedStepVar, nestedStepExpression) = createTemporaryVariableIfNecessary(nestedStep, "nestedStep") nestedStepVar = tmpNestedStepVar val nestedStepNonPositiveCheck = irCall(stepCompFun).apply { - putValueArgument(0, nestedStepExpression) - putValueArgument(1, zeroStep.deepCopyWithSymbols()) + putValueArgument(0, nestedStepExpression.copy()) + putValueArgument(1, data.run { zeroStepExpression() }) } if (stepArgVar == null) { // Create a temporary variable for the possibly-negated step, so we don't have to re-check every time step is used. @@ -142,8 +142,8 @@ internal class StepHandler( irIfThenElse( stepType, nestedStepNonPositiveCheck, - stepArgExpression.deepCopyWithSymbols().negate(), - stepArgExpression.deepCopyWithSymbols() + stepArgExpression.copy().negate(), + stepArgExpression.copy() ), nameHint = "maybeNegatedStep" ) @@ -272,9 +272,9 @@ internal class StepHandler( return ProgressionHeaderInfo( data, - first = nestedFirstExpression, + first = nestedFirstExpression.copy(), last = recalculatedLast, - step = finalStepExpression, + step = finalStepExpression.copy(), isReversed = nestedInfo.isReversed, additionalStatements = additionalStatements, direction = nestedInfo.direction @@ -283,13 +283,13 @@ internal class StepHandler( private fun DeclarationIrBuilder.callGetProgressionLastElementIfNecessary( progressionType: ProgressionType, - first: IrExpression, - last: IrExpression, - step: IrExpression + first: IrExpressionWithCopy, + last: IrExpressionWithCopy, + step: IrExpressionWithCopy ): IrExpression { // Calling getProgressionLastElement() is not needed if step == 1 or -1; the "last" value is unchanged in such cases. if (step.constLongValue?.absoluteValue == 1L) { - return last + return last.copy() } // Call `getProgressionLastElement(first, last, step)`. The following overloads are present in the stdlib: @@ -304,17 +304,17 @@ internal class StepHandler( // Bounds are signed for unsigned progressions but `getProgressionLastElement` expects unsigned. // The return value is finally converted back to signed since it will be assigned back to `last`. irCall(getProgressionLastElementFun).apply { - putValueArgument(0, first.deepCopyWithSymbols().asElementType().asUnsigned()) - putValueArgument(1, last.deepCopyWithSymbols().asElementType().asUnsigned()) - putValueArgument(2, step.deepCopyWithSymbols().asStepType()) + putValueArgument(0, first.copy().asElementType().asUnsigned()) + putValueArgument(1, last.copy().asElementType().asUnsigned()) + putValueArgument(2, step.copy().asStepType()) }.asSigned() } else { irCall(getProgressionLastElementFun).apply { // Step type is used for casting because it works for all signed progressions. In particular, // getProgressionLastElement(Int, Int, Int) is called for CharProgression, which uses an Int step. - putValueArgument(0, first.deepCopyWithSymbols().asStepType()) - putValueArgument(1, last.deepCopyWithSymbols().asStepType()) - putValueArgument(2, step.deepCopyWithSymbols().asStepType()) + putValueArgument(0, first.copy().asStepType()) + putValueArgument(1, last.copy().asStepType()) + putValueArgument(2, step.copy().asStepType()) } } } diff --git a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/lower/AddContinuationLowering.kt b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/lower/AddContinuationLowering.kt index 15cf2b86277..436510ef336 100644 --- a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/lower/AddContinuationLowering.kt +++ b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/lower/AddContinuationLowering.kt @@ -291,7 +291,7 @@ private class AddContinuationLowering(context: JvmBackendContext) : SuspendLower if (view.isInline) JvmLoweredDeclarationOrigin.FOR_INLINE_STATE_MACHINE_TEMPLATE else JvmLoweredDeclarationOrigin.FOR_INLINE_STATE_MACHINE_TEMPLATE_CAPTURES_CROSSINLINE }.apply { - annotations += view.annotations.map { it.deepCopyWithSymbols(this) } + copyAnnotationsFrom(view) copyParameterDeclarationsFrom(view) copyAttributes(view) generateErrorForInlineBody() diff --git a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/lower/GenerateMultifileFacades.kt b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/lower/GenerateMultifileFacades.kt index bbf6e838ece..3f35f36d497 100644 --- a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/lower/GenerateMultifileFacades.kt +++ b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/lower/GenerateMultifileFacades.kt @@ -7,6 +7,7 @@ package org.jetbrains.kotlin.backend.jvm.lower import org.jetbrains.kotlin.backend.common.ClassLoweringPass import org.jetbrains.kotlin.backend.common.FileLoweringPass +import org.jetbrains.kotlin.backend.common.ir.copyAnnotationsFrom import org.jetbrains.kotlin.backend.common.ir.copyParameterDeclarationsFrom import org.jetbrains.kotlin.backend.common.ir.createImplicitParameterDeclarationWithWrappedDescriptor import org.jetbrains.kotlin.backend.common.ir.passTypeArgumentsFrom @@ -219,10 +220,10 @@ private fun IrSimpleFunction.createMultifileDelegateIfNeeded( } } + function.copyAnnotationsFrom(target) function.copyParameterDeclarationsFrom(target) function.returnType = target.returnType.substitute(target.typeParameters, function.typeParameters.map { it.defaultType }) function.parent = facadeClass - function.annotations = target.annotations.map { it.deepCopyWithSymbols() } if (shouldGeneratePartHierarchy) { function.origin = IrDeclarationOrigin.FAKE_OVERRIDE diff --git a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/lower/JvmDefaultConstructorLowering.kt b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/lower/JvmDefaultConstructorLowering.kt index 68ec4c7e845..102a6e23472 100644 --- a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/lower/JvmDefaultConstructorLowering.kt +++ b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/lower/JvmDefaultConstructorLowering.kt @@ -6,6 +6,7 @@ package org.jetbrains.kotlin.backend.jvm.lower import org.jetbrains.kotlin.backend.common.ClassLoweringPass +import org.jetbrains.kotlin.backend.common.ir.copyAnnotationsFrom import org.jetbrains.kotlin.backend.common.ir.passTypeArgumentsFrom import org.jetbrains.kotlin.backend.common.lower.createIrBuilder import org.jetbrains.kotlin.backend.common.phaser.makeIrFilePhase @@ -17,7 +18,6 @@ import org.jetbrains.kotlin.ir.builders.irBlockBody import org.jetbrains.kotlin.ir.builders.irDelegatingConstructorCall import org.jetbrains.kotlin.ir.declarations.IrClass import org.jetbrains.kotlin.ir.util.constructors -import org.jetbrains.kotlin.ir.util.deepCopyWithSymbols import org.jetbrains.kotlin.ir.util.hasDefaultValue internal val jvmDefaultConstructorPhase = makeIrFilePhase( @@ -53,7 +53,7 @@ private class JvmDefaultConstructorLowering(val context: JvmBackendContext) : Cl visibility = primaryConstructor.visibility }.apply { val irBuilder = context.createIrBuilder(this.symbol, startOffset, endOffset) - annotations += primaryConstructor.annotations.map { it.deepCopyWithSymbols(this) } + copyAnnotationsFrom(primaryConstructor) body = irBuilder.irBlockBody { +irDelegatingConstructorCall(primaryConstructor).apply { passTypeArgumentsFrom(irClass) diff --git a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/lower/JvmInnerClassesSupport.kt b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/lower/JvmInnerClassesSupport.kt index c2a2798d97b..75467772513 100644 --- a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/lower/JvmInnerClassesSupport.kt +++ b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/lower/JvmInnerClassesSupport.kt @@ -5,6 +5,7 @@ package org.jetbrains.kotlin.backend.jvm.lower +import org.jetbrains.kotlin.backend.common.ir.copyAnnotationsFrom import org.jetbrains.kotlin.backend.common.ir.copyTo import org.jetbrains.kotlin.backend.common.ir.copyTypeParametersFrom import org.jetbrains.kotlin.backend.common.lower.InnerClassesSupport @@ -17,7 +18,6 @@ import org.jetbrains.kotlin.ir.declarations.IrClass import org.jetbrains.kotlin.ir.declarations.IrConstructor import org.jetbrains.kotlin.ir.declarations.IrFactory import org.jetbrains.kotlin.ir.declarations.IrField -import org.jetbrains.kotlin.ir.util.deepCopyWithSymbols import org.jetbrains.kotlin.ir.util.defaultType import org.jetbrains.kotlin.ir.util.dump import org.jetbrains.kotlin.ir.util.parentAsClass @@ -67,9 +67,9 @@ class JvmInnerClassesSupport(private val irFactory: IrFactory) : InnerClassesSup updateFrom(oldConstructor) returnType = oldConstructor.returnType }.apply { - annotations = oldConstructor.annotations.map { it.deepCopyWithSymbols(this) } parent = oldConstructor.parent returnType = oldConstructor.returnType + copyAnnotationsFrom(oldConstructor) copyTypeParametersFrom(oldConstructor) val outerThisValueParameter = buildValueParameter(this) { diff --git a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/lower/JvmOverloadsAnnotationLowering.kt b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/lower/JvmOverloadsAnnotationLowering.kt index 70e7c30551a..c2ff837bc18 100644 --- a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/lower/JvmOverloadsAnnotationLowering.kt +++ b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/lower/JvmOverloadsAnnotationLowering.kt @@ -6,6 +6,7 @@ package org.jetbrains.kotlin.backend.jvm.lower import org.jetbrains.kotlin.backend.common.ClassLoweringPass +import org.jetbrains.kotlin.backend.common.ir.copyAnnotationsFrom import org.jetbrains.kotlin.backend.common.ir.copyTo import org.jetbrains.kotlin.backend.common.ir.copyTypeParametersFrom import org.jetbrains.kotlin.backend.common.phaser.makeIrFilePhase @@ -20,7 +21,6 @@ import org.jetbrains.kotlin.ir.declarations.* import org.jetbrains.kotlin.ir.expressions.impl.* import org.jetbrains.kotlin.ir.types.defaultType import org.jetbrains.kotlin.ir.util.allTypeParameters -import org.jetbrains.kotlin.ir.util.deepCopyWithSymbols import org.jetbrains.kotlin.ir.util.hasAnnotation import org.jetbrains.kotlin.ir.util.render import org.jetbrains.kotlin.resolve.jvm.annotations.JVM_OVERLOADS_FQ_NAME @@ -145,7 +145,7 @@ private class JvmOverloadsAnnotationLowering(val context: JvmBackendContext) : C } res.parent = oldFunction.parent - res.annotations += oldFunction.annotations.map { it.deepCopyWithSymbols(res) } + res.copyAnnotationsFrom(oldFunction) res.copyTypeParametersFrom(oldFunction) res.dispatchReceiverParameter = oldFunction.dispatchReceiverParameter?.copyTo(res) res.extensionReceiverParameter = oldFunction.extensionReceiverParameter?.copyTo(res) diff --git a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/lower/JvmStaticAnnotationLowering.kt b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/lower/JvmStaticAnnotationLowering.kt index c95eb735e35..a1c0d7be115 100644 --- a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/lower/JvmStaticAnnotationLowering.kt +++ b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/lower/JvmStaticAnnotationLowering.kt @@ -7,10 +7,7 @@ package org.jetbrains.kotlin.backend.jvm.lower import org.jetbrains.kotlin.backend.common.ClassLoweringPass import org.jetbrains.kotlin.backend.common.FileLoweringPass -import org.jetbrains.kotlin.backend.common.ir.copyParameterDeclarationsFrom -import org.jetbrains.kotlin.backend.common.ir.copyTo -import org.jetbrains.kotlin.backend.common.ir.copyTypeParametersFrom -import org.jetbrains.kotlin.backend.common.ir.passTypeArgumentsFrom +import org.jetbrains.kotlin.backend.common.ir.* import org.jetbrains.kotlin.backend.common.lower.createIrBuilder import org.jetbrains.kotlin.backend.common.lower.irBlock import org.jetbrains.kotlin.backend.common.phaser.makeIrFilePhase @@ -79,9 +76,9 @@ private class CompanionObjectJvmStaticLowering(val context: JvmBackendContext) : returnType = jvmStaticFunction.returnType }.apply { copyTypeParametersFrom(jvmStaticFunction) + copyAnnotationsFrom(jvmStaticFunction) extensionReceiverParameter = jvmStaticFunction.extensionReceiverParameter?.copyTo(this) valueParameters = jvmStaticFunction.valueParameters.map { it.copyTo(this) } - annotations = jvmStaticFunction.annotations.map { it.deepCopyWithSymbols() } } companion.declarations.remove(jvmStaticFunction) companion.addProxy(staticExternal, companion, isStatic = false) @@ -106,12 +103,12 @@ private class CompanionObjectJvmStaticLowering(val context: JvmBackendContext) : isSuspend = target.isSuspend }.apply { copyTypeParametersFrom(target) + copyAnnotationsFrom(target) if (!isStatic) { dispatchReceiverParameter = thisReceiver?.copyTo(this, type = defaultType) } extensionReceiverParameter = target.extensionReceiverParameter?.copyTo(this) valueParameters = target.valueParameters.map { it.copyTo(this) } - annotations = target.annotations.map { it.deepCopyWithSymbols() } val proxy = this val companionInstanceField = context.cachedDeclarations.getFieldForObjectInstance(companion)