KT-39228 Fix inliner when latest 1.4 compiler used with 1.3 stdlib
Since 1.4.0-dev-8774, we mangle functions returning inline class values, including functions with return type 'kotlin.Result'. This causes incompatibility when 1.4 compiler is used with 1.3 (or just some pre-1.4.0-dev-8774) standard library. Also, write "message from the future" on functions returning inline class values indicating that they can be used since compiler version 1.4 (otherwise 1.3 compiler using 1.4 stdlib would fail to find some @InlineOnly functions such as 'Result.success' and 'Result.failure').
This commit is contained in:
@@ -16,6 +16,7 @@ import org.jetbrains.kotlin.codegen.intrinsics.IntrinsicArrayConstructors
|
|||||||
import org.jetbrains.kotlin.codegen.state.GenerationState
|
import org.jetbrains.kotlin.codegen.state.GenerationState
|
||||||
import org.jetbrains.kotlin.codegen.state.KotlinTypeMapper
|
import org.jetbrains.kotlin.codegen.state.KotlinTypeMapper
|
||||||
import org.jetbrains.kotlin.descriptors.*
|
import org.jetbrains.kotlin.descriptors.*
|
||||||
|
import org.jetbrains.kotlin.name.ClassId
|
||||||
import org.jetbrains.kotlin.name.Name
|
import org.jetbrains.kotlin.name.Name
|
||||||
import org.jetbrains.kotlin.renderer.DescriptorRenderer
|
import org.jetbrains.kotlin.renderer.DescriptorRenderer
|
||||||
import org.jetbrains.kotlin.resolve.DescriptorToSourceUtils
|
import org.jetbrains.kotlin.resolve.DescriptorToSourceUtils
|
||||||
@@ -24,7 +25,9 @@ import org.jetbrains.kotlin.resolve.ImportedFromObjectCallableDescriptor
|
|||||||
import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall
|
import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall
|
||||||
import org.jetbrains.kotlin.resolve.inline.InlineUtil
|
import org.jetbrains.kotlin.resolve.inline.InlineUtil
|
||||||
import org.jetbrains.kotlin.resolve.inline.isInlineOnly
|
import org.jetbrains.kotlin.resolve.inline.isInlineOnly
|
||||||
|
import org.jetbrains.kotlin.resolve.isInlineClassType
|
||||||
import org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodSignature
|
import org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodSignature
|
||||||
|
import org.jetbrains.kotlin.resolve.jvm.requiresFunctionNameManglingForReturnType
|
||||||
import org.jetbrains.kotlin.resolve.scopes.MemberScope
|
import org.jetbrains.kotlin.resolve.scopes.MemberScope
|
||||||
import org.jetbrains.kotlin.serialization.deserialization.descriptors.DescriptorWithContainerSource
|
import org.jetbrains.kotlin.serialization.deserialization.descriptors.DescriptorWithContainerSource
|
||||||
import org.jetbrains.kotlin.types.KotlinType
|
import org.jetbrains.kotlin.types.KotlinType
|
||||||
@@ -629,8 +632,7 @@ abstract class InlineCodegen<out T : BaseExpressionCodegen>(
|
|||||||
?: throw IllegalStateException("Couldn't find declaration file for $containerId")
|
?: throw IllegalStateException("Couldn't find declaration file for $containerId")
|
||||||
}
|
}
|
||||||
|
|
||||||
val methodNode =
|
val methodNode = getMethodNodeInner(containerId, bytes, asmMethod, callableDescriptor) ?: return null
|
||||||
getMethodNode(bytes, asmMethod.name, asmMethod.descriptor, AsmUtil.asmTypeByClassId(containerId)) ?: return null
|
|
||||||
|
|
||||||
// KLUDGE: Inline suspend function built with compiler version less than 1.1.4/1.2-M1 did not contain proper
|
// KLUDGE: Inline suspend function built with compiler version less than 1.1.4/1.2-M1 did not contain proper
|
||||||
// before/after suspension point marks, so we detect those functions here and insert the corresponding marks
|
// before/after suspension point marks, so we detect those functions here and insert the corresponding marks
|
||||||
@@ -641,6 +643,28 @@ abstract class InlineCodegen<out T : BaseExpressionCodegen>(
|
|||||||
return methodNode
|
return methodNode
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun getMethodNodeInner(
|
||||||
|
containerId: ClassId,
|
||||||
|
bytes: ByteArray,
|
||||||
|
asmMethod: Method,
|
||||||
|
callableDescriptor: CallableMemberDescriptor
|
||||||
|
): SMAPAndMethodNode? {
|
||||||
|
val classType = AsmUtil.asmTypeByClassId(containerId)
|
||||||
|
var methodNode = getMethodNode(bytes, asmMethod.name, asmMethod.descriptor, classType)
|
||||||
|
if (methodNode == null && requiresFunctionNameManglingForReturnType(callableDescriptor)) {
|
||||||
|
val nameWithoutManglingSuffix = asmMethod.name.stripManglingSuffixOrNull()
|
||||||
|
if (nameWithoutManglingSuffix != null) {
|
||||||
|
methodNode = getMethodNode(bytes, nameWithoutManglingSuffix, asmMethod.descriptor, classType)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return methodNode
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun String.stripManglingSuffixOrNull(): String? {
|
||||||
|
val dashIndex = indexOf('-')
|
||||||
|
return if (dashIndex < 0) null else substring(0, dashIndex)
|
||||||
|
}
|
||||||
|
|
||||||
private fun isBuiltInArrayIntrinsic(callableDescriptor: CallableMemberDescriptor): Boolean {
|
private fun isBuiltInArrayIntrinsic(callableDescriptor: CallableMemberDescriptor): Boolean {
|
||||||
if (callableDescriptor is FictitiousArrayConstructor) return true
|
if (callableDescriptor is FictitiousArrayConstructor) return true
|
||||||
val name = callableDescriptor.name.asString()
|
val name = callableDescriptor.name.asString()
|
||||||
|
|||||||
+22
-6
@@ -32,6 +32,7 @@ import org.jetbrains.kotlin.resolve.descriptorUtil.classId
|
|||||||
import org.jetbrains.kotlin.resolve.descriptorUtil.isEffectivelyPrivateApi
|
import org.jetbrains.kotlin.resolve.descriptorUtil.isEffectivelyPrivateApi
|
||||||
import org.jetbrains.kotlin.resolve.descriptorUtil.nonSourceAnnotations
|
import org.jetbrains.kotlin.resolve.descriptorUtil.nonSourceAnnotations
|
||||||
import org.jetbrains.kotlin.resolve.jvm.annotations.hasJvmDefaultAnnotation
|
import org.jetbrains.kotlin.resolve.jvm.annotations.hasJvmDefaultAnnotation
|
||||||
|
import org.jetbrains.kotlin.resolve.jvm.requiresFunctionNameManglingForReturnType
|
||||||
import org.jetbrains.kotlin.serialization.DescriptorSerializer
|
import org.jetbrains.kotlin.serialization.DescriptorSerializer
|
||||||
import org.jetbrains.kotlin.serialization.DescriptorSerializer.Companion.writeVersionRequirement
|
import org.jetbrains.kotlin.serialization.DescriptorSerializer.Companion.writeVersionRequirement
|
||||||
import org.jetbrains.kotlin.serialization.SerializerExtension
|
import org.jetbrains.kotlin.serialization.SerializerExtension
|
||||||
@@ -54,6 +55,7 @@ class JvmSerializerExtension @JvmOverloads constructor(
|
|||||||
private val languageVersionSettings = state.languageVersionSettings
|
private val languageVersionSettings = state.languageVersionSettings
|
||||||
private val isParamAssertionsDisabled = state.isParamAssertionsDisabled
|
private val isParamAssertionsDisabled = state.isParamAssertionsDisabled
|
||||||
private val unifiedNullChecks = state.unifiedNullChecks
|
private val unifiedNullChecks = state.unifiedNullChecks
|
||||||
|
private val functionsWithInlineClassReturnTypesMangled = state.functionsWithInlineClassReturnTypesMangled
|
||||||
override val metadataVersion = state.metadataVersion
|
override val metadataVersion = state.metadataVersion
|
||||||
private val jvmDefaultMode = state.jvmDefaultMode
|
private val jvmDefaultMode = state.jvmDefaultMode
|
||||||
|
|
||||||
@@ -75,17 +77,17 @@ class JvmSerializerExtension @JvmOverloads constructor(
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun serializeClass(
|
override fun serializeClass(
|
||||||
descriptor: ClassDescriptor,
|
descriptor: ClassDescriptor,
|
||||||
proto: ProtoBuf.Class.Builder,
|
proto: ProtoBuf.Class.Builder,
|
||||||
versionRequirementTable: MutableVersionRequirementTable,
|
versionRequirementTable: MutableVersionRequirementTable,
|
||||||
childSerializer: DescriptorSerializer
|
childSerializer: DescriptorSerializer
|
||||||
) {
|
) {
|
||||||
if (moduleName != JvmProtoBufUtil.DEFAULT_MODULE_NAME) {
|
if (moduleName != JvmProtoBufUtil.DEFAULT_MODULE_NAME) {
|
||||||
proto.setExtension(JvmProtoBuf.classModuleName, stringTable.getStringIndex(moduleName))
|
proto.setExtension(JvmProtoBuf.classModuleName, stringTable.getStringIndex(moduleName))
|
||||||
}
|
}
|
||||||
//TODO: support local delegated properties in new defaults scheme
|
//TODO: support local delegated properties in new defaults scheme
|
||||||
val containerAsmType =
|
val containerAsmType =
|
||||||
if (DescriptorUtils.isInterface(descriptor)) typeMapper.mapDefaultImpls(descriptor) else typeMapper.mapClass(descriptor)
|
if (isInterface(descriptor)) typeMapper.mapDefaultImpls(descriptor) else typeMapper.mapClass(descriptor)
|
||||||
writeLocalProperties(proto, containerAsmType, JvmProtoBuf.classLocalVariable)
|
writeLocalProperties(proto, containerAsmType, JvmProtoBuf.classLocalVariable)
|
||||||
writeVersionRequirementForJvmDefaultIfNeeded(descriptor, proto, versionRequirementTable)
|
writeVersionRequirementForJvmDefaultIfNeeded(descriptor, proto, versionRequirementTable)
|
||||||
|
|
||||||
@@ -198,6 +200,10 @@ class JvmSerializerExtension @JvmOverloads constructor(
|
|||||||
if (descriptor.needsInlineParameterNullCheckRequirement()) {
|
if (descriptor.needsInlineParameterNullCheckRequirement()) {
|
||||||
versionRequirementTable?.writeInlineParameterNullCheckRequirement(proto::addVersionRequirement)
|
versionRequirementTable?.writeInlineParameterNullCheckRequirement(proto::addVersionRequirement)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (requiresFunctionNameManglingForReturnType(descriptor)) {
|
||||||
|
versionRequirementTable?.writeFunctionNameManglingForReturnTypeRequirement(proto::addVersionRequirement)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun MutableVersionRequirementTable.writeInlineParameterNullCheckRequirement(add: (Int) -> Unit) {
|
private fun MutableVersionRequirementTable.writeInlineParameterNullCheckRequirement(add: (Int) -> Unit) {
|
||||||
@@ -208,6 +214,12 @@ class JvmSerializerExtension @JvmOverloads constructor(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun MutableVersionRequirementTable.writeFunctionNameManglingForReturnTypeRequirement(add: (Int) -> Unit) {
|
||||||
|
if (functionsWithInlineClassReturnTypesMangled) {
|
||||||
|
add(writeVersionRequirement(1, 4, 0, ProtoBuf.VersionRequirement.VersionKind.COMPILER_VERSION, this))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private fun FunctionDescriptor.needsInlineParameterNullCheckRequirement(): Boolean =
|
private fun FunctionDescriptor.needsInlineParameterNullCheckRequirement(): Boolean =
|
||||||
isInline && !isSuspend && !isParamAssertionsDisabled &&
|
isInline && !isSuspend && !isParamAssertionsDisabled &&
|
||||||
!Visibilities.isPrivate(visibility) &&
|
!Visibilities.isPrivate(visibility) &&
|
||||||
@@ -253,6 +265,10 @@ class JvmSerializerExtension @JvmOverloads constructor(
|
|||||||
if (getter?.needsInlineParameterNullCheckRequirement() == true || setter?.needsInlineParameterNullCheckRequirement() == true) {
|
if (getter?.needsInlineParameterNullCheckRequirement() == true || setter?.needsInlineParameterNullCheckRequirement() == true) {
|
||||||
versionRequirementTable?.writeInlineParameterNullCheckRequirement(proto::addVersionRequirement)
|
versionRequirementTable?.writeInlineParameterNullCheckRequirement(proto::addVersionRequirement)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (requiresFunctionNameManglingForReturnType(descriptor)) {
|
||||||
|
versionRequirementTable?.writeFunctionNameManglingForReturnTypeRequirement(proto::addVersionRequirement)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun PropertyDescriptor.isJvmFieldPropertyInInterfaceCompanion(): Boolean {
|
private fun PropertyDescriptor.isJvmFieldPropertyInInterfaceCompanion(): Boolean {
|
||||||
@@ -262,7 +278,7 @@ class JvmSerializerExtension @JvmOverloads constructor(
|
|||||||
if (!DescriptorUtils.isCompanionObject(container)) return false
|
if (!DescriptorUtils.isCompanionObject(container)) return false
|
||||||
|
|
||||||
val grandParent = (container as ClassDescriptor).containingDeclaration
|
val grandParent = (container as ClassDescriptor).containingDeclaration
|
||||||
return DescriptorUtils.isInterface(grandParent) || DescriptorUtils.isAnnotationClass(grandParent)
|
return isInterface(grandParent) || DescriptorUtils.isAnnotationClass(grandParent)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun serializeErrorType(type: KotlinType, builder: ProtoBuf.Type.Builder) {
|
override fun serializeErrorType(type: KotlinType, builder: ProtoBuf.Type.Builder) {
|
||||||
|
|||||||
@@ -251,6 +251,7 @@ class GenerationState private constructor(
|
|||||||
val isInlineDisabled: Boolean = configuration.getBoolean(CommonConfigurationKeys.DISABLE_INLINE)
|
val isInlineDisabled: Boolean = configuration.getBoolean(CommonConfigurationKeys.DISABLE_INLINE)
|
||||||
val useTypeTableInSerializer: Boolean = configuration.getBoolean(JVMConfigurationKeys.USE_TYPE_TABLE)
|
val useTypeTableInSerializer: Boolean = configuration.getBoolean(JVMConfigurationKeys.USE_TYPE_TABLE)
|
||||||
val unifiedNullChecks: Boolean = languageVersionSettings.apiVersion >= ApiVersion.KOTLIN_1_4
|
val unifiedNullChecks: Boolean = languageVersionSettings.apiVersion >= ApiVersion.KOTLIN_1_4
|
||||||
|
val functionsWithInlineClassReturnTypesMangled: Boolean = languageVersionSettings.apiVersion >= ApiVersion.KOTLIN_1_4
|
||||||
|
|
||||||
val rootContext: CodegenContext<*> = RootContext(this)
|
val rootContext: CodegenContext<*> = RootContext(this)
|
||||||
|
|
||||||
|
|||||||
@@ -9,7 +9,6 @@ import org.jetbrains.kotlin.codegen.coroutines.unwrapInitialDescriptorForSuspend
|
|||||||
import org.jetbrains.kotlin.descriptors.*
|
import org.jetbrains.kotlin.descriptors.*
|
||||||
import org.jetbrains.kotlin.resolve.InlineClassDescriptorResolver
|
import org.jetbrains.kotlin.resolve.InlineClassDescriptorResolver
|
||||||
import org.jetbrains.kotlin.resolve.descriptorUtil.fqNameUnsafe
|
import org.jetbrains.kotlin.resolve.descriptorUtil.fqNameUnsafe
|
||||||
import org.jetbrains.kotlin.resolve.isInlineClassType
|
|
||||||
import org.jetbrains.kotlin.resolve.jvm.requiresFunctionNameManglingForParameterTypes
|
import org.jetbrains.kotlin.resolve.jvm.requiresFunctionNameManglingForParameterTypes
|
||||||
import org.jetbrains.kotlin.resolve.jvm.requiresFunctionNameManglingForReturnType
|
import org.jetbrains.kotlin.resolve.jvm.requiresFunctionNameManglingForReturnType
|
||||||
import org.jetbrains.kotlin.types.KotlinType
|
import org.jetbrains.kotlin.types.KotlinType
|
||||||
@@ -31,11 +30,9 @@ fun getManglingSuffixBasedOnKotlinSignature(descriptor: CallableMemberDescriptor
|
|||||||
// If a class member function returns inline class value, mangle its name.
|
// If a class member function returns inline class value, mangle its name.
|
||||||
// NB here function can be a suspend function JVM view with return type replaced with 'Any',
|
// NB here function can be a suspend function JVM view with return type replaced with 'Any',
|
||||||
// should unwrap it and take original return type instead.
|
// should unwrap it and take original return type instead.
|
||||||
if (descriptor.containingDeclaration is ClassDescriptor) {
|
val unwrappedDescriptor = descriptor.unwrapInitialDescriptorForSuspendFunction()
|
||||||
val returnType = descriptor.unwrapInitialDescriptorForSuspendFunction().returnType!!
|
if (requiresFunctionNameManglingForReturnType(unwrappedDescriptor)) {
|
||||||
if (requiresFunctionNameManglingForReturnType(returnType)) {
|
return "-" + md5base64(":" + getSignatureElementForMangling(unwrappedDescriptor.returnType!!))
|
||||||
return "-" + md5base64(":" + getSignatureElementForMangling(returnType))
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-1
@@ -151,7 +151,7 @@ class JvmNameAnnotationChecker : DeclarationChecker {
|
|||||||
diagnosticHolder.report(ErrorsJvm.INAPPLICABLE_JVM_NAME.on(annotationEntry))
|
diagnosticHolder.report(ErrorsJvm.INAPPLICABLE_JVM_NAME.on(annotationEntry))
|
||||||
} else if (descriptor.containingDeclaration.isInlineClassThatRequiresMangling() ||
|
} else if (descriptor.containingDeclaration.isInlineClassThatRequiresMangling() ||
|
||||||
requiresFunctionNameManglingForParameterTypes(descriptor.valueParameters.map { it.type }) ||
|
requiresFunctionNameManglingForParameterTypes(descriptor.valueParameters.map { it.type }) ||
|
||||||
descriptor.containingDeclaration is ClassDescriptor && requiresFunctionNameManglingForReturnType(descriptor.returnType)
|
requiresFunctionNameManglingForReturnType(descriptor)
|
||||||
) {
|
) {
|
||||||
diagnosticHolder.report(ErrorsJvm.INAPPLICABLE_JVM_NAME.on(annotationEntry))
|
diagnosticHolder.report(ErrorsJvm.INAPPLICABLE_JVM_NAME.on(annotationEntry))
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,8 @@
|
|||||||
|
package test
|
||||||
|
|
||||||
|
inline class IC(val x: Int)
|
||||||
|
|
||||||
|
class C {
|
||||||
|
fun returnsInlineClassType(): IC = IC(42)
|
||||||
|
val propertyOfInlineClassType: IC get() = IC(42)
|
||||||
|
}
|
||||||
+28
-12
@@ -33,33 +33,49 @@ abstract class AbstractVersionRequirementTest : TestCaseWithTmpdir() {
|
|||||||
fqNamesWithRequirements: List<String>,
|
fqNamesWithRequirements: List<String>,
|
||||||
fqNamesWithoutRequirement: List<String> = emptyList()
|
fqNamesWithoutRequirement: List<String> = emptyList()
|
||||||
) {
|
) {
|
||||||
compileFiles(listOf(File("compiler/testData/versionRequirement/${getTestName(true)}.kt")), tmpdir, customLanguageVersion, analysisFlags)
|
compileFiles(
|
||||||
|
listOf(File("compiler/testData/versionRequirement/${getTestName(true)}.kt")),
|
||||||
|
tmpdir, customLanguageVersion, analysisFlags
|
||||||
|
)
|
||||||
val module = loadModule(tmpdir)
|
val module = loadModule(tmpdir)
|
||||||
|
|
||||||
for (fqName in fqNamesWithRequirements) {
|
for (fqName in fqNamesWithRequirements) {
|
||||||
val descriptor = module.findUnambiguousDescriptorByFqName(fqName)
|
val descriptor = module.findUnambiguousDescriptorByFqName(fqName)
|
||||||
|
|
||||||
val requirement = extractRequirement(descriptor) ?: throw AssertionError("No VersionRequirement for $descriptor")
|
val requirements = extractRequirement(descriptor)
|
||||||
|
if (requirements.isEmpty()) throw AssertionError("No VersionRequirement for $descriptor")
|
||||||
|
|
||||||
assertEquals("Incorrect version for $fqName", expectedVersionRequirement, requirement.version)
|
requirements.firstOrNull {
|
||||||
assertEquals("Incorrect level for $fqName", expectedLevel, requirement.level)
|
expectedVersionRequirement == it.version &&
|
||||||
assertEquals("Incorrect message for $fqName", expectedMessage, requirement.message)
|
expectedLevel == it.level &&
|
||||||
assertEquals("Incorrect versionKind for $fqName", expectedVersionKind, requirement.kind)
|
expectedMessage == it.message &&
|
||||||
assertEquals("Incorrect errorCode for $fqName", expectedErrorCode, requirement.errorCode)
|
expectedVersionKind == it.kind &&
|
||||||
|
expectedErrorCode == it.errorCode
|
||||||
|
}
|
||||||
|
?: throw AssertionError(
|
||||||
|
"Version requirement not found:\n" +
|
||||||
|
"expectedVersionRequirement=" + expectedVersionRequirement +
|
||||||
|
"; expectedLevel=" + expectedLevel +
|
||||||
|
"; expectedMessage=" + expectedMessage +
|
||||||
|
"; expectedVersionKind=" + expectedVersionKind +
|
||||||
|
"; expectedErrorCode=" + expectedErrorCode +
|
||||||
|
"\nActual requirements:\n" +
|
||||||
|
requirements.joinToString(separator = "\n") { it.toString() }
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
for (fqName in fqNamesWithoutRequirement) {
|
for (fqName in fqNamesWithoutRequirement) {
|
||||||
val descriptor = module.findUnambiguousDescriptorByFqName(fqName)
|
val descriptor = module.findUnambiguousDescriptorByFqName(fqName)
|
||||||
|
|
||||||
val requirenment = extractRequirement(descriptor)
|
val requirement = extractRequirement(descriptor)
|
||||||
assertNull("Expecting absence of any requirements for $fqName, but `$requirenment`", requirenment)
|
assertTrue("Expecting absence of any requirements for $fqName, but `$requirement`", requirement.isEmpty())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun extractRequirement(descriptor: DeclarationDescriptor): VersionRequirement? {
|
private fun extractRequirement(descriptor: DeclarationDescriptor): List<VersionRequirement> {
|
||||||
return when (descriptor) {
|
return when (descriptor) {
|
||||||
is DeserializedMemberDescriptor -> descriptor.versionRequirements.singleOrNull()
|
is DeserializedMemberDescriptor -> descriptor.versionRequirements
|
||||||
is DeserializedClassDescriptor -> descriptor.versionRequirements.singleOrNull()
|
is DeserializedClassDescriptor -> descriptor.versionRequirements
|
||||||
else -> throw AssertionError("Unknown descriptor: $descriptor")
|
else -> throw AssertionError("Unknown descriptor: $descriptor")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -128,6 +128,17 @@ class JvmVersionRequirementTest : AbstractVersionRequirementTest() {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun testInlineClassReturnTypeMangled() {
|
||||||
|
doTest(
|
||||||
|
VersionRequirement.Version(1, 4, 0), DeprecationLevel.ERROR, null, COMPILER_VERSION, null,
|
||||||
|
fqNamesWithRequirements = listOf(
|
||||||
|
"test.C.returnsInlineClassType",
|
||||||
|
"test.C.propertyOfInlineClassType"
|
||||||
|
),
|
||||||
|
customLanguageVersion = LanguageVersion.KOTLIN_1_4
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
fun testSuspendFun_1_2() {
|
fun testSuspendFun_1_2() {
|
||||||
doTest(
|
doTest(
|
||||||
VersionRequirement.Version(1, 1), DeprecationLevel.ERROR, null, LANGUAGE_VERSION, null,
|
VersionRequirement.Version(1, 1), DeprecationLevel.ERROR, null, LANGUAGE_VERSION, null,
|
||||||
|
|||||||
+5
-2
@@ -29,8 +29,11 @@ fun requiresFunctionNameManglingForParameterTypes(valueParameterTypes: List<Kotl
|
|||||||
}
|
}
|
||||||
|
|
||||||
// NB functions returning all inline classes (including our special 'kotlin.Result') should be mangled.
|
// NB functions returning all inline classes (including our special 'kotlin.Result') should be mangled.
|
||||||
fun requiresFunctionNameManglingForReturnType(returnType: KotlinType?) =
|
fun requiresFunctionNameManglingForReturnType(descriptor: CallableMemberDescriptor): Boolean {
|
||||||
returnType != null && returnType.isInlineClassType()
|
if (descriptor.containingDeclaration !is ClassDescriptor) return false
|
||||||
|
val returnType = descriptor.returnType ?: return false
|
||||||
|
return returnType.isInlineClassType()
|
||||||
|
}
|
||||||
|
|
||||||
fun DeclarationDescriptor.isInlineClassThatRequiresMangling(): Boolean =
|
fun DeclarationDescriptor.isInlineClassThatRequiresMangling(): Boolean =
|
||||||
isInlineClass() && !isDontMangleClass(this as ClassDescriptor)
|
isInlineClass() && !isDontMangleClass(this as ClassDescriptor)
|
||||||
|
|||||||
@@ -79,41 +79,49 @@ public final annotation class A : kotlin/Annotation {
|
|||||||
public final get
|
public final get
|
||||||
|
|
||||||
// requires language version 1.3.0 (level=ERROR)
|
// requires language version 1.3.0 (level=ERROR)
|
||||||
|
// requires compiler version 1.4.0 (level=ERROR)
|
||||||
// getter: ub()B
|
// getter: ub()B
|
||||||
public final val ub: kotlin/UByte
|
public final val ub: kotlin/UByte
|
||||||
public final get
|
public final get
|
||||||
|
|
||||||
// requires language version 1.3.0 (level=ERROR)
|
// requires language version 1.3.0 (level=ERROR)
|
||||||
|
// requires compiler version 1.4.0 (level=ERROR)
|
||||||
// getter: ub_max()B
|
// getter: ub_max()B
|
||||||
public final val ub_max: kotlin/UByte
|
public final val ub_max: kotlin/UByte
|
||||||
public final get
|
public final get
|
||||||
|
|
||||||
// requires language version 1.3.0 (level=ERROR)
|
// requires language version 1.3.0 (level=ERROR)
|
||||||
|
// requires compiler version 1.4.0 (level=ERROR)
|
||||||
// getter: ui()I
|
// getter: ui()I
|
||||||
public final val ui: kotlin/UInt
|
public final val ui: kotlin/UInt
|
||||||
public final get
|
public final get
|
||||||
|
|
||||||
// requires language version 1.3.0 (level=ERROR)
|
// requires language version 1.3.0 (level=ERROR)
|
||||||
|
// requires compiler version 1.4.0 (level=ERROR)
|
||||||
// getter: ui_max()I
|
// getter: ui_max()I
|
||||||
public final val ui_max: kotlin/UInt
|
public final val ui_max: kotlin/UInt
|
||||||
public final get
|
public final get
|
||||||
|
|
||||||
// requires language version 1.3.0 (level=ERROR)
|
// requires language version 1.3.0 (level=ERROR)
|
||||||
|
// requires compiler version 1.4.0 (level=ERROR)
|
||||||
// getter: ul()J
|
// getter: ul()J
|
||||||
public final val ul: kotlin/ULong
|
public final val ul: kotlin/ULong
|
||||||
public final get
|
public final get
|
||||||
|
|
||||||
// requires language version 1.3.0 (level=ERROR)
|
// requires language version 1.3.0 (level=ERROR)
|
||||||
|
// requires compiler version 1.4.0 (level=ERROR)
|
||||||
// getter: ul_max()J
|
// getter: ul_max()J
|
||||||
public final val ul_max: kotlin/ULong
|
public final val ul_max: kotlin/ULong
|
||||||
public final get
|
public final get
|
||||||
|
|
||||||
// requires language version 1.3.0 (level=ERROR)
|
// requires language version 1.3.0 (level=ERROR)
|
||||||
|
// requires compiler version 1.4.0 (level=ERROR)
|
||||||
// getter: us()S
|
// getter: us()S
|
||||||
public final val us: kotlin/UShort
|
public final val us: kotlin/UShort
|
||||||
public final get
|
public final get
|
||||||
|
|
||||||
// requires language version 1.3.0 (level=ERROR)
|
// requires language version 1.3.0 (level=ERROR)
|
||||||
|
// requires compiler version 1.4.0 (level=ERROR)
|
||||||
// getter: us_max()S
|
// getter: us_max()S
|
||||||
public final val us_max: kotlin/UShort
|
public final val us_max: kotlin/UShort
|
||||||
public final get
|
public final get
|
||||||
|
|||||||
Reference in New Issue
Block a user