diff --git a/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/lower/loops/HeaderInfo.kt b/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/lower/loops/HeaderInfo.kt index 257cd9bf839..3463e1db6fb 100644 --- a/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/lower/loops/HeaderInfo.kt +++ b/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/lower/loops/HeaderInfo.kt @@ -26,10 +26,10 @@ import org.jetbrains.kotlin.utils.addToStdlib.firstNotNullResult // TODO: Handle UIntProgression, ULongProgression /** Represents a progression type in the Kotlin stdlib. */ -enum class ProgressionType(val numberCastFunctionName: Name) { - INT_PROGRESSION(Name.identifier("toInt")), - LONG_PROGRESSION(Name.identifier("toLong")), - CHAR_PROGRESSION(Name.identifier("toChar")); +enum class ProgressionType(val elementCastFunctionName: Name, val stepCastFunctionName: Name) { + INT_PROGRESSION(Name.identifier("toInt"), Name.identifier("toInt")), + LONG_PROGRESSION(Name.identifier("toLong"), Name.identifier("toLong")), + CHAR_PROGRESSION(Name.identifier("toChar"), Name.identifier("toInt")); /** Returns the [IrType] of the `first`/`last` properties and elements in the progression. */ fun elementType(builtIns: IrBuiltIns): IrType = when (this) { 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 6cd876484ab..ef4798f15a1 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 @@ -22,6 +22,7 @@ import org.jetbrains.kotlin.ir.symbols.IrSymbol import org.jetbrains.kotlin.ir.types.* import org.jetbrains.kotlin.ir.util.functions import org.jetbrains.kotlin.ir.util.isNullable +import org.jetbrains.kotlin.name.Name /** Contains information about variables used in the loop. */ internal sealed class ForLoopHeader( @@ -224,7 +225,10 @@ internal class HeaderProcessor( // In the above example, if first() is a Long and last() is an Int, this creates a // LongProgression so last(), should be cast to a Long. val inductionVariable = scope.createTemporaryVariable( - first.castIfNecessary(progressionType), + first.castIfNecessary( + progressionType.elementType(context.irBuiltIns), + progressionType.elementCastFunctionName + ), nameHint = "inductionVariable", isMutable = true, origin = IrDeclarationOrigin.FOR_LOOP_IMPLICIT_VARIABLE @@ -235,13 +239,23 @@ internal class HeaderProcessor( // them to non-nullable. // TODO: Confirm if casting to non-nullable is still necessary val lastValue = scope.createTemporaryVariable( - ensureNotNullable(last.castIfNecessary(progressionType)), + ensureNotNullable( + last.castIfNecessary( + progressionType.elementType(context.irBuiltIns), + progressionType.elementCastFunctionName + ) + ), nameHint = "last", origin = IrDeclarationOrigin.FOR_LOOP_IMPLICIT_VARIABLE ) val stepValue = scope.createTemporaryVariable( - ensureNotNullable(step), + ensureNotNullable( + step.castIfNecessary( + progressionType.stepType(context.irBuiltIns), + progressionType.stepCastFunctionName + ) + ), nameHint = "step", origin = IrDeclarationOrigin.FOR_LOOP_IMPLICIT_VARIABLE ) @@ -265,11 +279,11 @@ internal class HeaderProcessor( } - private fun IrExpression.castIfNecessary(progressionType: ProgressionType): IrExpression { - return if (type.toKotlinType() == progressionType.elementType(context.irBuiltIns).toKotlinType()) { + private fun IrExpression.castIfNecessary(targetType: IrType, numberCastFunctionName: Name): IrExpression { + return if (type.toKotlinType() == targetType.toKotlinType()) { this } else { - val function = type.getClass()!!.functions.first { it.name == progressionType.numberCastFunctionName } + val function = type.getClass()!!.functions.first { it.name == numberCastFunctionName } IrCallImpl(startOffset, endOffset, function.returnType, function.symbol) .apply { dispatchReceiver = this@castIfNecessary } }