IR: add BackendContext.typeSystem and JvmIrTypeSystemContext

To be able to override JVM-specific behavior of IrTypeSystemContext in
JVM IR, for things like JVM flexible types.
This commit is contained in:
Alexander Udalov
2021-06-30 22:54:37 +02:00
parent ae07127f08
commit 2834c22a85
36 changed files with 140 additions and 91 deletions
@@ -19,15 +19,16 @@ package org.jetbrains.kotlin.backend.common
import org.jetbrains.kotlin.backend.common.ir.Ir
import org.jetbrains.kotlin.backend.common.ir.SharedVariablesManager
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
import org.jetbrains.kotlin.ir.declarations.IrClass
import org.jetbrains.kotlin.ir.declarations.IrFactory
import org.jetbrains.kotlin.ir.descriptors.IrBuiltIns
import org.jetbrains.kotlin.ir.types.IrTypeSystemContext
import org.jetbrains.kotlin.name.FqName
interface BackendContext {
val ir: Ir<CommonBackendContext>
val builtIns: KotlinBuiltIns
val irBuiltIns: IrBuiltIns
val typeSystem: IrTypeSystemContext
val sharedVariablesManager: SharedVariablesManager
val internalPackageFqn: FqName
val irFactory: IrFactory
@@ -479,8 +479,8 @@ private class FakeOverrideBuilderForLowerings : FakeOverrideBuilderStrategy() {
}
}
fun IrClass.addFakeOverrides(irBuiltIns: IrBuiltIns, implementedMembers: List<IrOverridableMember> = emptyList()) {
IrOverridingUtil(irBuiltIns, FakeOverrideBuilderForLowerings())
fun IrClass.addFakeOverrides(typeSystem: IrTypeSystemContext, implementedMembers: List<IrOverridableMember> = emptyList()) {
IrOverridingUtil(typeSystem, FakeOverrideBuilderForLowerings())
.buildFakeOverridesForClassUsingOverriddenSymbols(this, implementedMembers, compatibilityMode = false)
.forEach { addChild(it) }
}
@@ -407,7 +407,7 @@ abstract class AbstractSuspendFunctionsLowering<C : CommonBackendContext>(val co
}
coroutineClass.superTypes += superTypes
coroutineClass.addFakeOverrides(context.irBuiltIns)
coroutineClass.addFakeOverrides(context.typeSystem)
initializeStateMachine(coroutineConstructors, coroutineClassThis)
@@ -13,9 +13,9 @@ import org.jetbrains.kotlin.backend.common.ir.addFakeOverrides
import org.jetbrains.kotlin.backend.common.ir.copyTo
import org.jetbrains.kotlin.backend.common.ir.createImplicitParameterDeclarationWithWrappedDescriptor
import org.jetbrains.kotlin.descriptors.ClassKind
import org.jetbrains.kotlin.descriptors.Modality
import org.jetbrains.kotlin.descriptors.DescriptorVisibilities
import org.jetbrains.kotlin.descriptors.DescriptorVisibility
import org.jetbrains.kotlin.descriptors.Modality
import org.jetbrains.kotlin.ir.IrElement
import org.jetbrains.kotlin.ir.IrStatement
import org.jetbrains.kotlin.ir.builders.*
@@ -32,7 +32,6 @@ import org.jetbrains.kotlin.ir.types.*
import org.jetbrains.kotlin.ir.util.*
import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.util.OperatorNameConventions
import org.jetbrains.kotlin.ir.util.functions
abstract class SingleAbstractMethodLowering(val context: CommonBackendContext) : FileLoweringPass, IrElementTransformerVoidWithContext() {
// SAM wrappers are cached, either in the file class (if it exists), or in a top-level enclosing class.
@@ -234,7 +233,7 @@ abstract class SingleAbstractMethodLowering(val context: CommonBackendContext) :
if (superType.needEqualsHashCodeMethods)
generateEqualsHashCode(subclass, superType, field)
subclass.addFakeOverrides(context.irBuiltIns)
subclass.addFakeOverrides(context.typeSystem)
return subclass
}
@@ -12,7 +12,10 @@ import org.jetbrains.kotlin.backend.common.lower.createIrBuilder
import org.jetbrains.kotlin.backend.common.phaser.makeIrFilePhase
import org.jetbrains.kotlin.ir.IrElement
import org.jetbrains.kotlin.ir.IrStatement
import org.jetbrains.kotlin.ir.declarations.*
import org.jetbrains.kotlin.ir.declarations.IrDeclaration
import org.jetbrains.kotlin.ir.declarations.IrDeclarationOrigin
import org.jetbrains.kotlin.ir.declarations.IrSymbolOwner
import org.jetbrains.kotlin.ir.declarations.IrVariable
import org.jetbrains.kotlin.ir.expressions.*
import org.jetbrains.kotlin.ir.expressions.impl.IrCompositeImpl
import org.jetbrains.kotlin.ir.util.dump
@@ -236,7 +239,7 @@ private class RangeLoopTransformer(
mainLoopVariable.endOffset,
context.irBuiltIns.unitType,
IrStatementOrigin.FOR_LOOP_NEXT,
loopHeader.initializeIteration(mainLoopVariable, loopVariableComponents, this)
loopHeader.initializeIteration(mainLoopVariable, loopVariableComponents, this, this@RangeLoopTransformer.context)
)
}
@@ -48,7 +48,8 @@ internal interface ForLoopHeader {
fun initializeIteration(
loopVariable: IrVariable?,
loopVariableComponents: Map<Int, IrVariable>,
builder: DeclarationIrBuilder
builder: DeclarationIrBuilder,
backendContext: CommonBackendContext,
): List<IrStatement>
/** Builds a new loop from the old loop. */
@@ -273,8 +274,9 @@ internal class ProgressionLoopHeader(
override fun initializeIteration(
loopVariable: IrVariable?,
loopVariableComponents: Map<Int, IrVariable>,
builder: DeclarationIrBuilder
) =
builder: DeclarationIrBuilder,
backendContext: CommonBackendContext,
): List<IrStatement> =
with(builder) {
// loopVariable is used in the loop condition if it can overflow. If no loopVariable was provided, create one.
this@ProgressionLoopHeader.loopVariable = if (headerInfo.canOverflow && loopVariable == null) {
@@ -377,8 +379,9 @@ internal class IndexedGetLoopHeader(
override fun initializeIteration(
loopVariable: IrVariable?,
loopVariableComponents: Map<Int, IrVariable>,
builder: DeclarationIrBuilder
) =
builder: DeclarationIrBuilder,
backendContext: CommonBackendContext,
): List<IrStatement> =
with(builder) {
// loopVariable = objectVariable[inductionVariable]
val indexedGetFun = with(headerInfo.expressionHandler) { headerInfo.objectVariable.type.getFunction }
@@ -483,8 +486,9 @@ internal class WithIndexLoopHeader(
override fun initializeIteration(
loopVariable: IrVariable?,
loopVariableComponents: Map<Int, IrVariable>,
builder: DeclarationIrBuilder
) =
builder: DeclarationIrBuilder,
backendContext: CommonBackendContext,
): List<IrStatement> =
with(builder) {
// The `withIndex()` extension function returns a lazy Iterable that wraps each element of the underlying iterable (e.g., array,
// progression, Iterable, Sequence, CharSequence) into an IndexedValue containing the index of that element and the element
@@ -553,7 +557,7 @@ internal class WithIndexLoopHeader(
// We "wire" the 1st destructured component to index, and the 2nd to the loop variable value from the underlying iterable.
loopVariableComponents[1]?.initializer = irGet(indexVariable)
listOfNotNull(loopVariableComponents[1], incrementIndexStatement) +
nestedLoopHeader.initializeIteration(loopVariableComponents[2], linkedMapOf(), builder)
nestedLoopHeader.initializeIteration(loopVariableComponents[2], linkedMapOf(), builder, backendContext)
}
// Use the nested loop header to build the loop. More info in comments in initializeIteration().
@@ -571,7 +575,8 @@ internal class IterableLoopHeader(
override fun initializeIteration(
loopVariable: IrVariable?,
loopVariableComponents: Map<Int, IrVariable>,
builder: DeclarationIrBuilder
builder: DeclarationIrBuilder,
backendContext: CommonBackendContext,
): List<IrStatement> =
with(builder) {
// loopVariable = iteratorVar.next()
@@ -586,7 +591,7 @@ internal class IterableLoopHeader(
// Find and replace the call to preserve any type-casts.
loopVariable?.initializer = loopVariable?.initializer?.transform(InitializerCallReplacer(next), null)
// Even if there is no loop variable, we always want to call `next()` for iterables and sequences.
listOf(loopVariable ?: next.coerceToUnitIfNeeded(next.type, context.irBuiltIns))
listOf(loopVariable ?: next.coerceToUnitIfNeeded(next.type, context.irBuiltIns, backendContext.typeSystem))
}
override fun buildLoop(builder: DeclarationIrBuilder, oldLoop: IrLoop, newBody: IrExpression?): LoopReplacement = with(builder) {
@@ -10,27 +10,40 @@ import org.jetbrains.kotlin.backend.common.ir.Ir
import org.jetbrains.kotlin.backend.common.ir.Symbols
import org.jetbrains.kotlin.builtins.PrimitiveType
import org.jetbrains.kotlin.config.CompilerConfiguration
import org.jetbrains.kotlin.descriptors.*
import org.jetbrains.kotlin.descriptors.ClassDescriptor
import org.jetbrains.kotlin.descriptors.ModuleDescriptor
import org.jetbrains.kotlin.descriptors.PropertyDescriptor
import org.jetbrains.kotlin.descriptors.SimpleFunctionDescriptor
import org.jetbrains.kotlin.descriptors.impl.EmptyPackageFragmentDescriptor
import org.jetbrains.kotlin.incremental.components.NoLookupLocation
import org.jetbrains.kotlin.ir.*
import org.jetbrains.kotlin.ir.IrElement
import org.jetbrains.kotlin.ir.IrFileEntry
import org.jetbrains.kotlin.ir.SourceRangeInfo
import org.jetbrains.kotlin.ir.UNDEFINED_OFFSET
import org.jetbrains.kotlin.ir.backend.js.ir.JsIrBuilder
import org.jetbrains.kotlin.ir.backend.js.lower.JsInnerClassesSupport
import org.jetbrains.kotlin.ir.backend.js.utils.*
import org.jetbrains.kotlin.ir.backend.js.utils.JsInlineClassesUtils
import org.jetbrains.kotlin.ir.backend.js.utils.OperatorNames
import org.jetbrains.kotlin.ir.builders.declarations.addFunction
import org.jetbrains.kotlin.ir.declarations.*
import org.jetbrains.kotlin.ir.declarations.impl.IrExternalPackageFragmentImpl
import org.jetbrains.kotlin.ir.declarations.impl.IrFileImpl
import org.jetbrains.kotlin.ir.descriptors.IrBuiltIns
import org.jetbrains.kotlin.ir.expressions.IrCall
import org.jetbrains.kotlin.ir.symbols.*
import org.jetbrains.kotlin.ir.symbols.IrClassSymbol
import org.jetbrains.kotlin.ir.symbols.IrClassifierSymbol
import org.jetbrains.kotlin.ir.symbols.IrFileSymbol
import org.jetbrains.kotlin.ir.symbols.IrSimpleFunctionSymbol
import org.jetbrains.kotlin.ir.symbols.impl.DescriptorlessExternalPackageFragmentSymbol
import org.jetbrains.kotlin.ir.types.*
import org.jetbrains.kotlin.ir.types.impl.IrDynamicTypeImpl
import org.jetbrains.kotlin.ir.util.*
import org.jetbrains.kotlin.js.config.RuntimeDiagnostic
import org.jetbrains.kotlin.ir.util.SymbolTable
import org.jetbrains.kotlin.ir.util.getPropertyGetter
import org.jetbrains.kotlin.ir.util.getPropertySetter
import org.jetbrains.kotlin.ir.util.kotlinPackageFqn
import org.jetbrains.kotlin.js.config.ErrorTolerancePolicy
import org.jetbrains.kotlin.js.config.JSConfigurationKeys
import org.jetbrains.kotlin.js.config.RuntimeDiagnostic
import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.resolve.scopes.MemberScope
@@ -58,6 +71,7 @@ class JsIrBackendContext(
val extractedLocalClasses: MutableSet<IrClass> = hashSetOf()
override val builtIns = module.builtIns
override val typeSystem: IrTypeSystemContext = IrTypeSystemContextImpl(irBuiltIns)
override val irFactory: IrFactory = symbolTable.irFactory
@@ -394,4 +408,4 @@ class JsIrBackendContext(
// TODO: investigate if it could be removed
fun <T> lazy2(fn: () -> T) = lazy { irFactory.stageController.withInitialIr(fn) }
}
}
@@ -8,8 +8,8 @@ package org.jetbrains.kotlin.ir.backend.js.lower.coroutines
import org.jetbrains.kotlin.backend.common.*
import org.jetbrains.kotlin.backend.common.ir.*
import org.jetbrains.kotlin.backend.common.lower.createIrBuilder
import org.jetbrains.kotlin.descriptors.Modality
import org.jetbrains.kotlin.descriptors.DescriptorVisibilities
import org.jetbrains.kotlin.descriptors.Modality
import org.jetbrains.kotlin.ir.IrElement
import org.jetbrains.kotlin.ir.backend.js.lower.CallableReferenceLowering
import org.jetbrains.kotlin.ir.builders.*
@@ -437,7 +437,7 @@ abstract class AbstractSuspendFunctionsLowering<C : CommonBackendContext>(val co
coroutineClass.superTypes += coroutineBaseClass.defaultType
}
coroutineClass.addFakeOverrides(context.irBuiltIns, implementedMembers)
coroutineClass.addFakeOverrides(context.typeSystem, implementedMembers)
// TODO constructing fake overrides on lowered declaration is tricky.
coroutineClass.declarations.transformFlat {
@@ -91,7 +91,7 @@ open class JvmIrCodegenFactory(
val irLinker = JvmIrLinker(
psi2irContext.moduleDescriptor,
messageLogger,
psi2irContext.irBuiltIns,
JvmIrTypeSystemContext(psi2irContext.irBuiltIns),
symbolTable,
functionFactory,
frontEndContext,
@@ -35,6 +35,7 @@ import org.jetbrains.kotlin.ir.expressions.IrExpression
import org.jetbrains.kotlin.ir.expressions.IrFunctionReference
import org.jetbrains.kotlin.ir.symbols.*
import org.jetbrains.kotlin.ir.types.IrType
import org.jetbrains.kotlin.ir.types.IrTypeSystemContext
import org.jetbrains.kotlin.ir.types.defaultType
import org.jetbrains.kotlin.ir.util.SymbolTable
import org.jetbrains.kotlin.name.FqName
@@ -62,6 +63,7 @@ class JvmBackendContext(
override val scriptMode: Boolean = false
override val builtIns = state.module.builtIns
override val typeSystem: IrTypeSystemContext = JvmIrTypeSystemContext(irBuiltIns)
val typeMapper = IrTypeMapper(this)
val methodSignatureMapper = MethodSignatureMapper(this)
@@ -0,0 +1,11 @@
/*
* Copyright 2010-2021 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/
package org.jetbrains.kotlin.backend.jvm
import org.jetbrains.kotlin.ir.descriptors.IrBuiltIns
import org.jetbrains.kotlin.ir.types.IrTypeSystemContext
class JvmIrTypeSystemContext(override val irBuiltIns: IrBuiltIns) : IrTypeSystemContext
@@ -1443,7 +1443,7 @@ class ExpressionCodegen(
val reifiedTypeInliner = ReifiedTypeInliner(
mappings,
IrInlineIntrinsicsSupport(context, typeMapper),
IrTypeSystemContextImpl(context.irBuiltIns),
context.typeSystem,
state.languageVersionSettings,
state.unifiedNullChecks,
)
@@ -40,7 +40,7 @@ import org.jetbrains.kotlin.ir.types.isKClass as isKClassImpl
import org.jetbrains.kotlin.ir.util.isSuspendFunction as isSuspendFunctionImpl
class IrTypeMapper(private val context: JvmBackendContext) : KotlinTypeMapperBase(), TypeMappingContext<JvmSignatureWriter> {
override val typeSystem: IrTypeSystemContext = IrTypeSystemContextImpl(context.irBuiltIns)
override val typeSystem: IrTypeSystemContext = context.typeSystem
override val typeContext: TypeSystemCommonBackendContextForTypeMapping = IrTypeCheckerContextForTypeMapping(typeSystem, context)
override fun mapClass(classifier: ClassifierDescriptor): Type =
@@ -219,10 +219,8 @@ fun IrDeclaration.isInCurrentModule(): Boolean =
// "not learned through smartcasting".
fun IrExpression.isSmartcastFromHigherThanNullable(context: JvmBackendContext): Boolean {
return when (this) {
is IrTypeOperatorCall -> operator == IrTypeOperator.IMPLICIT_CAST && !argument.type.isSubtypeOf(
type.makeNullable(),
context.irBuiltIns
)
is IrTypeOperatorCall ->
operator == IrTypeOperator.IMPLICIT_CAST && !argument.type.isSubtypeOf(type.makeNullable(), context.typeSystem)
is IrGetValue -> {
// Check if the variable initializer is smartcast. In FIR, if the subject of a `when` is smartcast,
// the IMPLICIT_CAST is in the initializer of the variable for the subject.
@@ -231,7 +231,7 @@ internal class CollectionStubMethodLowering(val context: JvmBackendContext) : Cl
private fun createTypeChecker(overrideFun: IrSimpleFunction, parentFun: IrSimpleFunction): AbstractTypeCheckerContext =
IrTypeCheckerContext(
IrTypeSystemContextWithAdditionalAxioms(
context.irBuiltIns,
context.typeSystem,
overrideFun.typeParameters,
parentFun.typeParameters
)
@@ -522,7 +522,7 @@ internal class FunctionReferenceLowering(private val context: JvmBackendContext)
generateSamEqualsHashCodeMethods(boundReceiverVar)
}
if (isKotlinFunInterface) {
functionReferenceClass.addFakeOverrides(context.irBuiltIns)
functionReferenceClass.addFakeOverrides(backendContext.typeSystem)
}
+functionReferenceClass
@@ -845,5 +845,3 @@ internal class FunctionReferenceLowering(private val context: JvmBackendContext)
declaration.parent.let { it is IrClass && it.isFileClass }
}
}
@@ -280,7 +280,7 @@ class JvmOptimizationLowering(val context: JvmBackendContext) : FileLoweringPass
return context.createIrBuilder(expression.symbol, expression.startOffset, expression.endOffset).irBlock(expression) {
if (backingField.isStatic && receiver != null) {
// If the field is static, evaluate the receiver for potential side effects.
+receiver.coerceToUnit(context.irBuiltIns)
+receiver.coerceToUnit(context.irBuiltIns, this@JvmOptimizationLowering.context.typeSystem)
}
if (accessor.valueParameters.size > 0) {
+irSetField(
@@ -126,7 +126,7 @@ class JvmPropertiesLowering(private val backendContext: JvmBackendContext) : IrE
private fun IrBuilderWithScope.patchReceiver(expression: IrFieldAccessExpression): IrExpression =
if (expression.symbol.owner.isStatic && expression.receiver != null) {
irBlock {
+expression.receiver!!.coerceToUnit(context.irBuiltIns)
+expression.receiver!!.coerceToUnit(context.irBuiltIns, backendContext.typeSystem)
expression.receiver = null
+expression
}
@@ -30,7 +30,10 @@ import org.jetbrains.kotlin.ir.symbols.IrFunctionSymbol
import org.jetbrains.kotlin.ir.symbols.IrSimpleFunctionSymbol
import org.jetbrains.kotlin.ir.symbols.IrTypeParameterSymbol
import org.jetbrains.kotlin.ir.types.*
import org.jetbrains.kotlin.ir.util.*
import org.jetbrains.kotlin.ir.util.defaultType
import org.jetbrains.kotlin.ir.util.dump
import org.jetbrains.kotlin.ir.util.parentAsClass
import org.jetbrains.kotlin.ir.util.render
import org.jetbrains.kotlin.ir.visitors.IrElementVisitorVoid
import org.jetbrains.kotlin.ir.visitors.acceptChildrenVoid
import org.jetbrains.kotlin.ir.visitors.acceptVoid
@@ -360,7 +363,11 @@ private class TypeOperatorLowering(private val context: JvmBackendContext) : Fil
irComposite(resultType = expression.type) {
+expression.argument.transformVoid()
// TODO: Don't generate these casts in the first place
if (!expression.argument.type.isSubtypeOf(expression.type.makeNullable(), context.irBuiltIns)) {
if (!expression.argument.type.isSubtypeOf(
expression.type.makeNullable(),
this@TypeOperatorLowering.context.typeSystem
)
) {
+IrCompositeImpl(UNDEFINED_OFFSET, UNDEFINED_OFFSET, expression.type)
}
}
@@ -13,16 +13,24 @@ import org.jetbrains.kotlin.backend.wasm.utils.WasmInlineClassesUtils
import org.jetbrains.kotlin.config.CompilerConfiguration
import org.jetbrains.kotlin.descriptors.ModuleDescriptor
import org.jetbrains.kotlin.descriptors.impl.EmptyPackageFragmentDescriptor
import org.jetbrains.kotlin.ir.*
import org.jetbrains.kotlin.ir.IrElement
import org.jetbrains.kotlin.ir.IrFileEntry
import org.jetbrains.kotlin.ir.SourceRangeInfo
import org.jetbrains.kotlin.ir.UNDEFINED_OFFSET
import org.jetbrains.kotlin.ir.backend.js.JsCommonBackendContext
import org.jetbrains.kotlin.ir.backend.js.JsMapping
import org.jetbrains.kotlin.ir.backend.js.lower.JsInnerClassesSupport
import org.jetbrains.kotlin.ir.builders.declarations.buildFun
import org.jetbrains.kotlin.ir.declarations.*
import org.jetbrains.kotlin.ir.declarations.IrFactory
import org.jetbrains.kotlin.ir.declarations.IrFile
import org.jetbrains.kotlin.ir.declarations.IrModuleFragment
import org.jetbrains.kotlin.ir.declarations.IrPackageFragment
import org.jetbrains.kotlin.ir.declarations.impl.IrExternalPackageFragmentImpl
import org.jetbrains.kotlin.ir.declarations.impl.IrFileImpl
import org.jetbrains.kotlin.ir.descriptors.IrBuiltIns
import org.jetbrains.kotlin.ir.symbols.impl.DescriptorlessExternalPackageFragmentSymbol
import org.jetbrains.kotlin.ir.types.IrTypeSystemContext
import org.jetbrains.kotlin.ir.types.IrTypeSystemContextImpl
import org.jetbrains.kotlin.ir.util.SymbolTable
import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.name.Name
@@ -36,6 +44,7 @@ class WasmBackendContext(
override val configuration: CompilerConfiguration,
) : JsCommonBackendContext {
override val builtIns = module.builtIns
override val typeSystem: IrTypeSystemContext = IrTypeSystemContextImpl(irBuiltIns)
override var inVerbosePhase: Boolean = false
override val scriptMode = false
override val irFactory: IrFactory = symbolTable.irFactory
@@ -15,7 +15,6 @@ import org.jetbrains.kotlin.ir.backend.js.utils.realOverrideTarget
import org.jetbrains.kotlin.ir.builders.irImplicitCast
import org.jetbrains.kotlin.ir.declarations.IrFile
import org.jetbrains.kotlin.ir.declarations.IrSimpleFunction
import org.jetbrains.kotlin.ir.declarations.IrTypeParameter
import org.jetbrains.kotlin.ir.expressions.IrCall
import org.jetbrains.kotlin.ir.expressions.IrExpression
import org.jetbrains.kotlin.ir.symbols.IrSymbol
@@ -62,7 +61,7 @@ class GenericReturnTypeLowering(val context: WasmBackendContext) : FileLoweringP
if (erasedReturnType != call.type) {
if (callType.isNothing()) return call
if (erasedReturnType.isSubtypeOf(callType, context.irBuiltIns)) return call
if (erasedReturnType.isSubtypeOf(callType, context.typeSystem)) return call
// Erase type parameter from call return type
val newCall = irCall(
@@ -83,4 +82,4 @@ class GenericReturnTypeLowering(val context: WasmBackendContext) : FileLoweringP
}
return call
}
}
}
@@ -17,7 +17,10 @@ import org.jetbrains.kotlin.backend.wasm.ir2wasm.erasedUpperBound
import org.jetbrains.kotlin.ir.builders.*
import org.jetbrains.kotlin.ir.declarations.IrFile
import org.jetbrains.kotlin.ir.declarations.IrTypeParameter
import org.jetbrains.kotlin.ir.expressions.*
import org.jetbrains.kotlin.ir.expressions.IrConst
import org.jetbrains.kotlin.ir.expressions.IrExpression
import org.jetbrains.kotlin.ir.expressions.IrTypeOperator
import org.jetbrains.kotlin.ir.expressions.IrTypeOperatorCall
import org.jetbrains.kotlin.ir.types.*
import org.jetbrains.kotlin.ir.util.*
import org.jetbrains.kotlin.ir.visitors.transformChildrenVoid
@@ -94,7 +97,7 @@ class WasmBaseTypeOperatorTransformer(val context: WasmBackendContext) : IrEleme
// Inlined values have no type information on runtime.
// But since they are final we can compute type checks on compile time.
if (fromType.isInlined()) {
val result = fromType.erasedType.isSubtypeOf(toType.erasedType, builtIns)
val result = fromType.erasedType.isSubtypeOf(toType.erasedType, context.typeSystem)
return builder.irBoolean(result)
}
@@ -173,7 +176,7 @@ class WasmBaseTypeOperatorTransformer(val context: WasmBackendContext) : IrEleme
}
}
if (fromType.erasedType.isSubtypeOf(toType.erasedType, context.irBuiltIns)) {
if (fromType.erasedType.isSubtypeOf(toType.erasedType, context.typeSystem)) {
return value
}
if (toType.isNothing()) {
@@ -213,7 +216,7 @@ class WasmBaseTypeOperatorTransformer(val context: WasmBackendContext) : IrEleme
val toType = expression.typeOperand
val fromType = expression.argument.type
if (fromType.erasedType.isSubtypeOf(expression.type.erasedType, context.irBuiltIns)) {
if (fromType.erasedType.isSubtypeOf(expression.type.erasedType, context.typeSystem)) {
return narrowType(fromType, expression.type, expression.argument)
}
@@ -10,7 +10,6 @@ import org.jetbrains.kotlin.descriptors.DescriptorVisibilities
import org.jetbrains.kotlin.descriptors.DescriptorVisibility
import org.jetbrains.kotlin.descriptors.Modality
import org.jetbrains.kotlin.ir.declarations.*
import org.jetbrains.kotlin.ir.descriptors.IrBuiltIns
import org.jetbrains.kotlin.ir.symbols.*
import org.jetbrains.kotlin.ir.types.*
import org.jetbrains.kotlin.ir.util.collectAndFilterRealOverrides
@@ -98,7 +97,7 @@ fun buildFakeOverrideMember(superType: IrType, member: IrOverridableMember, claz
// to use abstract overridable member interfaces.
class IrOverridingUtil(
private val irBuiltIns: IrBuiltIns,
private val typeSystem: IrTypeSystemContext,
private val fakeOverrideBuilder: FakeOverrideBuilderStrategy
) {
private val originals = mutableMapOf<IrOverridableMember, IrOverridableMember>()
@@ -446,7 +445,7 @@ class IrOverridingUtil(
AbstractTypeChecker.equalTypes(this as AbstractTypeCheckerContext, a, b)
private fun createTypeChecker(a: List<IrTypeParameter>, b: List<IrTypeParameter>) =
IrTypeCheckerContext(IrTypeSystemContextWithAdditionalAxioms(irBuiltIns, a, b))
IrTypeCheckerContext(IrTypeSystemContextWithAdditionalAxioms(typeSystem, a, b))
private fun isReturnTypeMoreSpecific(
a: IrOverridableMember,
@@ -677,7 +676,7 @@ class IrOverridingUtil(
val typeCheckerContext =
IrTypeCheckerContext(
IrTypeSystemContextWithAdditionalAxioms(
irBuiltIns,
typeSystem,
superTypeParameters,
subTypeParameters
)
@@ -6,14 +6,13 @@
package org.jetbrains.kotlin.ir.types
import org.jetbrains.kotlin.ir.declarations.IrTypeParameter
import org.jetbrains.kotlin.ir.descriptors.IrBuiltIns
import org.jetbrains.kotlin.types.model.TypeConstructorMarker
class IrTypeSystemContextWithAdditionalAxioms(
override val irBuiltIns: IrBuiltIns,
typeSystem: IrTypeSystemContext,
firstParameters: List<IrTypeParameter>,
secondParameters: List<IrTypeParameter>
) : IrTypeSystemContext {
) : IrTypeSystemContext by typeSystem {
init {
assert(firstParameters.size == secondParameters.size) {
"different length of type parameter lists: $firstParameters vs $secondParameters"
@@ -29,4 +28,4 @@ class IrTypeSystemContextWithAdditionalAxioms(
if (matchingTypeConstructors[c1] == c2 || matchingTypeConstructors[c2] == c1) return true
return false
}
}
}
@@ -13,7 +13,6 @@ import org.jetbrains.kotlin.ir.symbols.IrClassifierSymbol
import org.jetbrains.kotlin.ir.symbols.IrTypeParameterSymbol
import org.jetbrains.kotlin.ir.util.fqNameWhenAvailable
import org.jetbrains.kotlin.types.AbstractTypeChecker
import org.jetbrains.kotlin.types.AbstractTypeCheckerContext
fun IrClassifierSymbol.superTypes(): List<IrType> = when (this) {
is IrClassSymbol -> owner.superTypes
@@ -30,13 +29,8 @@ fun IrClassifierSymbol.isStrictSubtypeOfClass(superClass: IrClassSymbol): Boolea
fun IrType.isSubtypeOfClass(superClass: IrClassSymbol): Boolean =
this is IrSimpleType && classifier.isSubtypeOfClass(superClass)
fun IrType.isSubtypeOf(superType: IrType, irBuiltIns: IrBuiltIns): Boolean {
return AbstractTypeChecker.isSubtypeOf(
IrTypeCheckerContext(IrTypeSystemContextImpl(irBuiltIns)) as AbstractTypeCheckerContext,
this,
superType
)
}
fun IrType.isSubtypeOf(superType: IrType, typeSystem: IrTypeSystemContext): Boolean =
AbstractTypeChecker.isSubtypeOf(IrTypeCheckerContext(typeSystem), this, superType)
fun IrType.isNullable(): Boolean =
when (this) {
@@ -154,12 +154,12 @@ fun IrExpression.isFalseConst() = this is IrConst<*> && this.kind == IrConstKind
fun IrExpression.isIntegerConst(value: Int) = this is IrConst<*> && this.kind == IrConstKind.Int && this.value == value
fun IrExpression.coerceToUnit(builtins: IrBuiltIns): IrExpression {
return coerceToUnitIfNeeded(type, builtins)
fun IrExpression.coerceToUnit(builtins: IrBuiltIns, typeSystem: IrTypeSystemContext): IrExpression {
return coerceToUnitIfNeeded(type, builtins, typeSystem)
}
fun IrExpression.coerceToUnitIfNeeded(valueType: IrType, irBuiltIns: IrBuiltIns): IrExpression {
return if (valueType.isSubtypeOf(irBuiltIns.unitType, irBuiltIns))
fun IrExpression.coerceToUnitIfNeeded(valueType: IrType, irBuiltIns: IrBuiltIns, typeSystem: IrTypeSystemContext): IrExpression {
return if (valueType.isSubtypeOf(irBuiltIns.unitType, typeSystem))
this
else
IrTypeOperatorCallImpl(
@@ -28,6 +28,7 @@ import org.jetbrains.kotlin.ir.overrides.IrOverridingUtil
import org.jetbrains.kotlin.ir.symbols.IrPropertySymbol
import org.jetbrains.kotlin.ir.symbols.IrSimpleFunctionSymbol
import org.jetbrains.kotlin.ir.symbols.impl.IrPropertySymbolImpl
import org.jetbrains.kotlin.ir.types.IrTypeSystemContext
import org.jetbrains.kotlin.ir.types.getClass
import org.jetbrains.kotlin.ir.util.IdSignature
import org.jetbrains.kotlin.ir.util.KotlinMangler
@@ -69,12 +70,12 @@ class FakeOverrideBuilder(
val linker: FileLocalAwareLinker,
val symbolTable: SymbolTable,
mangler: KotlinMangler.IrMangler,
irBuiltIns: IrBuiltIns,
typeSystem: IrTypeSystemContext,
val platformSpecificClassFilter: FakeOverrideClassFilter = DefaultFakeOverrideClassFilter
) : FakeOverrideBuilderStrategy() {
private val haveFakeOverrides = mutableSetOf<IrClass>()
private val irOverridingUtil = IrOverridingUtil(irBuiltIns, this)
private val irOverridingUtil = IrOverridingUtil(typeSystem, this)
// TODO: The declaration table is needed for the signaturer.
private val fakeOverrideDeclarationTable = FakeOverrideDeclarationTable(mangler)
@@ -7,13 +7,12 @@ package org.jetbrains.kotlin.ir.backend.js.lower.serialization.ir
import org.jetbrains.kotlin.backend.common.overrides.FakeOverrideBuilder
import org.jetbrains.kotlin.backend.common.serialization.*
import org.jetbrains.kotlin.backend.common.serialization.signature.IdSignatureSerializer
import org.jetbrains.kotlin.backend.common.serialization.signature.PublicIdSignatureComputer
import org.jetbrains.kotlin.descriptors.ModuleDescriptor
import org.jetbrains.kotlin.ir.builders.TranslationPluginContext
import org.jetbrains.kotlin.ir.declarations.IrModuleFragment
import org.jetbrains.kotlin.ir.descriptors.IrAbstractFunctionFactory
import org.jetbrains.kotlin.ir.descriptors.IrBuiltIns
import org.jetbrains.kotlin.ir.types.IrTypeSystemContextImpl
import org.jetbrains.kotlin.ir.util.IrMessageLogger
import org.jetbrains.kotlin.ir.util.ReferenceSymbolTable
import org.jetbrains.kotlin.ir.util.SymbolTable
@@ -30,7 +29,7 @@ class JsIrLinker(
private val icData: ICData? = null
) : KotlinIrLinker(currentModule, messageLogger, builtIns, symbolTable, emptyList()) {
override val fakeOverrideBuilder = FakeOverrideBuilder(this, symbolTable, JsManglerIr, builtIns)
override val fakeOverrideBuilder = FakeOverrideBuilder(this, symbolTable, JsManglerIr, IrTypeSystemContextImpl(builtIns))
override fun isBuiltInModule(moduleDescriptor: ModuleDescriptor): Boolean =
moduleDescriptor === moduleDescriptor.builtIns.builtInsModule
@@ -8,8 +8,6 @@ package org.jetbrains.kotlin.ir.backend.jvm.serialization
import org.jetbrains.kotlin.backend.common.overrides.FakeOverrideBuilder
import org.jetbrains.kotlin.backend.common.serialization.*
import org.jetbrains.kotlin.backend.common.serialization.encodings.BinarySymbolData
import org.jetbrains.kotlin.backend.common.serialization.signature.IdSignatureSerializer
import org.jetbrains.kotlin.backend.common.serialization.signature.PublicIdSignatureComputer
import org.jetbrains.kotlin.descriptors.*
import org.jetbrains.kotlin.descriptors.konan.KlibModuleOrigin
import org.jetbrains.kotlin.ir.ObsoleteDescriptorBasedAPI
@@ -18,9 +16,9 @@ import org.jetbrains.kotlin.ir.declarations.IrField
import org.jetbrains.kotlin.ir.declarations.IrModuleFragment
import org.jetbrains.kotlin.ir.declarations.impl.IrModuleFragmentImpl
import org.jetbrains.kotlin.ir.descriptors.IrAbstractFunctionFactory
import org.jetbrains.kotlin.ir.descriptors.IrBuiltIns
import org.jetbrains.kotlin.ir.symbols.IrFieldSymbol
import org.jetbrains.kotlin.ir.symbols.IrSymbol
import org.jetbrains.kotlin.ir.types.IrTypeSystemContext
import org.jetbrains.kotlin.ir.util.DeclarationStubGenerator
import org.jetbrains.kotlin.ir.util.IdSignature
import org.jetbrains.kotlin.ir.util.IrMessageLogger
@@ -37,15 +35,15 @@ import org.jetbrains.kotlin.name.Name
class JvmIrLinker(
currentModule: ModuleDescriptor?,
messageLogger: IrMessageLogger,
builtIns: IrBuiltIns,
typeSystem: IrTypeSystemContext,
symbolTable: SymbolTable,
override val functionalInterfaceFactory: IrAbstractFunctionFactory,
override val translationPluginContext: TranslationPluginContext?,
private val stubGenerator: DeclarationStubGenerator,
private val manglerDesc: JvmManglerDesc
) : KotlinIrLinker(currentModule, messageLogger, builtIns, symbolTable, emptyList()) {
) : KotlinIrLinker(currentModule, messageLogger, typeSystem.irBuiltIns, symbolTable, emptyList()) {
override val fakeOverrideBuilder = FakeOverrideBuilder(this, symbolTable, JvmManglerIr, builtIns)
override val fakeOverrideBuilder = FakeOverrideBuilder(this, symbolTable, JvmManglerIr, typeSystem)
private val javaName = Name.identifier("java")
@@ -24,6 +24,8 @@ import org.jetbrains.kotlin.ir.declarations.*
import org.jetbrains.kotlin.ir.declarations.impl.IrFieldImpl
import org.jetbrains.kotlin.ir.declarations.impl.IrFunctionImpl
import org.jetbrains.kotlin.ir.util.*
import org.jetbrains.kotlin.ir.types.IrTypeSystemContext
import org.jetbrains.kotlin.ir.types.IrTypeSystemContextImpl
import org.jetbrains.kotlin.builtins.konan.KonanBuiltIns
import org.jetbrains.kotlin.cli.jvm.compiler.KotlinCoreEnvironment
import org.jetbrains.kotlin.ir.symbols.impl.IrSimpleFunctionSymbolImpl
@@ -330,6 +332,9 @@ internal class Context(config: KonanConfig) : KonanBackendContext(config) {
override val irBuiltIns
get() = ir.irModule.irBuiltins
override val typeSystem: IrTypeSystemContext
get() = IrTypeSystemContextImpl(irBuiltIns)
val interopBuiltIns by lazy {
InteropBuiltIns(this.builtIns)
}
@@ -13,7 +13,6 @@ import org.jetbrains.kotlin.backend.konan.descriptors.synthesizedName
import org.jetbrains.kotlin.descriptors.ClassKind
import org.jetbrains.kotlin.descriptors.DescriptorVisibilities
import org.jetbrains.kotlin.descriptors.Modality
import org.jetbrains.kotlin.ir.UNDEFINED_OFFSET
import org.jetbrains.kotlin.ir.builders.declarations.buildFun
import org.jetbrains.kotlin.ir.builders.irBlockBody
import org.jetbrains.kotlin.ir.builders.irCall
@@ -32,9 +31,11 @@ import org.jetbrains.kotlin.ir.symbols.impl.IrFieldSymbolImpl
import org.jetbrains.kotlin.ir.symbols.impl.IrSimpleFunctionSymbolImpl
import org.jetbrains.kotlin.ir.types.IrType
import org.jetbrains.kotlin.ir.types.typeWith
import org.jetbrains.kotlin.ir.util.*
import org.jetbrains.kotlin.ir.util.constructors
import org.jetbrains.kotlin.ir.util.defaultType
import org.jetbrains.kotlin.ir.util.functions
import org.jetbrains.kotlin.ir.util.module
import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.resolve.descriptorUtil.module
internal object DECLARATION_ORIGIN_ENUM : IrDeclarationOriginImpl("ENUM")
@@ -203,7 +204,7 @@ internal class EnumSpecialDeclarationsFactory(val context: Context) {
)
implObject.superTypes += context.irBuiltIns.anyType
implObject.addFakeOverrides(context.irBuiltIns)
implObject.addFakeOverrides(context.typeSystem)
val itemGetterSymbol = findItemGetterSymbol()
val enumEntriesMap = enumEntriesMap(enumClass)
@@ -45,6 +45,7 @@ import org.jetbrains.kotlin.util.OperatorNameConventions
internal interface KotlinStubs {
val irBuiltIns: IrBuiltIns
val typeSystem: IrTypeSystemContext
val symbols: KonanSymbols
val target: KonanTarget
val language: String
@@ -1221,7 +1222,7 @@ private class ObjCBlockPointerValuePassing(
+irReturn(callBlock(blockPointer, arguments))
}
irClass.addFakeOverrides(stubs.irBuiltIns)
irClass.addFakeOverrides(stubs.typeSystem)
stubs.addKotlin(irClass)
return constructor
@@ -294,7 +294,7 @@ internal class FunctionReferenceLowering(val context: Context): FileLoweringPass
functionReferenceClass.superTypes += superTypes
functionReferenceClass.addFakeOverrides(context.irBuiltIns)
functionReferenceClass.addFakeOverrides(context.typeSystem)
return BuiltFunctionReference(functionReferenceClass, buildConstructor())
}
@@ -80,6 +80,7 @@ private abstract class BaseInteropIrTransformer(private val context: Context) :
return object : KotlinStubs {
override val irBuiltIns get() = context.irBuiltIns
override val symbols get() = context.ir.symbols
override val typeSystem: IrTypeSystemContext get() = context.typeSystem
val klib: KonanLibrary? get() {
return (element as? IrCall)?.symbol?.owner?.konanLibrary as? KonanLibrary
@@ -518,7 +518,7 @@ internal class TestProcessor (val context: Context) {
companionGetter?.let { declarations += it }
superTypes += symbols.baseClassSuite.typeWith(listOf(testClassType, testCompanionType))
addFakeOverrides(context.irBuiltIns)
addFakeOverrides(context.typeSystem)
}
//endregion
@@ -37,6 +37,7 @@ import org.jetbrains.kotlin.ir.descriptors.IrAbstractFunctionFactory
import org.jetbrains.kotlin.ir.descriptors.IrBuiltIns
import org.jetbrains.kotlin.ir.symbols.IrSymbol
import org.jetbrains.kotlin.ir.symbols.impl.IrPublicSymbolBase
import org.jetbrains.kotlin.ir.types.IrTypeSystemContextImpl
import org.jetbrains.kotlin.ir.types.classOrNull
import org.jetbrains.kotlin.ir.util.*
import org.jetbrains.kotlin.ir.visitors.IrElementTransformer
@@ -91,7 +92,8 @@ internal class KonanIrLinker(
override fun isBuiltInModule(moduleDescriptor: ModuleDescriptor): Boolean = moduleDescriptor.isNativeStdlib()
private val forwardDeclarationDeserializer = forwardModuleDescriptor?.let { KonanForwardDeclarationModuleDeserializer(it) }
override val fakeOverrideBuilder = FakeOverrideBuilder(this, symbolTable, KonanManglerIr, builtIns, KonanFakeOverrideClassFilter)
override val fakeOverrideBuilder: FakeOverrideBuilder =
FakeOverrideBuilder(this, symbolTable, KonanManglerIr, IrTypeSystemContextImpl(builtIns), KonanFakeOverrideClassFilter)
override fun createModuleDeserializer(moduleDescriptor: ModuleDescriptor, klib: KotlinLibrary?, strategy: DeserializationStrategy): IrModuleDeserializer {
if (moduleDescriptor === forwardModuleDescriptor) {