From 2db8471dd79cad1d4408fa0615e32df7df2b365d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Steven=20Sch=C3=A4fer?= Date: Mon, 11 Nov 2019 11:21:18 +0100 Subject: [PATCH] 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. --- .../kotlin/backend/common/ir/IrUtils.kt | 5 +-- .../common/lower/loops/ProgressionHandlers.kt | 2 +- .../kotlin/backend/jvm/JvmSymbols.kt | 41 +++++++++---------- .../jvm/descriptors/SharedVariablesManager.kt | 2 +- .../backend/jvm/lower/AssertionLowering.kt | 8 +--- .../jvm/lower/CallableReferenceLowering.kt | 12 +++--- .../org/jetbrains/kotlin/ir/types/irTypes.kt | 11 +++++ 7 files changed, 44 insertions(+), 37 deletions(-) diff --git a/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/ir/IrUtils.kt b/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/ir/IrUtils.kt index e8df6e3614a..1604272804c 100644 --- a/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/ir/IrUtils.kt +++ b/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/ir/IrUtils.kt @@ -8,7 +8,6 @@ package org.jetbrains.kotlin.backend.common.ir import org.jetbrains.kotlin.backend.common.CommonBackendContext import org.jetbrains.kotlin.backend.common.DumpIrTreeWithDescriptorsVisitor 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.Modality import org.jetbrains.kotlin.descriptors.Visibilities @@ -369,7 +368,7 @@ fun IrClass.createImplicitParameterDeclarationWithWrappedDescriptor() { IrValueParameterSymbolImpl(thisReceiverDescriptor), Name.identifier(""), index = -1, - type = this.symbol.typeWith(this.typeParameters.map { it.defaultType }), + type = symbol.typeWithParameters(typeParameters), varargElementType = null, isCrossinline = false, isNoinline = false @@ -407,7 +406,7 @@ fun IrClass.createParameterDeclarations() { IrValueParameterSymbolImpl(it), Name.special(""), 0, - symbol.typeWith(typeParameters.map { it.defaultType }), + symbol.typeWithParameters(typeParameters), null, false, false diff --git a/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/lower/loops/ProgressionHandlers.kt b/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/lower/loops/ProgressionHandlers.kt index 1fcc27f30e9..7294e6ae88f 100644 --- a/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/lower/loops/ProgressionHandlers.kt +++ b/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/lower/loops/ProgressionHandlers.kt @@ -228,7 +228,7 @@ internal class StepHandler( private val symbols = context.ir.symbols 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() } } diff --git a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/JvmSymbols.kt b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/JvmSymbols.kt index 5248276365c..91ab7dc6191 100644 --- a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/JvmSymbols.kt +++ b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/JvmSymbols.kt @@ -235,7 +235,7 @@ class JvmSymbols( } val suspendLambdaClass: IrClassSymbol = createClass(FqName("kotlin.coroutines.jvm.internal.SuspendLambda")) { klass -> - klass.superTypes += suspendFunctionInterface.typeWith() + klass.superTypes += suspendFunctionInterface.owner.defaultType klass.addConstructor().apply { addValueParameter("arity", irBuiltIns.intType) addValueParameter("completion", continuationClass.typeWith(irBuiltIns.anyNType).makeNullable()) @@ -255,7 +255,7 @@ class JvmSymbols( private fun generateCallableReferenceMethods(klass: IrClass) { klass.addFunction("getSignature", 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 -> @@ -339,7 +339,7 @@ class JvmSymbols( createClass(FqName("kotlin.jvm.internal.$className")) { klass -> if (impl) { klass.addConstructor().apply { - addValueParameter("owner", irBuiltIns.kDeclarationContainerClass.typeWith()) + addValueParameter("owner", irBuiltIns.kDeclarationContainerClass.owner.defaultType) addValueParameter("name", irBuiltIns.stringType) addValueParameter("string", irBuiltIns.stringType) } @@ -396,29 +396,27 @@ class JvmSymbols( propertyReferenceClasses(PropertyReferenceKey(mutable, parameterCount, impl)) 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 - // at declaration site at kotlin.jvm.internal.Reflection. - val rawJavaLangClass = javaLangClass.typeWith() - val rawKClass = irBuiltIns.kClassClass.typeWith() + val javaLangClassType = javaLangClass.starProjectedType + val kClassType = irBuiltIns.kClassClass.starProjectedType - klass.addFunction("getOrCreateKotlinPackage", irBuiltIns.kDeclarationContainerClass.typeWith(), isStatic = true).apply { - addValueParameter("javaClass", rawJavaLangClass) + klass.addFunction("getOrCreateKotlinPackage", irBuiltIns.kDeclarationContainerClass.owner.defaultType, isStatic = true).apply { + addValueParameter("javaClass", javaLangClassType) addValueParameter("moduleName", irBuiltIns.stringType) } - klass.addFunction("getOrCreateKotlinClass", rawKClass, isStatic = true).apply { - addValueParameter("javaClass", rawJavaLangClass) + klass.addFunction("getOrCreateKotlinClass", kClassType, isStatic = true).apply { + addValueParameter("javaClass", javaLangClassType) } - klass.addFunction("getOrCreateKotlinClasses", irBuiltIns.arrayClass.typeWith(rawKClass), isStatic = true).apply { - addValueParameter("javaClasses", irBuiltIns.arrayClass.typeWith(rawJavaLangClass)) + klass.addFunction("getOrCreateKotlinClasses", irBuiltIns.arrayClass.typeWith(kClassType), isStatic = true).apply { + addValueParameter("javaClasses", irBuiltIns.arrayClass.typeWith(javaLangClassType)) } for (mutable in listOf(false, true)) { for (n in 0..2) { val functionName = (if (mutable) "mutableProperty" else "property") + n - klass.addFunction(functionName, irBuiltIns.getKPropertyClass(mutable, n).typeWith(), isStatic = true).apply { - addValueParameter("p", getPropertyReferenceClass(mutable, n, impl = false).typeWith()) + klass.addFunction(functionName, irBuiltIns.getKPropertyClass(mutable, n).starProjectedType, isStatic = true).apply { + addValueParameter("p", getPropertyReferenceClass(mutable, n, impl = false).owner.defaultType) } } } @@ -459,14 +457,15 @@ class JvmSymbols( klass.origin = JvmLoweredDeclarationOrigin.TO_ARRAY val arrayType = irBuiltIns.arrayClass.typeWith(irBuiltIns.anyNType) + val collectionType = irBuiltIns.collectionClass.starProjectedType klass.addFunction("toArray", arrayType, isStatic = true).apply { 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 { origin = JvmLoweredDeclarationOrigin.TO_ARRAY - addValueParameter("collection", irBuiltIns.collectionClass.owner.typeWith(), JvmLoweredDeclarationOrigin.TO_ARRAY) - addValueParameter("array", arrayType, JvmLoweredDeclarationOrigin.TO_ARRAY) + addValueParameter("collection", collectionType, JvmLoweredDeclarationOrigin.TO_ARRAY) + addValueParameter("array", arrayType.makeNullable(), JvmLoweredDeclarationOrigin.TO_ARRAY) } } @@ -482,8 +481,8 @@ class JvmSymbols( }.apply { parent = kotlinJvmPackage addGetter().apply { - addExtensionReceiver(irBuiltIns.kClassClass.typeWith()) - returnType = javaLangClass.typeWith() + addExtensionReceiver(irBuiltIns.kClassClass.starProjectedType) + returnType = javaLangClass.starProjectedType } }.symbol @@ -525,7 +524,7 @@ class JvmSymbols( addValueParameter("element", irType) } - klass.addFunction("toArray", irBuiltIns.primitiveArrayForType.getValue(irType).owner.typeWith()) + klass.addFunction("toArray", irBuiltIns.primitiveArrayForType.getValue(irType).owner.defaultType) } } diff --git a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/descriptors/SharedVariablesManager.kt b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/descriptors/SharedVariablesManager.kt index 5cf37246b3f..7b96fdca095 100644 --- a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/descriptors/SharedVariablesManager.kt +++ b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/descriptors/SharedVariablesManager.kt @@ -153,7 +153,7 @@ class JvmSharedVariablesManager( 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 = diff --git a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/lower/AssertionLowering.kt b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/lower/AssertionLowering.kt index 6f9f594ab60..9aa5b120953 100644 --- a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/lower/AssertionLowering.kt +++ b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/lower/AssertionLowering.kt @@ -27,11 +27,7 @@ import org.jetbrains.kotlin.ir.expressions.IrCall import org.jetbrains.kotlin.ir.expressions.IrExpression import org.jetbrains.kotlin.ir.expressions.impl.IrCompositeImpl import org.jetbrains.kotlin.ir.types.getClass -import org.jetbrains.kotlin.ir.types.typeWith -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.util.* import org.jetbrains.kotlin.ir.visitors.IrElementTransformer import org.jetbrains.kotlin.name.Name 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) = with(CallableReferenceLowering) { - javaClassReference(irClass.typeWith(), backendContext) + javaClassReference(irClass.defaultType, backendContext) } fun IrClass.buildAssertionsDisabledField(backendContext: JvmBackendContext, topLevelClass: IrClass) = diff --git a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/lower/CallableReferenceLowering.kt b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/lower/CallableReferenceLowering.kt index 2fbc01b59a2..67bc5e31adf 100644 --- a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/lower/CallableReferenceLowering.kt +++ b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/lower/CallableReferenceLowering.kt @@ -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.jvm.JvmBackendContext 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.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.Visibilities import org.jetbrains.kotlin.ir.IrStatement @@ -126,7 +128,7 @@ internal class CallableReferenceLowering(private val context: JvmBackendContext) private val superMethod = functionSuperClass.functions.single { it.owner.modality == Modality.ABSTRACT } 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 { setSourceRange(irFunctionReference) @@ -140,7 +142,7 @@ internal class CallableReferenceLowering(private val context: JvmBackendContext) superTypes += superType if (samSuperType == null) superTypes += functionSuperClass.typeWith(parameterTypes) - if (irFunctionReference.isSuspend) superTypes += context.ir.symbols.suspendFunctionInterface.typeWith() + if (irFunctionReference.isSuspend) superTypes += context.ir.symbols.suspendFunctionInterface.owner.defaultType createImplicitParameterDeclarationWithWrappedDescriptor() copyAttributes(irFunctionReference) } @@ -358,11 +360,11 @@ internal class CallableReferenceLowering(private val context: JvmBackendContext) companion object { private fun IrBuilderWithScope.kClassReference(classType: IrType) = 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) = - 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 } diff --git a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/types/irTypes.kt b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/types/irTypes.kt index e827c970327..7b8b0ed846e 100644 --- a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/types/irTypes.kt +++ b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/types/irTypes.kt @@ -104,6 +104,17 @@ val IrTypeParameter.defaultType: IrType annotations = emptyList() ) +val IrClassSymbol.starProjectedType: IrSimpleType + get() = IrSimpleTypeImpl( + this, + hasQuestionMark = false, + arguments = owner.typeParameters.map { IrStarProjectionImpl }, + annotations = emptyList() + ) + +fun IrClassifierSymbol.typeWithParameters(parameters: List): IrSimpleType = + typeWith(parameters.map { it.defaultType }) + fun IrClassifierSymbol.typeWith(vararg arguments: IrType): IrSimpleType = typeWith(arguments.toList()) fun IrClassifierSymbol.typeWith(arguments: List): IrSimpleType =