diff --git a/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/CheckIrElementVisitor.kt b/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/CheckIrElementVisitor.kt index bf9b344263360..9dbfab68322e5 100644 --- a/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/CheckIrElementVisitor.kt +++ b/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/CheckIrElementVisitor.kt @@ -13,9 +13,11 @@ import org.jetbrains.kotlin.ir.declarations.* import org.jetbrains.kotlin.ir.expressions.* import org.jetbrains.kotlin.ir.symbols.IrClassSymbol import org.jetbrains.kotlin.ir.symbols.IrSymbol +import org.jetbrains.kotlin.ir.symbols.IrTypeParameterSymbol import org.jetbrains.kotlin.ir.types.* import org.jetbrains.kotlin.ir.util.isNullable import org.jetbrains.kotlin.ir.util.render +import org.jetbrains.kotlin.ir.util.resolveFakeOverrideMaybeAbstract import org.jetbrains.kotlin.ir.visitors.IrElementVisitorVoid import org.jetbrains.kotlin.resolve.scopes.receivers.ExtensionReceiver @@ -168,13 +170,15 @@ internal class CheckIrElementVisitor( // TODO: Why don't we check parameters as well? - val returnType = expression.symbol.owner.returnType + val callee = expression.symbol.owner // TODO: We don't have the proper type substitution yet, so skip generics for now. + val actualCallee = callee.resolveFakeOverrideMaybeAbstract { it.returnType.classifierOrNull !is IrTypeParameterSymbol } ?: callee + val returnType = actualCallee.returnType if (returnType is IrSimpleType && returnType.classifier is IrClassSymbol && returnType.arguments.isEmpty() ) { - expression.ensureTypeIs(returnType) + expression.ensureTypeIs(callee.returnType) } expression.superQualifierSymbol?.ensureBound(expression) diff --git a/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/driver/phases/NativeLoweringPhases.kt b/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/driver/phases/NativeLoweringPhases.kt index 442bf2746ce6d..99c7b895338bd 100644 --- a/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/driver/phases/NativeLoweringPhases.kt +++ b/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/driver/phases/NativeLoweringPhases.kt @@ -454,16 +454,15 @@ private val bridgesPhase = createFileLoweringPhase( prerequisite = setOf(coroutinesPhase) ) -private val autoboxPhase = createFileLoweringPhase( - ::Autoboxing, - name = "Autobox", - prerequisite = setOf(bridgesPhase, coroutinesPhase) -) - private val eraseGenericCallsReturnTypesPhase = createFileLoweringPhase( name = "EraseGenericCallsReturnTypesPhase", lowering = ::GenericCallsReturnTypeEraser, - prerequisite = setOf(autoboxPhase) +) + +private val autoboxPhase = createFileLoweringPhase( + ::Autoboxing, + name = "Autobox", + prerequisite = setOf(bridgesPhase, coroutinesPhase, eraseGenericCallsReturnTypesPhase) ) private val constructorsLoweringPhase = createFileLoweringPhase( @@ -618,8 +617,8 @@ internal fun KonanConfig.getLoweringsAfterInlining(): LoweringList = listOfNotNu bridgesPhase, exportInternalAbiPhase.takeIf { this.produce.isCache }, useInternalAbiPhase, - autoboxPhase, eraseGenericCallsReturnTypesPhase, + autoboxPhase, constructorsLoweringPhase, ) diff --git a/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/lower/Autoboxing.kt b/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/lower/Autoboxing.kt index ea6860fa0345c..4ecd99582015a 100644 --- a/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/lower/Autoboxing.kt +++ b/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/lower/Autoboxing.kt @@ -106,10 +106,6 @@ private class AutoboxingTransformer(val context: Context) : AbstractValueUsageTr val skipTypeCheck = forceSkipTypeCheck || !insertSafeCasts || (this as? IrTypeOperatorCall)?.operator == IrTypeOperator.CAST val actualType = when (this) { is IrGetField -> this.symbol.owner.type - is IrCall -> when (this.symbol) { - symbols.reinterpret -> this.getTypeArgument(1)!! - else -> this.target.returnType - } is IrTypeOperatorCall -> when (this.operator) { IrTypeOperator.CAST -> context.irBuiltIns.anyNType IrTypeOperator.IMPLICIT_CAST -> if (insertSafeCasts) this.type else context.irBuiltIns.anyNType diff --git a/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/lower/GenericCallsReturnTypeEraser.kt b/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/lower/GenericCallsReturnTypeEraser.kt index 52065a98a1e6e..f84fe917dbd0b 100644 --- a/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/lower/GenericCallsReturnTypeEraser.kt +++ b/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/lower/GenericCallsReturnTypeEraser.kt @@ -6,16 +6,22 @@ package org.jetbrains.kotlin.backend.konan.lower import org.jetbrains.kotlin.backend.common.BodyLoweringPass +import org.jetbrains.kotlin.backend.common.lower.at +import org.jetbrains.kotlin.backend.common.lower.createIrBuilder +import org.jetbrains.kotlin.backend.common.lower.irImplicitCoercionToUnit import org.jetbrains.kotlin.backend.konan.Context -import org.jetbrains.kotlin.ir.IrElement +import org.jetbrains.kotlin.ir.builders.irImplicitCast import org.jetbrains.kotlin.ir.declarations.IrDeclaration import org.jetbrains.kotlin.ir.expressions.IrBody import org.jetbrains.kotlin.ir.expressions.IrCall +import org.jetbrains.kotlin.ir.expressions.IrExpression import org.jetbrains.kotlin.ir.symbols.IrTypeParameterSymbol import org.jetbrains.kotlin.ir.types.classifierOrNull +import org.jetbrains.kotlin.ir.types.isNothing +import org.jetbrains.kotlin.ir.types.isUnit import org.jetbrains.kotlin.ir.util.target -import org.jetbrains.kotlin.ir.visitors.IrElementVisitorVoid -import org.jetbrains.kotlin.ir.visitors.acceptChildrenVoid +import org.jetbrains.kotlin.ir.visitors.IrElementTransformerVoid +import org.jetbrains.kotlin.ir.visitors.transformChildrenVoid /* * FE substitutes types for generic calls, but by the end of the lowerings pipeline, the return types should be @@ -27,20 +33,27 @@ internal class GenericCallsReturnTypeEraser(val context: Context) : BodyLowering private val reinterpret = context.ir.symbols.reinterpret.owner override fun lower(irBody: IrBody, container: IrDeclaration) { - irBody.acceptChildrenVoid(object : IrElementVisitorVoid { - override fun visitElement(element: IrElement) { - element.acceptChildrenVoid(this) - } - - override fun visitCall(expression: IrCall) { - expression.acceptChildrenVoid(this) + val irBuilder = context.createIrBuilder(container.symbol) + irBody.transformChildrenVoid(object : IrElementTransformerVoid() { + override fun visitCall(expression: IrCall): IrExpression { + expression.transformChildrenVoid(this) val callee = expression.target if (callee != reinterpret && callee.returnType.classifierOrNull is IrTypeParameterSymbol) { - expression.type = callee.returnType.erasure() + val actualType = callee.returnType.erasure() + val expectedType = expression.type + if (actualType != expectedType) { + expression.type = actualType + return when { + expectedType.isUnit() -> irBuilder.at(expression).irImplicitCoercionToUnit(expression) + expectedType.isNothing() -> expression + else -> irBuilder.at(expression).irImplicitCast(expression, expectedType) + } + } } + + return expression } }) } - } \ No newline at end of file