IR: Avoid "raw" IrTypes

The ir type checker cannot deal with types with an incorrect number of arguments.
On the other hand, the JVM IR backend sometimes produces "raw types" - types with
generic parameters but without arguments. This commit removes such raw types as
much as possible, by replacing calls to "typeWith()" with calls to "defaultType"
for classes without type parametes (defaultType doesn't allocate, unlike typeWith)
and with calls to "starProjectedType" for classes with type parameters.
This commit is contained in:
Steven Schäfer
2019-11-11 11:21:18 +01:00
committed by Alexander Udalov
parent 4d67803f04
commit 2db8471dd7
7 changed files with 44 additions and 37 deletions
@@ -8,7 +8,6 @@ package org.jetbrains.kotlin.backend.common.ir
import org.jetbrains.kotlin.backend.common.CommonBackendContext import org.jetbrains.kotlin.backend.common.CommonBackendContext
import org.jetbrains.kotlin.backend.common.DumpIrTreeWithDescriptorsVisitor import org.jetbrains.kotlin.backend.common.DumpIrTreeWithDescriptorsVisitor
import org.jetbrains.kotlin.backend.common.deepCopyWithVariables import org.jetbrains.kotlin.backend.common.deepCopyWithVariables
import org.jetbrains.kotlin.backend.common.lower.VariableRemapper
import org.jetbrains.kotlin.descriptors.ClassKind import org.jetbrains.kotlin.descriptors.ClassKind
import org.jetbrains.kotlin.descriptors.Modality import org.jetbrains.kotlin.descriptors.Modality
import org.jetbrains.kotlin.descriptors.Visibilities import org.jetbrains.kotlin.descriptors.Visibilities
@@ -369,7 +368,7 @@ fun IrClass.createImplicitParameterDeclarationWithWrappedDescriptor() {
IrValueParameterSymbolImpl(thisReceiverDescriptor), IrValueParameterSymbolImpl(thisReceiverDescriptor),
Name.identifier("<this>"), Name.identifier("<this>"),
index = -1, index = -1,
type = this.symbol.typeWith(this.typeParameters.map { it.defaultType }), type = symbol.typeWithParameters(typeParameters),
varargElementType = null, varargElementType = null,
isCrossinline = false, isCrossinline = false,
isNoinline = false isNoinline = false
@@ -407,7 +406,7 @@ fun IrClass.createParameterDeclarations() {
IrValueParameterSymbolImpl(it), IrValueParameterSymbolImpl(it),
Name.special("<this>"), Name.special("<this>"),
0, 0,
symbol.typeWith(typeParameters.map { it.defaultType }), symbol.typeWithParameters(typeParameters),
null, null,
false, false,
false false
@@ -228,7 +228,7 @@ internal class StepHandler(
private val symbols = context.ir.symbols private val symbols = context.ir.symbols
override val matcher = SimpleCalleeMatcher { override val matcher = SimpleCalleeMatcher {
singleArgumentExtension(FqName("kotlin.ranges.step"), symbols.progressionClasses.map { it.typeWith() }) singleArgumentExtension(FqName("kotlin.ranges.step"), symbols.progressionClasses.map { it.owner.defaultType })
parameter(0) { it.type.isInt() || it.type.isLong() } parameter(0) { it.type.isInt() || it.type.isLong() }
} }
@@ -235,7 +235,7 @@ class JvmSymbols(
} }
val suspendLambdaClass: IrClassSymbol = createClass(FqName("kotlin.coroutines.jvm.internal.SuspendLambda")) { klass -> val suspendLambdaClass: IrClassSymbol = createClass(FqName("kotlin.coroutines.jvm.internal.SuspendLambda")) { klass ->
klass.superTypes += suspendFunctionInterface.typeWith() klass.superTypes += suspendFunctionInterface.owner.defaultType
klass.addConstructor().apply { klass.addConstructor().apply {
addValueParameter("arity", irBuiltIns.intType) addValueParameter("arity", irBuiltIns.intType)
addValueParameter("completion", continuationClass.typeWith(irBuiltIns.anyNType).makeNullable()) addValueParameter("completion", continuationClass.typeWith(irBuiltIns.anyNType).makeNullable())
@@ -255,7 +255,7 @@ class JvmSymbols(
private fun generateCallableReferenceMethods(klass: IrClass) { private fun generateCallableReferenceMethods(klass: IrClass) {
klass.addFunction("getSignature", irBuiltIns.stringType, Modality.OPEN) klass.addFunction("getSignature", irBuiltIns.stringType, Modality.OPEN)
klass.addFunction("getName", irBuiltIns.stringType, Modality.OPEN) klass.addFunction("getName", irBuiltIns.stringType, Modality.OPEN)
klass.addFunction("getOwner", irBuiltIns.kDeclarationContainerClass.typeWith(), Modality.OPEN) klass.addFunction("getOwner", irBuiltIns.kDeclarationContainerClass.owner.defaultType, Modality.OPEN)
} }
val functionReference: IrClassSymbol = createClass(FqName("kotlin.jvm.internal.FunctionReference")) { klass -> val functionReference: IrClassSymbol = createClass(FqName("kotlin.jvm.internal.FunctionReference")) { klass ->
@@ -339,7 +339,7 @@ class JvmSymbols(
createClass(FqName("kotlin.jvm.internal.$className")) { klass -> createClass(FqName("kotlin.jvm.internal.$className")) { klass ->
if (impl) { if (impl) {
klass.addConstructor().apply { klass.addConstructor().apply {
addValueParameter("owner", irBuiltIns.kDeclarationContainerClass.typeWith()) addValueParameter("owner", irBuiltIns.kDeclarationContainerClass.owner.defaultType)
addValueParameter("name", irBuiltIns.stringType) addValueParameter("name", irBuiltIns.stringType)
addValueParameter("string", irBuiltIns.stringType) addValueParameter("string", irBuiltIns.stringType)
} }
@@ -396,29 +396,27 @@ class JvmSymbols(
propertyReferenceClasses(PropertyReferenceKey(mutable, parameterCount, impl)) propertyReferenceClasses(PropertyReferenceKey(mutable, parameterCount, impl))
val reflection: IrClassSymbol = createClass(FqName("kotlin.jvm.internal.Reflection")) { klass -> val reflection: IrClassSymbol = createClass(FqName("kotlin.jvm.internal.Reflection")) { klass ->
// We use raw types for java.lang.Class and kotlin.reflect.KClass here for simplicity and because this is what's used val javaLangClassType = javaLangClass.starProjectedType
// at declaration site at kotlin.jvm.internal.Reflection. val kClassType = irBuiltIns.kClassClass.starProjectedType
val rawJavaLangClass = javaLangClass.typeWith()
val rawKClass = irBuiltIns.kClassClass.typeWith()
klass.addFunction("getOrCreateKotlinPackage", irBuiltIns.kDeclarationContainerClass.typeWith(), isStatic = true).apply { klass.addFunction("getOrCreateKotlinPackage", irBuiltIns.kDeclarationContainerClass.owner.defaultType, isStatic = true).apply {
addValueParameter("javaClass", rawJavaLangClass) addValueParameter("javaClass", javaLangClassType)
addValueParameter("moduleName", irBuiltIns.stringType) addValueParameter("moduleName", irBuiltIns.stringType)
} }
klass.addFunction("getOrCreateKotlinClass", rawKClass, isStatic = true).apply { klass.addFunction("getOrCreateKotlinClass", kClassType, isStatic = true).apply {
addValueParameter("javaClass", rawJavaLangClass) addValueParameter("javaClass", javaLangClassType)
} }
klass.addFunction("getOrCreateKotlinClasses", irBuiltIns.arrayClass.typeWith(rawKClass), isStatic = true).apply { klass.addFunction("getOrCreateKotlinClasses", irBuiltIns.arrayClass.typeWith(kClassType), isStatic = true).apply {
addValueParameter("javaClasses", irBuiltIns.arrayClass.typeWith(rawJavaLangClass)) addValueParameter("javaClasses", irBuiltIns.arrayClass.typeWith(javaLangClassType))
} }
for (mutable in listOf(false, true)) { for (mutable in listOf(false, true)) {
for (n in 0..2) { for (n in 0..2) {
val functionName = (if (mutable) "mutableProperty" else "property") + n val functionName = (if (mutable) "mutableProperty" else "property") + n
klass.addFunction(functionName, irBuiltIns.getKPropertyClass(mutable, n).typeWith(), isStatic = true).apply { klass.addFunction(functionName, irBuiltIns.getKPropertyClass(mutable, n).starProjectedType, isStatic = true).apply {
addValueParameter("p", getPropertyReferenceClass(mutable, n, impl = false).typeWith()) addValueParameter("p", getPropertyReferenceClass(mutable, n, impl = false).owner.defaultType)
} }
} }
} }
@@ -459,14 +457,15 @@ class JvmSymbols(
klass.origin = JvmLoweredDeclarationOrigin.TO_ARRAY klass.origin = JvmLoweredDeclarationOrigin.TO_ARRAY
val arrayType = irBuiltIns.arrayClass.typeWith(irBuiltIns.anyNType) val arrayType = irBuiltIns.arrayClass.typeWith(irBuiltIns.anyNType)
val collectionType = irBuiltIns.collectionClass.starProjectedType
klass.addFunction("toArray", arrayType, isStatic = true).apply { klass.addFunction("toArray", arrayType, isStatic = true).apply {
origin = JvmLoweredDeclarationOrigin.TO_ARRAY origin = JvmLoweredDeclarationOrigin.TO_ARRAY
addValueParameter("collection", irBuiltIns.collectionClass.owner.typeWith(), JvmLoweredDeclarationOrigin.TO_ARRAY) addValueParameter("collection", collectionType, JvmLoweredDeclarationOrigin.TO_ARRAY)
} }
klass.addFunction("toArray", arrayType, isStatic = true).apply { klass.addFunction("toArray", arrayType, isStatic = true).apply {
origin = JvmLoweredDeclarationOrigin.TO_ARRAY origin = JvmLoweredDeclarationOrigin.TO_ARRAY
addValueParameter("collection", irBuiltIns.collectionClass.owner.typeWith(), JvmLoweredDeclarationOrigin.TO_ARRAY) addValueParameter("collection", collectionType, JvmLoweredDeclarationOrigin.TO_ARRAY)
addValueParameter("array", arrayType, JvmLoweredDeclarationOrigin.TO_ARRAY) addValueParameter("array", arrayType.makeNullable(), JvmLoweredDeclarationOrigin.TO_ARRAY)
} }
} }
@@ -482,8 +481,8 @@ class JvmSymbols(
}.apply { }.apply {
parent = kotlinJvmPackage parent = kotlinJvmPackage
addGetter().apply { addGetter().apply {
addExtensionReceiver(irBuiltIns.kClassClass.typeWith()) addExtensionReceiver(irBuiltIns.kClassClass.starProjectedType)
returnType = javaLangClass.typeWith() returnType = javaLangClass.starProjectedType
} }
}.symbol }.symbol
@@ -525,7 +524,7 @@ class JvmSymbols(
addValueParameter("element", irType) addValueParameter("element", irType)
} }
klass.addFunction("toArray", irBuiltIns.primitiveArrayForType.getValue(irType).owner.typeWith()) klass.addFunction("toArray", irBuiltIns.primitiveArrayForType.getValue(irType).owner.defaultType)
} }
} }
@@ -153,7 +153,7 @@ class JvmSharedVariablesManager(
override val elementType = refClass.typeParameters[0].defaultType override val elementType = refClass.typeParameters[0].defaultType
override fun getRefType(valueType: IrType) = refClass.typeWith(listOf(valueType)) override fun getRefType(valueType: IrType) = refClass.typeWith(valueType)
} }
private fun getProvider(valueType: IrType): RefProvider = private fun getProvider(valueType: IrType): RefProvider =
@@ -27,11 +27,7 @@ import org.jetbrains.kotlin.ir.expressions.IrCall
import org.jetbrains.kotlin.ir.expressions.IrExpression import org.jetbrains.kotlin.ir.expressions.IrExpression
import org.jetbrains.kotlin.ir.expressions.impl.IrCompositeImpl import org.jetbrains.kotlin.ir.expressions.impl.IrCompositeImpl
import org.jetbrains.kotlin.ir.types.getClass import org.jetbrains.kotlin.ir.types.getClass
import org.jetbrains.kotlin.ir.types.typeWith import org.jetbrains.kotlin.ir.util.*
import org.jetbrains.kotlin.ir.util.fields
import org.jetbrains.kotlin.ir.util.functions
import org.jetbrains.kotlin.ir.util.getPackageFragment
import org.jetbrains.kotlin.ir.util.patchDeclarationParents
import org.jetbrains.kotlin.ir.visitors.IrElementTransformer import org.jetbrains.kotlin.ir.visitors.IrElementTransformer
import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.util.OperatorNameConventions import org.jetbrains.kotlin.util.OperatorNameConventions
@@ -141,7 +137,7 @@ private class AssertionLowering(private val context: JvmBackendContext) :
private fun IrBuilderWithScope.getJavaClass(backendContext: JvmBackendContext, irClass: IrClass) = private fun IrBuilderWithScope.getJavaClass(backendContext: JvmBackendContext, irClass: IrClass) =
with(CallableReferenceLowering) { with(CallableReferenceLowering) {
javaClassReference(irClass.typeWith(), backendContext) javaClassReference(irClass.defaultType, backendContext)
} }
fun IrClass.buildAssertionsDisabledField(backendContext: JvmBackendContext, topLevelClass: IrClass) = fun IrClass.buildAssertionsDisabledField(backendContext: JvmBackendContext, topLevelClass: IrClass) =
@@ -14,8 +14,10 @@ import org.jetbrains.kotlin.backend.common.lower.createIrBuilder
import org.jetbrains.kotlin.backend.common.phaser.makeIrFilePhase import org.jetbrains.kotlin.backend.common.phaser.makeIrFilePhase
import org.jetbrains.kotlin.backend.jvm.JvmBackendContext import org.jetbrains.kotlin.backend.jvm.JvmBackendContext
import org.jetbrains.kotlin.backend.jvm.JvmLoweredDeclarationOrigin import org.jetbrains.kotlin.backend.jvm.JvmLoweredDeclarationOrigin
import org.jetbrains.kotlin.backend.jvm.ir.*
import org.jetbrains.kotlin.backend.jvm.ir.IrInlineReferenceLocator import org.jetbrains.kotlin.backend.jvm.ir.IrInlineReferenceLocator
import org.jetbrains.kotlin.backend.jvm.ir.createJvmIrBuilder
import org.jetbrains.kotlin.backend.jvm.ir.irArray
import org.jetbrains.kotlin.backend.jvm.ir.isLambda
import org.jetbrains.kotlin.descriptors.Modality import org.jetbrains.kotlin.descriptors.Modality
import org.jetbrains.kotlin.descriptors.Visibilities import org.jetbrains.kotlin.descriptors.Visibilities
import org.jetbrains.kotlin.ir.IrStatement import org.jetbrains.kotlin.ir.IrStatement
@@ -126,7 +128,7 @@ internal class CallableReferenceLowering(private val context: JvmBackendContext)
private val superMethod = private val superMethod =
functionSuperClass.functions.single { it.owner.modality == Modality.ABSTRACT } functionSuperClass.functions.single { it.owner.modality == Modality.ABSTRACT }
private val superType = private val superType =
samSuperType ?: (if (isLambda) context.ir.symbols.lambdaClass else context.ir.symbols.functionReference).owner.typeWith() samSuperType ?: (if (isLambda) context.ir.symbols.lambdaClass else context.ir.symbols.functionReference).owner.defaultType
private val functionReferenceClass = buildClass { private val functionReferenceClass = buildClass {
setSourceRange(irFunctionReference) setSourceRange(irFunctionReference)
@@ -140,7 +142,7 @@ internal class CallableReferenceLowering(private val context: JvmBackendContext)
superTypes += superType superTypes += superType
if (samSuperType == null) if (samSuperType == null)
superTypes += functionSuperClass.typeWith(parameterTypes) superTypes += functionSuperClass.typeWith(parameterTypes)
if (irFunctionReference.isSuspend) superTypes += context.ir.symbols.suspendFunctionInterface.typeWith() if (irFunctionReference.isSuspend) superTypes += context.ir.symbols.suspendFunctionInterface.owner.defaultType
createImplicitParameterDeclarationWithWrappedDescriptor() createImplicitParameterDeclarationWithWrappedDescriptor()
copyAttributes(irFunctionReference) copyAttributes(irFunctionReference)
} }
@@ -358,11 +360,11 @@ internal class CallableReferenceLowering(private val context: JvmBackendContext)
companion object { companion object {
private fun IrBuilderWithScope.kClassReference(classType: IrType) = private fun IrBuilderWithScope.kClassReference(classType: IrType) =
IrClassReferenceImpl( IrClassReferenceImpl(
startOffset, endOffset, context.irBuiltIns.kClassClass.typeWith(), context.irBuiltIns.kClassClass, classType startOffset, endOffset, context.irBuiltIns.kClassClass.starProjectedType, context.irBuiltIns.kClassClass, classType
) )
private fun IrBuilderWithScope.kClassToJavaClass(kClassReference: IrExpression, context: JvmBackendContext) = private fun IrBuilderWithScope.kClassToJavaClass(kClassReference: IrExpression, context: JvmBackendContext) =
irGet(context.ir.symbols.javaLangClass.typeWith(), null, context.ir.symbols.kClassJava.owner.getter!!.symbol).apply { irGet(context.ir.symbols.javaLangClass.starProjectedType, null, context.ir.symbols.kClassJava.owner.getter!!.symbol).apply {
extensionReceiver = kClassReference extensionReceiver = kClassReference
} }
@@ -104,6 +104,17 @@ val IrTypeParameter.defaultType: IrType
annotations = emptyList() annotations = emptyList()
) )
val IrClassSymbol.starProjectedType: IrSimpleType
get() = IrSimpleTypeImpl(
this,
hasQuestionMark = false,
arguments = owner.typeParameters.map { IrStarProjectionImpl },
annotations = emptyList()
)
fun IrClassifierSymbol.typeWithParameters(parameters: List<IrTypeParameter>): IrSimpleType =
typeWith(parameters.map { it.defaultType })
fun IrClassifierSymbol.typeWith(vararg arguments: IrType): IrSimpleType = typeWith(arguments.toList()) fun IrClassifierSymbol.typeWith(vararg arguments: IrType): IrSimpleType = typeWith(arguments.toList())
fun IrClassifierSymbol.typeWith(arguments: List<IrType>): IrSimpleType = fun IrClassifierSymbol.typeWith(arguments: List<IrType>): IrSimpleType =