[JVM_IR] Propagate Type Parameters to DefaultImpls
This ensures correct generation of generic signatures in the resulting byte code, but it _is_ a work in progress: the actual type *arguments* passed for these parameters during compilation are dummy `Any?` types. Sites that need more work are indicated with TODO's. - copy type parameters of interfaces to methods moved to DefaultImpls - implement type parameter renaming scheme from JVM, with proper renaming and substitution. - adjust call sites in bridges in classes->DefaultImpls - adjust call sites in bridges from DefaultImpls->Interface - adjust call sites in bridges from DefaultImpls->DefaultImpls - adjust super calls ->DefaultImpls - adjust calls in code of Interfaces->DefaultImpls
This commit is contained in:
committed by
Georgy Bronnikov
parent
3606a4104b
commit
4dd794c2d2
@@ -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<IrTypeParameter, IrTypeParameter> = 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<IrValueParameter>
|
||||
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<IrTypeParameter> = 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<IrTypeParameter>,
|
||||
existingParameters: Collection<IrTypeParameter>
|
||||
): List<IrTypeParameter> {
|
||||
val newParameters = mutableListOf<IrTypeParameter>()
|
||||
|
||||
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
|
||||
|
||||
+4
-1
@@ -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) }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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<S,T>` for the _calling_
|
||||
// class `C` gives the proper instantiation fo arguments.
|
||||
//
|
||||
// We essentially want to answer the type query:
|
||||
//
|
||||
// C <: I<?S,?T>
|
||||
//
|
||||
// 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))
|
||||
}
|
||||
}
|
||||
+16
-8
@@ -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 <supertype>.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)
|
||||
}
|
||||
|
||||
+13
-5
@@ -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
|
||||
}
|
||||
|
||||
+9
@@ -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<IrType> = SmartList()
|
||||
|
||||
fun updateFrom(from: IrTypeParameter) {
|
||||
super.updateFrom(from)
|
||||
index = from.index
|
||||
variance = from.variance
|
||||
isReified = from.isReified
|
||||
superTypes.addAll(from.superTypes)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
-1
@@ -1,5 +1,4 @@
|
||||
// IGNORE_BACKEND_FIR: JVM_IR
|
||||
// IGNORE_BACKEND: JVM_IR
|
||||
// TARGET_BACKEND: JVM
|
||||
|
||||
// FILE: J.java
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
// IGNORE_BACKEND_FIR: JVM_IR
|
||||
// IGNORE_BACKEND: JVM_IR
|
||||
// TARGET_BACKEND: JVM
|
||||
|
||||
// WITH_REFLECT
|
||||
|
||||
@@ -1,5 +1,3 @@
|
||||
// IGNORE_BACKEND: JVM_IR
|
||||
|
||||
class B<M>
|
||||
|
||||
interface A<T, Y : B<T>> {
|
||||
|
||||
-2
@@ -1,5 +1,3 @@
|
||||
// IGNORE_BACKEND: JVM_IR
|
||||
|
||||
class B<M>
|
||||
|
||||
interface A<T, Y : B<T>, T_I1: T> {
|
||||
|
||||
@@ -1,5 +1,3 @@
|
||||
// IGNORE_BACKEND: JVM_IR
|
||||
|
||||
class B<M>
|
||||
|
||||
interface A<T, Y : B<T>> {
|
||||
|
||||
Reference in New Issue
Block a user