Rework nullability in IR
This commit is contained in:
+2
-1
@@ -25,6 +25,7 @@ import org.jetbrains.kotlin.ir.symbols.IrSimpleFunctionSymbol
|
||||
import org.jetbrains.kotlin.ir.symbols.IrSymbol
|
||||
import org.jetbrains.kotlin.ir.symbols.impl.*
|
||||
import org.jetbrains.kotlin.ir.types.IrType
|
||||
import org.jetbrains.kotlin.ir.types.SimpleTypeNullability
|
||||
import org.jetbrains.kotlin.ir.types.classOrNull
|
||||
import org.jetbrains.kotlin.ir.types.defaultType
|
||||
import org.jetbrains.kotlin.ir.types.impl.*
|
||||
@@ -289,7 +290,7 @@ internal class BuiltInFictitiousFunctionIrClassFactory(
|
||||
val kotlinType = wrapped.unwrap()
|
||||
return with(IrSimpleTypeBuilder()) {
|
||||
classifier = symbolTable.referenceClassifier(kotlinType.constructor.declarationDescriptor ?: error("No classifier for type $kotlinType"))
|
||||
hasQuestionMark = kotlinType.isMarkedNullable
|
||||
nullability = SimpleTypeNullability.fromHasQuestionMark(kotlinType.isMarkedNullable)
|
||||
arguments = kotlinType.arguments.map {
|
||||
if (it.isStarProjection) IrStarProjectionImpl
|
||||
else makeTypeProjection(toIrType(it.type), it.projectionKind)
|
||||
|
||||
+4
-6
@@ -23,9 +23,8 @@ import org.jetbrains.kotlin.name.FqName
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
|
||||
internal fun IrType.isCEnumType(): Boolean {
|
||||
val simpleType = this as? IrSimpleType ?: return false
|
||||
if (simpleType.hasQuestionMark) return false
|
||||
val enumClass = simpleType.classifier.owner as? IrClass ?: return false
|
||||
if (isNullable()) return false
|
||||
val enumClass = classOrNull?.owner ?: return false
|
||||
if (!enumClass.isEnumClass) return false
|
||||
|
||||
return enumClass.superTypes
|
||||
@@ -53,11 +52,10 @@ internal fun IrSimpleFunction.objCReturnsRetained() = hasCCallAnnotation("Return
|
||||
internal fun IrClass.getCStructSpelling(): String? =
|
||||
getAnnotationArgumentValue(FqName("kotlinx.cinterop.internal.CStruct"), "spelling")
|
||||
|
||||
internal fun IrType.isTypeOfNullLiteral(): Boolean = this is IrSimpleType && hasQuestionMark
|
||||
&& classifier.isClassWithFqName(StandardNames.FqNames.nothing)
|
||||
internal fun IrType.isTypeOfNullLiteral(): Boolean = isNullableNothing()
|
||||
|
||||
internal fun IrType.isVector(): Boolean {
|
||||
if (this is IrSimpleType && !this.hasQuestionMark) {
|
||||
if (this is IrSimpleType && !this.isNullable()) {
|
||||
return classifier.isClassWithFqName(KonanFqNames.Vector128.toUnsafe())
|
||||
}
|
||||
return false
|
||||
|
||||
+1
-2
@@ -1515,8 +1515,7 @@ internal class CodeGeneratorVisitor(val context: Context, val lifetimes: Map<IrE
|
||||
!this.isChar()
|
||||
}
|
||||
|
||||
private fun IrType.isUnsignedInteger(): Boolean =
|
||||
this is IrSimpleType && !this.hasQuestionMark &&
|
||||
private fun IrType.isUnsignedInteger(): Boolean = !isNullable() &&
|
||||
UnsignedType.values().any { it.classId == this.getClass()?.descriptor?.classId }
|
||||
|
||||
private fun evaluateIntegerCoercion(value: IrTypeOperatorCall): LLVMValueRef {
|
||||
|
||||
+2
-2
@@ -16,8 +16,8 @@ import org.jetbrains.kotlin.ir.declarations.IrFunction
|
||||
import org.jetbrains.kotlin.ir.expressions.IrCall
|
||||
import org.jetbrains.kotlin.ir.expressions.IrExpression
|
||||
import org.jetbrains.kotlin.ir.types.classifierOrFail
|
||||
import org.jetbrains.kotlin.ir.types.isNullable
|
||||
import org.jetbrains.kotlin.ir.util.irCall
|
||||
import org.jetbrains.kotlin.ir.util.isSimpleTypeWithQuestionMark
|
||||
import org.jetbrains.kotlin.ir.visitors.IrElementTransformer
|
||||
|
||||
internal class DataClassOperatorsLowering(val context: Context) : FileLoweringPass, IrElementTransformer<IrFunction?> {
|
||||
@@ -56,7 +56,7 @@ internal class DataClassOperatorsLowering(val context: Context) : FileLoweringPa
|
||||
// TODO: use more precise type arguments.
|
||||
val typeArguments = (0 until newCallee.typeParameters.size).map { irBuiltins.anyNType }
|
||||
|
||||
if (!argument.type.isSimpleTypeWithQuestionMark) {
|
||||
if (!argument.type.isNullable()) {
|
||||
irCall(newCallee, typeArguments).apply {
|
||||
extensionReceiver = argument
|
||||
}
|
||||
|
||||
+3
-2
@@ -1114,8 +1114,9 @@ private class InteropTransformer(val context: Context, override val irFile: IrFi
|
||||
val receiverType = expression.symbol.owner.extensionReceiverParameter!!.type
|
||||
val source = receiverType.classifierOrFail as IrClassSymbol
|
||||
require(source in integerClasses) { renderCompilerError(expression) }
|
||||
require(typeOperand is IrSimpleType && typeOperand.classifier in integerClasses
|
||||
&& !typeOperand.hasQuestionMark) { renderCompilerError(expression) }
|
||||
require(typeOperand is IrSimpleType && !typeOperand.isNullable() && typeOperand.classifier in integerClasses) {
|
||||
renderCompilerError(expression)
|
||||
}
|
||||
|
||||
val target = typeOperand.classifier as IrClassSymbol
|
||||
val valueToConvert = expression.extensionReceiver!!
|
||||
|
||||
+1
-1
@@ -71,7 +71,7 @@ internal class KTypeGenerator(
|
||||
return irKTypeImpl(
|
||||
kClassifier = kClassifier,
|
||||
irTypeArguments = type.arguments,
|
||||
isMarkedNullable = type.hasQuestionMark,
|
||||
isMarkedNullable = type.isMarkedNullable(),
|
||||
leaveReifiedForLater = leaveReifiedForLater,
|
||||
seenTypeParameters = seenTypeParameters,
|
||||
type = type,
|
||||
|
||||
+2
-2
@@ -16,8 +16,8 @@ import org.jetbrains.kotlin.ir.declarations.IrFile
|
||||
import org.jetbrains.kotlin.ir.declarations.IrFunction
|
||||
import org.jetbrains.kotlin.ir.expressions.*
|
||||
import org.jetbrains.kotlin.ir.expressions.impl.IrBlockBodyImpl
|
||||
import org.jetbrains.kotlin.ir.types.isNullable
|
||||
import org.jetbrains.kotlin.ir.types.isNullableNothing
|
||||
import org.jetbrains.kotlin.ir.util.isSimpleTypeWithQuestionMark
|
||||
import org.jetbrains.kotlin.ir.visitors.IrElementVisitorVoid
|
||||
import org.jetbrains.kotlin.ir.visitors.acceptChildrenVoid
|
||||
import org.jetbrains.kotlin.ir.visitors.acceptVoid
|
||||
@@ -39,7 +39,7 @@ internal class ReturnsInsertionLowering(val context: Context) : FileLoweringPass
|
||||
context.createIrBuilder(declaration.symbol, declaration.endOffset, declaration.endOffset).run {
|
||||
if (declaration is IrConstructor || declaration.returnType == context.irBuiltIns.unitType) {
|
||||
body.statements += irReturn(irGetObject(symbols.unit))
|
||||
} else if (declaration.returnType.isSimpleTypeWithQuestionMark) {
|
||||
} else if (declaration.returnType.isNullable()) {
|
||||
// this is a workaround for KT-42832
|
||||
val typeOperatorCall = body.statements.lastOrNull() as? IrTypeOperatorCall
|
||||
if (typeOperatorCall?.operator == IrTypeOperator.IMPLICIT_COERCION_TO_UNIT
|
||||
|
||||
+1
-1
@@ -34,7 +34,7 @@ internal class SamSuperTypesChecker(private val context: Context,
|
||||
if (this !is IrSimpleType) return this
|
||||
return buildSimpleType {
|
||||
this.classifier = this@eraseProjections.classifier
|
||||
this.hasQuestionMark = this@eraseProjections.hasQuestionMark
|
||||
this.nullability = this@eraseProjections.nullability
|
||||
this.annotations = this@eraseProjections.annotations
|
||||
this.arguments = this@eraseProjections.arguments.mapIndexed { index, argument ->
|
||||
if (argument !is IrTypeProjection)
|
||||
|
||||
+1
-1
@@ -452,7 +452,7 @@ private class BackendChecker(val context: Context, val irFile: IrFile) : IrEleme
|
||||
val typeOperand = expression.getTypeArgument(0)!!
|
||||
val receiverType = expression.symbol.owner.extensionReceiverParameter!!.type
|
||||
|
||||
if (typeOperand !is IrSimpleType || typeOperand.classifier !in integerClasses || typeOperand.hasQuestionMark)
|
||||
if (typeOperand !is IrSimpleType || typeOperand.classifier !in integerClasses || typeOperand.isNullable())
|
||||
reportError(expression, "unable to convert ${receiverType.toKotlinType()} to ${typeOperand.toKotlinType()}")
|
||||
}
|
||||
IntrinsicType.WORKER_EXECUTE -> {
|
||||
|
||||
+3
-7
@@ -22,7 +22,6 @@ import org.jetbrains.kotlin.ir.visitors.transformChildrenVoid
|
||||
|
||||
// TODO: Similar to IrType.erasedUpperBound from jvm.ir
|
||||
internal fun IrType.erasure(): IrType {
|
||||
if (this is IrDefinitelyNotNullType) return this.original.erasure().makeNotNull()
|
||||
if (this !is IrSimpleType) return this
|
||||
|
||||
val upperBound = when (val classifier = classifier) {
|
||||
@@ -40,10 +39,7 @@ internal fun IrType.erasure(): IrType {
|
||||
else -> TODO(classifier.toString())
|
||||
}
|
||||
|
||||
return if (this.hasQuestionMark)
|
||||
upperBound.makeNullable()
|
||||
else
|
||||
upperBound
|
||||
return upperBound.mergeNullability(this)
|
||||
}
|
||||
|
||||
internal val IrType.erasedUpperBound get() = this.erasure().getClass() ?: error(this.render())
|
||||
@@ -72,7 +68,7 @@ internal class TypeOperatorLowering(val context: CommonBackendContext) : FileLow
|
||||
type = expression.type,
|
||||
condition = irEqeqeq(irGet(argument.owner), irNull()),
|
||||
|
||||
thenPart = if (typeOperand.isSimpleTypeWithQuestionMark)
|
||||
thenPart = if (typeOperand.isNullable())
|
||||
irNull()
|
||||
else
|
||||
irCall(this@TypeOperatorLowering.context.ir.symbols.throwNullPointerException.owner),
|
||||
@@ -83,7 +79,7 @@ internal class TypeOperatorLowering(val context: CommonBackendContext) : FileLow
|
||||
}
|
||||
}
|
||||
|
||||
typeOperand.isSimpleTypeWithQuestionMark -> builder.irAs(expression.argument, typeOperand.makeNotNull())
|
||||
typeOperand.isMarkedNullable() -> builder.irAs(expression.argument, typeOperand.makeNotNull())
|
||||
|
||||
typeOperand == expression.typeOperand -> expression
|
||||
|
||||
|
||||
+2
-7
@@ -192,9 +192,7 @@ fun IrType.substitute(map: Map<IrTypeParameterSymbol, IrType>): IrType {
|
||||
val classifier = this.classifier
|
||||
return when (classifier) {
|
||||
is IrTypeParameterSymbol ->
|
||||
map[classifier]?.let { if (this.hasQuestionMark) it.makeNullable() else it }
|
||||
?: this
|
||||
|
||||
map[classifier]?.mergeNullability(this) ?: this
|
||||
is IrClassSymbol -> if (this.arguments.isEmpty()) {
|
||||
this // Fast path.
|
||||
} else {
|
||||
@@ -205,7 +203,7 @@ fun IrType.substitute(map: Map<IrTypeParameterSymbol, IrType>): IrType {
|
||||
else -> error(it)
|
||||
}
|
||||
}
|
||||
IrSimpleTypeImpl(classifier, hasQuestionMark, newArguments, annotations)
|
||||
IrSimpleTypeImpl(classifier, nullability, newArguments, annotations)
|
||||
}
|
||||
else -> error(classifier)
|
||||
}
|
||||
@@ -368,9 +366,6 @@ fun IrValueParameter.copy(newDescriptor: ParameterDescriptor): IrValueParameter
|
||||
)
|
||||
}
|
||||
|
||||
val IrType.isSimpleTypeWithQuestionMark: Boolean
|
||||
get() = this is IrSimpleType && this.hasQuestionMark
|
||||
|
||||
fun IrClass.defaultOrNullableType(hasQuestionMark: Boolean) =
|
||||
if (hasQuestionMark) this.defaultType.makeNullable() else this.defaultType
|
||||
|
||||
|
||||
Reference in New Issue
Block a user