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:
Dmitry Petrov
2020-05-28 16:26:11 +03:00
parent ffdab473e2
commit 94509bdb4e
10 changed files with 113 additions and 29 deletions
@@ -33,33 +33,49 @@ abstract class AbstractVersionRequirementTest : TestCaseWithTmpdir() {
fqNamesWithRequirements: List<String>,
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)
for (fqName in fqNamesWithRequirements) {
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)
assertEquals("Incorrect level for $fqName", expectedLevel, requirement.level)
assertEquals("Incorrect message for $fqName", expectedMessage, requirement.message)
assertEquals("Incorrect versionKind for $fqName", expectedVersionKind, requirement.kind)
assertEquals("Incorrect errorCode for $fqName", expectedErrorCode, requirement.errorCode)
requirements.firstOrNull {
expectedVersionRequirement == it.version &&
expectedLevel == it.level &&
expectedMessage == it.message &&
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) {
val descriptor = module.findUnambiguousDescriptorByFqName(fqName)
val requirenment = extractRequirement(descriptor)
assertNull("Expecting absence of any requirements for $fqName, but `$requirenment`", requirenment)
val requirement = extractRequirement(descriptor)
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) {
is DeserializedMemberDescriptor -> descriptor.versionRequirements.singleOrNull()
is DeserializedClassDescriptor -> descriptor.versionRequirements.singleOrNull()
is DeserializedMemberDescriptor -> descriptor.versionRequirements
is DeserializedClassDescriptor -> descriptor.versionRequirements
else -> throw AssertionError("Unknown descriptor: $descriptor")
}
}