[FIR2IR] Properly set isAssignable flag for parameters of tailrec functions

^KT-63973 Fixed
This commit is contained in:
Dmitriy Novozhilov
2023-12-12 16:36:06 +02:00
committed by Space Team
parent f4e3203cd8
commit 28f0f1ea88
25 changed files with 153 additions and 3 deletions
@@ -55196,6 +55196,12 @@ public class LLFirBlackBoxCodegenBasedTestGenerated extends AbstractLLFirBlackBo
runTest("compiler/testData/codegen/box/vararg/varargInJava.kt");
}
@Test
@TestMetadata("varargInTailrec.kt")
public void testVarargInTailrec() throws Exception {
runTest("compiler/testData/codegen/box/vararg/varargInTailrec.kt");
}
@Test
@TestMetadata("varargsAndFunctionLiterals.kt")
public void testVarargsAndFunctionLiterals() throws Exception {
@@ -55196,6 +55196,12 @@ public class LLFirReversedBlackBoxCodegenBasedTestGenerated extends AbstractLLFi
runTest("compiler/testData/codegen/box/vararg/varargInJava.kt");
}
@Test
@TestMetadata("varargInTailrec.kt")
public void testVarargInTailrec() throws Exception {
runTest("compiler/testData/codegen/box/vararg/varargInTailrec.kt");
}
@Test
@TestMetadata("varargsAndFunctionLiterals.kt")
public void testVarargsAndFunctionLiterals() throws Exception {
@@ -35,6 +35,7 @@ class JvmFir2IrExtensions(
private val irDeserializer: JvmIrDeserializer,
private val mangler: KotlinMangler.IrMangler,
) : Fir2IrExtensions, JvmGeneratorExtensions {
override val parametersAreAssignable: Boolean get() = true
override val externalOverridabilityConditions: List<IrExternalOverridabilityCondition> = emptyList() // TODO: KT-61370, KT-61804
override val classNameOverride: MutableMap<IrClass, JvmClassName> = mutableMapOf()
override val cachedFields = CachedFieldsForObjectInstances(IrFactoryImpl, configuration.languageVersionSettings)
@@ -562,6 +562,7 @@ internal fun IrDeclarationParent.declareThisReceiverParameter(
endOffset: Int = this.endOffset,
name: Name = SpecialNames.THIS,
explicitReceiver: FirReceiverParameter? = null,
isAssignable: Boolean = false
): IrValueParameter {
return symbolTable.irFactory.createValueParameter(
startOffset = startOffset,
@@ -569,7 +570,7 @@ internal fun IrDeclarationParent.declareThisReceiverParameter(
origin = thisOrigin,
name = name,
type = thisType,
isAssignable = false,
isAssignable = isAssignable,
symbol = IrValueParameterSymbolImpl(),
index = UNDEFINED_PARAMETER_INDEX,
varargElementType = null,
@@ -16,6 +16,12 @@ import org.jetbrains.kotlin.ir.util.SymbolTable
interface Fir2IrExtensions {
val irNeedsDeserialization: Boolean
/**
* Determines if parameters of tailrec functions should be generated with isAssignable = true
*/
val parametersAreAssignable: Boolean
val externalOverridabilityConditions: List<IrExternalOverridabilityCondition>
fun generateOrGetFacadeClass(declaration: IrMemberWithContainerSource, components: Fir2IrComponents): IrClass?
@@ -35,6 +41,9 @@ interface Fir2IrExtensions {
override val irNeedsDeserialization: Boolean
get() = false
override val parametersAreAssignable: Boolean
get() = false
override val externalOverridabilityConditions: List<IrExternalOverridabilityCondition> = emptyList()
override fun generateOrGetFacadeClass(declaration: IrMemberWithContainerSource, components: Fir2IrComponents): IrClass? = null
override fun deserializeToplevelClass(irClass: IrClass, components: Fir2IrComponents): Boolean = false
@@ -42,4 +51,4 @@ interface Fir2IrExtensions {
override fun findInjectedValue(calleeReference: FirReference, conversionScope: Fir2IrConversionScope) = null
override fun hasBackingField(property: FirProperty, session: FirSession): Boolean = property.hasBackingField
}
}
}
@@ -705,6 +705,7 @@ class Fir2IrCallableDeclarationsGenerator(val components: Fir2IrComponents) : Fi
endOffset = endOffset,
name = name,
explicitReceiver = receiver,
isAssignable = function.shouldParametersBeAssignable()
)
}
}
@@ -750,7 +751,7 @@ class Fir2IrCallableDeclarationsGenerator(val components: Fir2IrComponents) : Fi
origin = origin,
name = valueParameter.name,
type = type,
isAssignable = false,
isAssignable = valueParameter.containingFunctionSymbol.fir.shouldParametersBeAssignable(),
symbol = IrValueParameterSymbolImpl(),
index = index,
varargElementType = valueParameter.varargElementType?.toIrType(typeOrigin),
@@ -1026,3 +1027,8 @@ internal fun IrDeclarationParent?.isExternalParent(): Boolean {
}
return this is Fir2IrLazyClass || this is IrExternalPackageFragment
}
context(Fir2IrComponents)
internal fun FirCallableDeclaration?.shouldParametersBeAssignable(): Boolean {
return extensions.parametersAreAssignable && this?.isTailRec == true
}
@@ -54597,6 +54597,12 @@ public class FirLightTreeBlackBoxCodegenTestGenerated extends AbstractFirLightTr
runTest("compiler/testData/codegen/box/vararg/varargInJava.kt");
}
@Test
@TestMetadata("varargInTailrec.kt")
public void testVarargInTailrec() throws Exception {
runTest("compiler/testData/codegen/box/vararg/varargInTailrec.kt");
}
@Test
@TestMetadata("varargsAndFunctionLiterals.kt")
public void testVarargsAndFunctionLiterals() throws Exception {
@@ -54597,6 +54597,12 @@ public class FirLightTreeBlackBoxCodegenWithIrFakeOverrideGeneratorTestGenerated
runTest("compiler/testData/codegen/box/vararg/varargInJava.kt");
}
@Test
@TestMetadata("varargInTailrec.kt")
public void testVarargInTailrec() throws Exception {
runTest("compiler/testData/codegen/box/vararg/varargInTailrec.kt");
}
@Test
@TestMetadata("varargsAndFunctionLiterals.kt")
public void testVarargsAndFunctionLiterals() throws Exception {
@@ -54597,6 +54597,12 @@ public class FirPsiBlackBoxCodegenTestGenerated extends AbstractFirPsiBlackBoxCo
runTest("compiler/testData/codegen/box/vararg/varargInJava.kt");
}
@Test
@TestMetadata("varargInTailrec.kt")
public void testVarargInTailrec() throws Exception {
runTest("compiler/testData/codegen/box/vararg/varargInTailrec.kt");
}
@Test
@TestMetadata("varargsAndFunctionLiterals.kt")
public void testVarargsAndFunctionLiterals() throws Exception {
+19
View File
@@ -0,0 +1,19 @@
// ISSUE: KT-63973
// WITH_STDLIB
tailrec fun <T> foo(vararg items: String, fn: (String) -> T): T = when (items.size) {
0 -> fn("")
else -> foo(*items.drop(1).toTypedArray()) {
fn(items.first())
}
}
fun box(): String {
val result = buildString {
foo("abcde") { append(it) }
}
if (result != "abcde") {
return "Fail: $result"
}
return "OK"
}
@@ -50709,6 +50709,12 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest {
runTest("compiler/testData/codegen/box/vararg/varargInJava.kt");
}
@Test
@TestMetadata("varargInTailrec.kt")
public void testVarargInTailrec() throws Exception {
runTest("compiler/testData/codegen/box/vararg/varargInTailrec.kt");
}
@Test
@TestMetadata("varargsAndFunctionLiterals.kt")
public void testVarargsAndFunctionLiterals() throws Exception {
@@ -53949,6 +53949,12 @@ public class IrBlackBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTes
runTest("compiler/testData/codegen/box/vararg/varargInJava.kt");
}
@Test
@TestMetadata("varargInTailrec.kt")
public void testVarargInTailrec() throws Exception {
runTest("compiler/testData/codegen/box/vararg/varargInTailrec.kt");
}
@Test
@TestMetadata("varargsAndFunctionLiterals.kt")
public void testVarargsAndFunctionLiterals() throws Exception {
@@ -53949,6 +53949,12 @@ public class IrBlackBoxCodegenWithIrInlinerTestGenerated extends AbstractIrBlack
runTest("compiler/testData/codegen/box/vararg/varargInJava.kt");
}
@Test
@TestMetadata("varargInTailrec.kt")
public void testVarargInTailrec() throws Exception {
runTest("compiler/testData/codegen/box/vararg/varargInTailrec.kt");
}
@Test
@TestMetadata("varargsAndFunctionLiterals.kt")
public void testVarargsAndFunctionLiterals() throws Exception {
@@ -43626,6 +43626,11 @@ public class LightAnalysisModeTestGenerated extends AbstractLightAnalysisModeTes
runTest("compiler/testData/codegen/box/vararg/varargInJava.kt");
}
@TestMetadata("varargInTailrec.kt")
public void testVarargInTailrec() throws Exception {
runTest("compiler/testData/codegen/box/vararg/varargInTailrec.kt");
}
@TestMetadata("varargsAndFunctionLiterals.kt")
public void testVarargsAndFunctionLiterals() throws Exception {
runTest("compiler/testData/codegen/box/vararg/varargsAndFunctionLiterals.kt");
@@ -37923,6 +37923,12 @@ public class FirJsCodegenBoxTestGenerated extends AbstractFirJsCodegenBoxTest {
runTest("compiler/testData/codegen/box/vararg/varargInFunParam.kt");
}
@Test
@TestMetadata("varargInTailrec.kt")
public void testVarargInTailrec() throws Exception {
runTest("compiler/testData/codegen/box/vararg/varargInTailrec.kt");
}
@Test
@TestMetadata("varargsAndFunctionLiterals.kt")
public void testVarargsAndFunctionLiterals() throws Exception {
@@ -37923,6 +37923,12 @@ public class FirJsES6CodegenBoxTestGenerated extends AbstractFirJsES6CodegenBoxT
runTest("compiler/testData/codegen/box/vararg/varargInFunParam.kt");
}
@Test
@TestMetadata("varargInTailrec.kt")
public void testVarargInTailrec() throws Exception {
runTest("compiler/testData/codegen/box/vararg/varargInTailrec.kt");
}
@Test
@TestMetadata("varargsAndFunctionLiterals.kt")
public void testVarargsAndFunctionLiterals() throws Exception {
@@ -37377,6 +37377,12 @@ public class IrJsCodegenBoxTestGenerated extends AbstractIrJsCodegenBoxTest {
runTest("compiler/testData/codegen/box/vararg/varargInFunParam.kt");
}
@Test
@TestMetadata("varargInTailrec.kt")
public void testVarargInTailrec() throws Exception {
runTest("compiler/testData/codegen/box/vararg/varargInTailrec.kt");
}
@Test
@TestMetadata("varargsAndFunctionLiterals.kt")
public void testVarargsAndFunctionLiterals() throws Exception {
@@ -37377,6 +37377,12 @@ public class IrJsES6CodegenBoxTestGenerated extends AbstractIrJsES6CodegenBoxTes
runTest("compiler/testData/codegen/box/vararg/varargInFunParam.kt");
}
@Test
@TestMetadata("varargInTailrec.kt")
public void testVarargInTailrec() throws Exception {
runTest("compiler/testData/codegen/box/vararg/varargInTailrec.kt");
}
@Test
@TestMetadata("varargsAndFunctionLiterals.kt")
public void testVarargsAndFunctionLiterals() throws Exception {
@@ -53,6 +53,7 @@ internal val KlibFactories = KlibMetadataFactories(::KonanBuiltIns, DynamicTypeD
internal object NativeFir2IrExtensions : Fir2IrExtensions {
override val irNeedsDeserialization = false
override val parametersAreAssignable: Boolean get() = false
override val externalOverridabilityConditions = listOf(IrObjCOverridabilityCondition)
override fun generateOrGetFacadeClass(declaration: IrMemberWithContainerSource, components: Fir2IrComponents) = null
override fun deserializeToplevelClass(irClass: IrClass, components: Fir2IrComponents) = false
@@ -41696,6 +41696,12 @@ public class FirNativeCodegenBoxTestGenerated extends AbstractNativeCodegenBoxTe
runTest("compiler/testData/codegen/box/vararg/varargInFunParam.kt");
}
@Test
@TestMetadata("varargInTailrec.kt")
public void testVarargInTailrec() throws Exception {
runTest("compiler/testData/codegen/box/vararg/varargInTailrec.kt");
}
@Test
@TestMetadata("varargsAndFunctionLiterals.kt")
public void testVarargsAndFunctionLiterals() throws Exception {
@@ -42760,6 +42760,12 @@ public class FirNativeCodegenBoxTestNoPLGenerated extends AbstractNativeCodegenB
runTest("compiler/testData/codegen/box/vararg/varargInFunParam.kt");
}
@Test
@TestMetadata("varargInTailrec.kt")
public void testVarargInTailrec() throws Exception {
runTest("compiler/testData/codegen/box/vararg/varargInTailrec.kt");
}
@Test
@TestMetadata("varargsAndFunctionLiterals.kt")
public void testVarargsAndFunctionLiterals() throws Exception {
@@ -40074,6 +40074,12 @@ public class NativeCodegenBoxTestGenerated extends AbstractNativeCodegenBoxTest
runTest("compiler/testData/codegen/box/vararg/varargInFunParam.kt");
}
@Test
@TestMetadata("varargInTailrec.kt")
public void testVarargInTailrec() throws Exception {
runTest("compiler/testData/codegen/box/vararg/varargInTailrec.kt");
}
@Test
@TestMetadata("varargsAndFunctionLiterals.kt")
public void testVarargsAndFunctionLiterals() throws Exception {
@@ -41127,6 +41127,12 @@ public class NativeCodegenBoxTestNoPLGenerated extends AbstractNativeCodegenBoxT
runTest("compiler/testData/codegen/box/vararg/varargInFunParam.kt");
}
@Test
@TestMetadata("varargInTailrec.kt")
public void testVarargInTailrec() throws Exception {
runTest("compiler/testData/codegen/box/vararg/varargInTailrec.kt");
}
@Test
@TestMetadata("varargsAndFunctionLiterals.kt")
public void testVarargsAndFunctionLiterals() throws Exception {
@@ -37815,6 +37815,12 @@ public class FirWasmCodegenBoxTestGenerated extends AbstractFirWasmCodegenBoxTes
runTest("compiler/testData/codegen/box/vararg/varargInFunParam.kt");
}
@Test
@TestMetadata("varargInTailrec.kt")
public void testVarargInTailrec() throws Exception {
runTest("compiler/testData/codegen/box/vararg/varargInTailrec.kt");
}
@Test
@TestMetadata("varargsAndFunctionLiterals.kt")
public void testVarargsAndFunctionLiterals() throws Exception {
@@ -37269,6 +37269,12 @@ public class K1WasmCodegenBoxTestGenerated extends AbstractK1WasmCodegenBoxTest
runTest("compiler/testData/codegen/box/vararg/varargInFunParam.kt");
}
@Test
@TestMetadata("varargInTailrec.kt")
public void testVarargInTailrec() throws Exception {
runTest("compiler/testData/codegen/box/vararg/varargInTailrec.kt");
}
@Test
@TestMetadata("varargsAndFunctionLiterals.kt")
public void testVarargsAndFunctionLiterals() throws Exception {