JVM_IR: Do not copy attributes into DEFAULT_IMPLS functions

Otherwise, on creating suspend function views these functions will clash
with interface ones. Instead, compute name of their continuation classes
based on attributes of the interface class.
This commit is contained in:
Ilmir Usmanov
2020-01-31 15:28:41 +01:00
parent fc70455877
commit e5bd4f74f3
5 changed files with 23 additions and 22 deletions
@@ -1,11 +1,12 @@
/* /*
* Copyright 2010-2019 JetBrains s.r.o. and Kotlin Programming Language contributors. * Copyright 2010-2020 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. * 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.codegen package org.jetbrains.kotlin.backend.jvm.codegen
import org.jetbrains.kotlin.backend.jvm.JvmBackendContext import org.jetbrains.kotlin.backend.jvm.JvmBackendContext
import org.jetbrains.kotlin.backend.jvm.JvmLoweredDeclarationOrigin
import org.jetbrains.kotlin.builtins.functions.FunctionClassDescriptor import org.jetbrains.kotlin.builtins.functions.FunctionClassDescriptor
import org.jetbrains.kotlin.codegen.AsmUtil import org.jetbrains.kotlin.codegen.AsmUtil
import org.jetbrains.kotlin.codegen.JvmCodegenUtil import org.jetbrains.kotlin.codegen.JvmCodegenUtil
@@ -16,17 +17,11 @@ import org.jetbrains.kotlin.codegen.state.KotlinTypeMapperBase
import org.jetbrains.kotlin.descriptors.ClassDescriptor import org.jetbrains.kotlin.descriptors.ClassDescriptor
import org.jetbrains.kotlin.descriptors.ClassifierDescriptor import org.jetbrains.kotlin.descriptors.ClassifierDescriptor
import org.jetbrains.kotlin.descriptors.TypeParameterDescriptor import org.jetbrains.kotlin.descriptors.TypeParameterDescriptor
import org.jetbrains.kotlin.ir.declarations.IrClass import org.jetbrains.kotlin.ir.declarations.*
import org.jetbrains.kotlin.ir.declarations.IrPackageFragment
import org.jetbrains.kotlin.ir.declarations.IrSimpleFunction
import org.jetbrains.kotlin.ir.declarations.IrTypeParameter
import org.jetbrains.kotlin.ir.symbols.IrTypeParameterSymbol import org.jetbrains.kotlin.ir.symbols.IrTypeParameterSymbol
import org.jetbrains.kotlin.ir.types.* import org.jetbrains.kotlin.ir.types.*
import org.jetbrains.kotlin.ir.types.impl.originalKotlinType import org.jetbrains.kotlin.ir.types.impl.originalKotlinType
import org.jetbrains.kotlin.ir.util.defaultType import org.jetbrains.kotlin.ir.util.*
import org.jetbrains.kotlin.ir.util.fqNameWhenAvailable
import org.jetbrains.kotlin.ir.util.isSuspendFunction
import org.jetbrains.kotlin.ir.util.parentAsClass
import org.jetbrains.kotlin.load.kotlin.TypeMappingMode import org.jetbrains.kotlin.load.kotlin.TypeMappingMode
import org.jetbrains.kotlin.load.kotlin.computeExpandedTypeForInlineClass import org.jetbrains.kotlin.load.kotlin.computeExpandedTypeForInlineClass
import org.jetbrains.kotlin.load.kotlin.mapBuiltInType import org.jetbrains.kotlin.load.kotlin.mapBuiltInType
@@ -52,11 +47,20 @@ class IrTypeMapper(private val context: JvmBackendContext) : KotlinTypeMapperBas
} }
fun classInternalName(irClass: IrClass): String { fun classInternalName(irClass: IrClass): String {
fun report(): Nothing {
error(
"Local class should have its name computed in InventNamesForLocalClasses: ${irClass.fqNameWhenAvailable}\n" +
"Ensure that any lowering that transforms elements with local class info (classes, function references) " +
"invokes `copyAttributes` on the transformed element."
)
}
context.getLocalClassType(irClass)?.internalName?.let { return it } context.getLocalClassType(irClass)?.internalName?.let { return it }
context.classNameOverride[irClass]?.let { return it.internalName } context.classNameOverride[irClass]?.let { return it.internalName }
val className = SpecialNames.safeIdentifier(irClass.name).identifier val className = SpecialNames.safeIdentifier(irClass.name).identifier
val internalName = when (val parent = irClass.parent) { val internalName = when (val parent = irClass.parent) {
is IrPackageFragment -> { is IrPackageFragment -> {
val fqName = parent.fqName val fqName = parent.fqName
@@ -66,11 +70,13 @@ class IrTypeMapper(private val context: JvmBackendContext) : KotlinTypeMapperBas
is IrClass -> { is IrClass -> {
classInternalName(parent) + "$" + className classInternalName(parent) + "$" + className
} }
else -> error( is IrFunction -> {
"Local class should have its name computed in InventNamesForLocalClasses: ${irClass.fqNameWhenAvailable}\n" + if (parent.isSuspend && parent.parentAsClass.origin == JvmLoweredDeclarationOrigin.DEFAULT_IMPLS) {
"Ensure that any lowering that transforms elements with local class info (classes, function references) " + val interfaceClass = parent.parentAsClass.parent as IrClass
"invokes `copyAttributes` on the transformed element." classInternalName(interfaceClass) + "$" + parent.name.asString()
) } else report()
}
else -> report()
} }
return JvmCodegenUtil.sanitizeNameIfNeeded(internalName, context.state.languageVersionSettings) return JvmCodegenUtil.sanitizeNameIfNeeded(internalName, context.state.languageVersionSettings)
} }
@@ -1,5 +1,5 @@
/* /*
* Copyright 2010-2018 JetBrains s.r.o. and Kotlin Programming Language contributors. * Copyright 2010-2020 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. * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/ */
@@ -218,7 +218,7 @@ class JvmDeclarationFactory(
visibility = Visibilities.PUBLIC, visibility = Visibilities.PUBLIC,
typeParametersFromContext = parent.typeParameters typeParametersFromContext = parent.typeParameters
).also { it.copyAttributes(interfaceFun) } )
} }
} }
@@ -603,10 +603,7 @@ private class AddContinuationLowering(private val context: JvmBackendContext) :
functionsStack.pop() functionsStack.pop()
if (skip(function)) return function if (skip(function)) return function
// TODO: This does not work for DEFAULT_IMPLS val view = function.getOrCreateSuspendFunctionViewIfNeeded(context) as IrSimpleFunction
val view =
(if (function.body == null) function.suspendFunctionStub(context, false)
else function.getOrCreateSuspendFunctionViewIfNeeded(context)) as IrSimpleFunction
if (withoutContinuationClass(function)) return view if (withoutContinuationClass(function)) return view
@@ -1,5 +1,4 @@
// IGNORE_BACKEND_FIR: JVM_IR // IGNORE_BACKEND_FIR: JVM_IR
// IGNORE_BACKEND: JVM_IR
// WITH_RUNTIME // WITH_RUNTIME
// WITH_COROUTINES // WITH_COROUTINES
// COMMON_COROUTINES_TEST // COMMON_COROUTINES_TEST
@@ -1,5 +1,4 @@
// IGNORE_BACKEND_FIR: JVM_IR // IGNORE_BACKEND_FIR: JVM_IR
// IGNORE_BACKEND: JVM_IR
// WITH_RUNTIME // WITH_RUNTIME
// WITH_COROUTINES // WITH_COROUTINES
// COMMON_COROUTINES_TEST // COMMON_COROUTINES_TEST