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 1131b8da8e5..055157ec404 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 @@ -16,6 +16,8 @@ import org.jetbrains.kotlin.descriptors.annotations.Annotations import org.jetbrains.kotlin.ir.IrElement import org.jetbrains.kotlin.ir.UNDEFINED_OFFSET import org.jetbrains.kotlin.ir.builders.Scope +import org.jetbrains.kotlin.ir.builders.declarations.IrTypeParameterBuilder +import org.jetbrains.kotlin.ir.builders.declarations.build import org.jetbrains.kotlin.ir.declarations.* import org.jetbrains.kotlin.ir.declarations.impl.IrConstructorImpl import org.jetbrains.kotlin.ir.declarations.impl.IrFunctionImpl @@ -31,12 +33,12 @@ import org.jetbrains.kotlin.ir.symbols.impl.IrSimpleFunctionSymbolImpl import org.jetbrains.kotlin.ir.symbols.impl.IrTypeParameterSymbolImpl import org.jetbrains.kotlin.ir.symbols.impl.IrValueParameterSymbolImpl import org.jetbrains.kotlin.ir.types.* +import org.jetbrains.kotlin.ir.types.impl.IrSimpleTypeBuilder import org.jetbrains.kotlin.ir.types.impl.IrSimpleTypeImpl +import org.jetbrains.kotlin.ir.types.impl.buildSimpleType import org.jetbrains.kotlin.ir.types.impl.makeTypeProjection import org.jetbrains.kotlin.ir.util.* -import org.jetbrains.kotlin.ir.visitors.IrElementTransformerVoid import org.jetbrains.kotlin.ir.visitors.IrElementVisitor -import org.jetbrains.kotlin.ir.visitors.transformChildrenVoid import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.serialization.deserialization.descriptors.DescriptorWithContainerSource import java.io.StringWriter @@ -121,7 +123,7 @@ val IrClass.isFinalClass: Boolean fun IrCall.getAnnotationClass(): IrClass { val callable = symbol.owner assert(callable is IrConstructor) { "Constructor call expected, got ${ir2string(this)}" } - val annotationClass = callable.parentAsClass + val annotationClass = callable.parentAsClass assert(annotationClass.isAnnotationClass) { "Annotation class expected, got ${ir2string(annotationClass)}" } return annotationClass } @@ -135,9 +137,11 @@ fun IrValueParameter.copyTo( startOffset: Int = this.startOffset, endOffset: Int = this.endOffset, name: Name = this.name, + remapTypeMap: Map = mapOf(), type: IrType = this.type.remapTypeParameters( - (parent as IrTypeParametersContainer).classIfConstructor, - irFunction.classIfConstructor + (parent as IrTypeParametersContainer).classIfConstructor, + irFunction.classIfConstructor, + remapTypeMap ), varargElementType: IrType? = this.varargElementType, // TODO: remapTypeParameters here as well defaultValue: IrExpressionBody? = this.defaultValue, @@ -395,7 +399,8 @@ fun Scope.createTemporaryVariableWithWrappedDescriptor( irExpression: IrExpression, nameHint: String? = null, isMutable: Boolean = false, - origin: IrDeclarationOrigin = IrDeclarationOrigin.IR_TEMPORARY_VARIABLE): IrVariable { + origin: IrDeclarationOrigin = IrDeclarationOrigin.IR_TEMPORARY_VARIABLE +): IrVariable { val descriptor = WrappedVariableDescriptor() return createTemporaryVariableWithGivenDescriptor( @@ -440,7 +445,7 @@ fun IrClass.simpleFunctions() = declarations.flatMap { } fun IrClass.createParameterDeclarations() { - assert (thisReceiver == null) + assert(thisReceiver == null) thisReceiver = WrappedReceiverParameterDescriptor().let { IrValueParameterImpl( @@ -480,8 +485,9 @@ fun IrFunction.createDispatchReceiverParameter(origin: IrDeclarationOrigin? = nu val IrFunction.allParameters: List get() = if (this is IrConstructor) { - listOf(this.constructedClass.thisReceiver - ?: error(this.descriptor) + listOf( + this.constructedClass.thisReceiver + ?: error(this.descriptor) ) + explicitParameters } else { explicitParameters @@ -556,7 +562,8 @@ fun createStaticFunctionWithReceivers( origin: IrDeclarationOrigin = oldFunction.origin, modality: Modality = Modality.FINAL, visibility: Visibility = oldFunction.visibility, - copyMetadata: Boolean = true + copyMetadata: Boolean = true, + typeParametersFromContext: List = listOf() ): IrSimpleFunction { val descriptor = (oldFunction.descriptor as? DescriptorWithContainerSource)?.let { WrappedFunctionDescriptorWithContainerSource(it.containerSource) @@ -580,7 +587,19 @@ fun createStaticFunctionWithReceivers( descriptor.bind(this) parent = irParent - copyTypeParametersFrom(oldFunction) + val newTypeParametersFromContext = copyAndRenameConflictingTypeParametersFrom( + typeParametersFromContext, + oldFunction.typeParameters + ) + val newTypeParametersFromFunction = copyTypeParametersFrom(oldFunction) + val typeParameterMap = + (typeParametersFromContext + oldFunction.typeParameters) + .zip(newTypeParametersFromContext + newTypeParametersFromFunction).toMap() + + fun remap(type: IrType): IrType = + type.remapTypeParameters(oldFunction, this, typeParameterMap) + + typeParameters.forEach { it.superTypes.replaceAll { remap(it) } } annotations.addAll(oldFunction.annotations) @@ -589,22 +608,74 @@ fun createStaticFunctionWithReceivers( this, name = Name.identifier("this"), index = offset++, - type = dispatchReceiverType!!, + type = remap(dispatchReceiverType!!), origin = IrDeclarationOrigin.MOVED_DISPATCH_RECEIVER ) val extensionReceiver = oldFunction.extensionReceiverParameter?.copyTo( this, name = Name.identifier("receiver"), index = offset++, - origin = IrDeclarationOrigin.MOVED_EXTENSION_RECEIVER + origin = IrDeclarationOrigin.MOVED_EXTENSION_RECEIVER, + remapTypeMap = typeParameterMap ) valueParameters.addAll(listOfNotNull(dispatchReceiver, extensionReceiver) + - oldFunction.valueParameters.map { it.copyTo(this, index = it.index + offset) } + oldFunction.valueParameters.map { + it.copyTo( + this, + index = it.index + offset, + remapTypeMap = typeParameterMap + ) + } ) if (copyMetadata) metadata = oldFunction.metadata } } +/** + * Appends the parameters in [contextParameters] to the type parameters of + * [this] function, renaming those that may clash with a provided collection of + * [existingParameters] (e.g. type parameters of the function itself, when + * creating DefaultImpls). + * + * @returns List of newly created, possibly renamed, copies of type parameters + * in order of the corresponding parameters in [context]. + */ +private fun IrSimpleFunction.copyAndRenameConflictingTypeParametersFrom( + contextParameters: List, + existingParameters: Collection +): List { + val newParameters = mutableListOf() + + val existingNames = + (contextParameters.map { it.name.asString() } + existingParameters.map { it.name.asString() }).toMutableSet() + + contextParameters.forEach { contextType -> + val newName = if (existingParameters.any { it.name.asString() == contextType.name.asString() }) { + val newNamePrefix = contextType.name.asString() + "_I" + val newName = newNamePrefix + generateSequence(1) { x -> x + 1 }.first { n -> + (newNamePrefix + n) !in existingNames + } + existingNames.add(newName) + newName + } else { + contextType.name.asString() + } + + val newTypeParameter = IrTypeParameterBuilder().run { + updateFrom(contextType) + name = Name.identifier(newName) + build() + }.also { + it.parent = this + } + + typeParameters.add(newTypeParameter) + newParameters.add(newTypeParameter) + } + + return newParameters +} + val IrSymbol.isSuspend: Boolean get() = this is IrSimpleFunctionSymbol && owner.isSuspend diff --git a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/descriptors/JvmDeclarationFactory.kt b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/descriptors/JvmDeclarationFactory.kt index a5363032531..3ca9ab8363f 100644 --- a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/descriptors/JvmDeclarationFactory.kt +++ b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/descriptors/JvmDeclarationFactory.kt @@ -210,11 +210,14 @@ class JvmDeclarationFactory( }, // Old backend doesn't generate ACC_FINAL on DefaultImpls methods. modality = Modality.OPEN, + // Interface functions are always public, with one exception: clone in Cloneable, which is protected. However, Cloneable // has no DefaultImpls, so this merely replicates the incorrect behavior of the old backend. We should rather not generate // a bridge to clone when interface inherits from Cloneable at all. Below, we force everything, including those bridges, // to be public so that we won't try to generate synthetic accessor for them. - visibility = Visibilities.PUBLIC + visibility = Visibilities.PUBLIC, + + typeParametersFromContext = parent.typeParameters ).also { it.copyAttributes(interfaceFun) } } } diff --git a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/ir/IrUtils.kt b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/ir/IrUtils.kt index 2b37c95f3de..1c585a9f21d 100644 --- a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/ir/IrUtils.kt +++ b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/ir/IrUtils.kt @@ -209,3 +209,51 @@ fun IrBody.replaceThisByStaticReference( return super.visitGetValue(expression) } }, null) + + +// TODO: Interface Parameters +// +// The call sites using this function share that they are calling an +// interface method that has been moved to a DefaultImpls class. In that +// process, the type parameters of the interface are introduced as the first +// parameters to the method. When rewriting calls to point to the new method, +// the instantiation `S,T` of the interface type `I` for the _calling_ +// class `C` gives the proper instantiation fo arguments. +// +// We essentially want to answer the type query: +// +// C <: I +// +// And put that instantiation as the first type parameters to the call, filling +// in whatever type arguments are provided at call the call site for the rest. +// The front-end type checking guarantees this is well-formed. +// +// For now, we put `Any?`. +fun createPlaceholderAnyNType(irBuiltIns: IrBuiltIns): IrType = + irBuiltIns.anyNType + +fun createDelegatingCallWithPlaceholderTypeArguments(existingCall: IrCall, redirectTarget: IrFunction, irBuiltIns: IrBuiltIns): IrCall = + IrCallImpl( + existingCall.startOffset, + existingCall.endOffset, + existingCall.type, + redirectTarget.symbol, + typeArgumentsCount = redirectTarget.typeParameters.size, + valueArgumentsCount = redirectTarget.valueParameters.size, + origin = existingCall.origin + ).apply { + copyValueArgumentsFrom( + existingCall, + existingCall.symbol.owner, + this.symbol.owner, + receiversAsArguments = true, + argumentsAsReceivers = false + ) + var offset = 0 + existingCall.symbol.owner.parentAsClass.typeParameters.forEach { _ -> + putTypeArgument(offset++, createPlaceholderAnyNType(irBuiltIns)) + } + for (i in 0 until (existingCall.typeArgumentsCount)) { + putTypeArgument(i + offset, existingCall.getTypeArgument(i)) + } + } \ No newline at end of file diff --git a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/lower/InheritedDefaultMethodsOnClassesLowering.kt b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/lower/InheritedDefaultMethodsOnClassesLowering.kt index 2ce1fa5ee5f..51c35148ffa 100644 --- a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/lower/InheritedDefaultMethodsOnClassesLowering.kt +++ b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/lower/InheritedDefaultMethodsOnClassesLowering.kt @@ -14,6 +14,8 @@ 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.codegen.isJvmInterface +import org.jetbrains.kotlin.backend.jvm.ir.createDelegatingCallWithPlaceholderTypeArguments +import org.jetbrains.kotlin.backend.jvm.ir.createPlaceholderAnyNType import org.jetbrains.kotlin.backend.jvm.ir.hasJvmDefault import org.jetbrains.kotlin.descriptors.Modality import org.jetbrains.kotlin.descriptors.Visibilities @@ -49,11 +51,11 @@ private class InheritedDefaultMethodsOnClassesLowering(val context: JvmBackendCo element.acceptChildrenVoid(this) } - override fun lower(declaration: IrClass) { - if (!declaration.isJvmInterface) - generateInterfaceMethods(declaration) + override fun lower(irClass: IrClass) { + if (!irClass.isJvmInterface) + generateInterfaceMethods(irClass) - super.visitClass(declaration) + super.visitClass(irClass) } private fun generateInterfaceMethods(irClass: IrClass) { @@ -87,8 +89,12 @@ private class InheritedDefaultMethodsOnClassesLowering(val context: JvmBackendCo irFunction.body = irBlockBody { +irReturn( irCall(defaultImplFun.symbol, irFunction.returnType).apply { + interfaceImplementation.parentAsClass.typeParameters.forEachIndexed { index, _ -> + putTypeArgument(index, createPlaceholderAnyNType(context.irBuiltIns)) + } + passTypeArgumentsFrom(irFunction, offset = interfaceImplementation.parentAsClass.typeParameters.size) + var offset = 0 - passTypeArgumentsFrom(irFunction) irFunction.dispatchReceiverParameter?.let { putValueArgument(offset++, irGet(it)) } irFunction.extensionReceiverParameter?.let { putValueArgument(offset++, irGet(it)) } irFunction.valueParameters.mapIndexed { i, parameter -> putValueArgument(i + offset, irGet(parameter)) } @@ -118,12 +124,14 @@ private class InterfaceSuperCallsLowering(val context: JvmBackendContext) : IrEl return super.visitCall(expression) } + // TODO: This is too eagerly resolving the fake override statically. It + // should cf the old backend call precisely .foo, not + // resolve foo to its implementation. val superCallee = (expression.symbol.owner as IrSimpleFunction).resolveFakeOverride()!! if (superCallee.isDefinitelyNotDefaultImplsMethod() || superCallee.hasJvmDefault()) return super.visitCall(expression) val redirectTarget = context.declarationFactory.getDefaultImplsFunction(superCallee) - val newCall = irCall(expression, redirectTarget, receiversAsArguments = true) - + val newCall = createDelegatingCallWithPlaceholderTypeArguments(expression, redirectTarget, context.irBuiltIns) return super.visitCall(newCall) } } @@ -157,7 +165,7 @@ private class InterfaceDefaultCallsLowering(val context: JvmBackendContext) : Ir // gets redirected to call itself. if (redirectTarget == currentFunction?.irElement) return super.visitCall(expression) - val newCall = irCall(expression, redirectTarget, receiversAsArguments = true) + val newCall = createDelegatingCallWithPlaceholderTypeArguments(expression, redirectTarget, context.irBuiltIns) return super.visitCall(newCall) } diff --git a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/lower/InterfaceLowering.kt b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/lower/InterfaceLowering.kt index fa398322354..7974c219e5a 100644 --- a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/lower/InterfaceLowering.kt +++ b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/lower/InterfaceLowering.kt @@ -8,10 +8,11 @@ package org.jetbrains.kotlin.backend.jvm.lower import org.jetbrains.kotlin.backend.common.ClassLoweringPass import org.jetbrains.kotlin.backend.common.ir.isMethodOfAny import org.jetbrains.kotlin.backend.common.ir.moveBodyTo -import org.jetbrains.kotlin.backend.common.ir.passTypeArgumentsFrom import org.jetbrains.kotlin.backend.jvm.JvmBackendContext import org.jetbrains.kotlin.backend.jvm.JvmLoweredDeclarationOrigin import org.jetbrains.kotlin.backend.jvm.codegen.isJvmInterface +import org.jetbrains.kotlin.backend.jvm.ir.createDelegatingCallWithPlaceholderTypeArguments +import org.jetbrains.kotlin.backend.jvm.ir.createPlaceholderAnyNType import org.jetbrains.kotlin.backend.jvm.ir.hasJvmDefault import org.jetbrains.kotlin.descriptors.ClassKind import org.jetbrains.kotlin.descriptors.Modality @@ -24,6 +25,7 @@ import org.jetbrains.kotlin.ir.expressions.IrReturn import org.jetbrains.kotlin.ir.expressions.impl.* import org.jetbrains.kotlin.ir.symbols.IrFunctionSymbol import org.jetbrains.kotlin.ir.symbols.IrLocalDelegatedPropertySymbol +import org.jetbrains.kotlin.ir.types.defaultType import org.jetbrains.kotlin.ir.util.* import org.jetbrains.kotlin.ir.visitors.IrElementTransformerVoid import org.jetbrains.kotlin.ir.visitors.transformChildrenVoid @@ -187,11 +189,15 @@ internal class InterfaceLowering(val context: JvmBackendContext) : IrElementTran newFunction.parentAsClass.declarations.add(newFunction) } - // Bridge from static to static method - simply fill the arguments to the parameters. + // Bridge from static to static method - simply fill the function arguments to the parameters. // By nature of the generation of both source and target of bridge, they line up. private fun IrFunction.bridgeToStatic(callTarget: IrFunction) { body = IrExpressionBodyImpl(IrCallImpl(startOffset, endOffset, returnType, callTarget.symbol).also { call -> - call.passTypeArgumentsFrom(this) + + callTarget.typeParameters.forEachIndexed { i, _ -> + call.putTypeArgument(i, createPlaceholderAnyNType(context.irBuiltIns)) + } + valueParameters.forEachIndexed { i, it -> call.putValueArgument(i, IrGetValueImpl(startOffset, endOffset, it.symbol)) } @@ -209,7 +215,9 @@ internal class InterfaceLowering(val context: JvmBackendContext) : IrElementTran callTarget.symbol, superQualifierSymbol = callTarget.parentAsClass.symbol ).also { call -> - call.passTypeArgumentsFrom(this) + this.typeParameters.drop(callTarget.parentAsClass.typeParameters.size).forEachIndexed { i, typeParameter -> + call.putTypeArgument(i, typeParameter.defaultType) + } var offset = 0 callTarget.dispatchReceiverParameter?.let { @@ -243,7 +251,7 @@ internal class InterfaceLowering(val context: JvmBackendContext) : IrElementTran val newFunction = removedFunctions[expression.symbol]?.owner return super.visitCall( if (newFunction != null) { - irCall(expression, newFunction, receiversAsArguments = true) + createDelegatingCallWithPlaceholderTypeArguments(expression, newFunction, context.irBuiltIns) } else { expression } diff --git a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/builders/declarations/IrTypeParameterBuilder.kt b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/builders/declarations/IrTypeParameterBuilder.kt index 49e22a2ef41..6816d1db896 100644 --- a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/builders/declarations/IrTypeParameterBuilder.kt +++ b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/builders/declarations/IrTypeParameterBuilder.kt @@ -5,6 +5,7 @@ package org.jetbrains.kotlin.ir.builders.declarations +import org.jetbrains.kotlin.ir.declarations.IrTypeParameter import org.jetbrains.kotlin.ir.types.IrType import org.jetbrains.kotlin.types.Variance import org.jetbrains.kotlin.utils.SmartList @@ -14,4 +15,12 @@ class IrTypeParameterBuilder : IrDeclarationBuilder() { var variance: Variance = Variance.INVARIANT var isReified: Boolean = false val superTypes: MutableList = SmartList() + + fun updateFrom(from: IrTypeParameter) { + super.updateFrom(from) + index = from.index + variance = from.variance + isReified = from.isReified + superTypes.addAll(from.superTypes) + } } diff --git a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/util/IrUtils.kt b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/util/IrUtils.kt index 54799e11fef..67a4758eb3b 100644 --- a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/util/IrUtils.kt +++ b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/util/IrUtils.kt @@ -583,7 +583,16 @@ private fun IrMemberAccessExpression.copyTypeAndValueArgumentsFrom( argumentsAsReceivers: Boolean = false ) { copyTypeArgumentsFrom(src) + copyValueArgumentsFrom(src, srcFunction, destFunction, receiversAsArguments, argumentsAsReceivers) +} +fun IrMemberAccessExpression.copyValueArgumentsFrom( + src: IrMemberAccessExpression, + srcFunction: IrFunction, + destFunction: IrFunction, + receiversAsArguments: Boolean = false, + argumentsAsReceivers: Boolean = false +) { var destValueArgumentIndex = 0 var srcValueArgumentIndex = 0 diff --git a/compiler/testData/codegen/box/reflection/genericSignature/defaultImplsGenericSignature.kt b/compiler/testData/codegen/box/reflection/genericSignature/defaultImplsGenericSignature.kt index 790c230fe32..2e62a12956d 100644 --- a/compiler/testData/codegen/box/reflection/genericSignature/defaultImplsGenericSignature.kt +++ b/compiler/testData/codegen/box/reflection/genericSignature/defaultImplsGenericSignature.kt @@ -1,5 +1,4 @@ // IGNORE_BACKEND_FIR: JVM_IR -// IGNORE_BACKEND: JVM_IR // TARGET_BACKEND: JVM // FILE: J.java diff --git a/compiler/testData/codegen/box/reflection/genericSignature/kt11121.kt b/compiler/testData/codegen/box/reflection/genericSignature/kt11121.kt index a6ae2890798..993643f0f44 100644 --- a/compiler/testData/codegen/box/reflection/genericSignature/kt11121.kt +++ b/compiler/testData/codegen/box/reflection/genericSignature/kt11121.kt @@ -1,5 +1,4 @@ // IGNORE_BACKEND_FIR: JVM_IR -// IGNORE_BACKEND: JVM_IR // TARGET_BACKEND: JVM // WITH_REFLECT diff --git a/compiler/testData/writeSignature/defaultImpls/functionTypeParameterClash.kt b/compiler/testData/writeSignature/defaultImpls/functionTypeParameterClash.kt index c1a52c48a76..647b7ce0801 100644 --- a/compiler/testData/writeSignature/defaultImpls/functionTypeParameterClash.kt +++ b/compiler/testData/writeSignature/defaultImpls/functionTypeParameterClash.kt @@ -1,5 +1,3 @@ -// IGNORE_BACKEND: JVM_IR - class B interface A> { diff --git a/compiler/testData/writeSignature/defaultImpls/functionTypeParameterClashWith_I.kt b/compiler/testData/writeSignature/defaultImpls/functionTypeParameterClashWith_I.kt index cbd8ab30c32..8c06675d234 100644 --- a/compiler/testData/writeSignature/defaultImpls/functionTypeParameterClashWith_I.kt +++ b/compiler/testData/writeSignature/defaultImpls/functionTypeParameterClashWith_I.kt @@ -1,5 +1,3 @@ -// IGNORE_BACKEND: JVM_IR - class B interface A, T_I1: T> { diff --git a/compiler/testData/writeSignature/defaultImpls/propertyTypeParameterClash.kt b/compiler/testData/writeSignature/defaultImpls/propertyTypeParameterClash.kt index 13970b34ee9..645cb2b4cff 100644 --- a/compiler/testData/writeSignature/defaultImpls/propertyTypeParameterClash.kt +++ b/compiler/testData/writeSignature/defaultImpls/propertyTypeParameterClash.kt @@ -1,5 +1,3 @@ -// IGNORE_BACKEND: JVM_IR - class B interface A> {