backend: support boxing when generics involved
This commit is contained in:
committed by
SvyatoslavScherbina
parent
83bdae5d02
commit
0e6d8c3a7c
+1
-1
@@ -103,7 +103,7 @@ internal fun KonanBuiltIns.getKonanInternalClassOrNull(name: String): ClassDescr
|
|||||||
* @return built-in class `konan.internal.$name`
|
* @return built-in class `konan.internal.$name`
|
||||||
*/
|
*/
|
||||||
internal fun KonanBuiltIns.getKonanInternalClass(name: String): ClassDescriptor =
|
internal fun KonanBuiltIns.getKonanInternalClass(name: String): ClassDescriptor =
|
||||||
getKonanInternalClassOrNull(name)!!
|
getKonanInternalClassOrNull(name) ?: TODO(name)
|
||||||
|
|
||||||
internal fun KonanBuiltIns.getKonanInternalFunctions(name: String): List<FunctionDescriptor> {
|
internal fun KonanBuiltIns.getKonanInternalFunctions(name: String): List<FunctionDescriptor> {
|
||||||
return konanInternal.getContributedFunctions(Name.identifier(name), NoLookupLocation.FROM_BACKEND).toList()
|
return konanInternal.getContributedFunctions(Name.identifier(name), NoLookupLocation.FROM_BACKEND).toList()
|
||||||
|
|||||||
+25
-12
@@ -9,9 +9,7 @@ import org.jetbrains.kotlin.backend.konan.descriptors.unboundCallableReferenceTy
|
|||||||
import org.jetbrains.kotlin.descriptors.ParameterDescriptor
|
import org.jetbrains.kotlin.descriptors.ParameterDescriptor
|
||||||
import org.jetbrains.kotlin.descriptors.PropertyDescriptor
|
import org.jetbrains.kotlin.descriptors.PropertyDescriptor
|
||||||
import org.jetbrains.kotlin.ir.declarations.IrFile
|
import org.jetbrains.kotlin.ir.declarations.IrFile
|
||||||
import org.jetbrains.kotlin.ir.expressions.IrExpression
|
import org.jetbrains.kotlin.ir.expressions.*
|
||||||
import org.jetbrains.kotlin.ir.expressions.IrTypeOperator
|
|
||||||
import org.jetbrains.kotlin.ir.expressions.IrTypeOperatorCall
|
|
||||||
import org.jetbrains.kotlin.ir.expressions.impl.IrCallImpl
|
import org.jetbrains.kotlin.ir.expressions.impl.IrCallImpl
|
||||||
import org.jetbrains.kotlin.ir.expressions.impl.IrTypeOperatorCallImpl
|
import org.jetbrains.kotlin.ir.expressions.impl.IrTypeOperatorCallImpl
|
||||||
import org.jetbrains.kotlin.ir.visitors.transformChildrenVoid
|
import org.jetbrains.kotlin.ir.visitors.transformChildrenVoid
|
||||||
@@ -120,27 +118,42 @@ private class AutoboxingTransformer(val context: Context) : AbstractValueUsageTr
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun IrExpression.useAs(type: KotlinType): IrExpression {
|
override fun IrExpression.useAs(type: KotlinType): IrExpression {
|
||||||
return this.adaptIfNecessary(type)
|
|
||||||
|
val actualType = when (this) {
|
||||||
|
is IrCall -> this.descriptor.original.returnType ?: this.type
|
||||||
|
is IrGetField -> this.descriptor.original.type
|
||||||
|
else -> this.type
|
||||||
|
}
|
||||||
|
|
||||||
|
return this.adaptIfNecessary(actualType, type)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun IrExpression.adaptIfNecessary(expectedType: KotlinType): IrExpression {
|
override fun IrExpression.useAsArgument(parameter: ParameterDescriptor): IrExpression {
|
||||||
val thisRepresentation = getCustomRepresentation(this.type)
|
return this.useAsValue(parameter.original)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun IrExpression.useForField(field: PropertyDescriptor): IrExpression {
|
||||||
|
return this.useForVariable(field.original)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun IrExpression.adaptIfNecessary(actualType: KotlinType, expectedType: KotlinType): IrExpression {
|
||||||
|
val actualRepresentation = getCustomRepresentation(actualType)
|
||||||
val expectedRepresentation = getCustomRepresentation(expectedType)
|
val expectedRepresentation = getCustomRepresentation(expectedType)
|
||||||
|
|
||||||
return when {
|
return when {
|
||||||
thisRepresentation == expectedRepresentation -> this
|
actualRepresentation == expectedRepresentation -> this
|
||||||
|
|
||||||
thisRepresentation == null && expectedRepresentation != null -> {
|
actualRepresentation == null && expectedRepresentation != null -> {
|
||||||
// This may happen in the following cases:
|
// This may happen in the following cases:
|
||||||
// 1. `this.type` is `Nothing`;
|
// 1. `actualType` is `Nothing`;
|
||||||
// 2. `this` has the incompatible type.
|
// 2. `actualType` is incompatible.
|
||||||
|
|
||||||
this.unbox(expectedRepresentation)
|
this.unbox(expectedRepresentation)
|
||||||
}
|
}
|
||||||
|
|
||||||
thisRepresentation != null && expectedRepresentation == null -> this.box(thisRepresentation)
|
actualRepresentation != null && expectedRepresentation == null -> this.box(actualRepresentation)
|
||||||
|
|
||||||
else -> throw IllegalArgumentException("this is ${this.type}, expected $expectedType")
|
else -> throw IllegalArgumentException("actual type is $actualType, expected $expectedType")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user