[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"); 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 @Test
@TestMetadata("varargsAndFunctionLiterals.kt") @TestMetadata("varargsAndFunctionLiterals.kt")
public void testVarargsAndFunctionLiterals() throws Exception { public void testVarargsAndFunctionLiterals() throws Exception {
@@ -55196,6 +55196,12 @@ public class LLFirReversedBlackBoxCodegenBasedTestGenerated extends AbstractLLFi
runTest("compiler/testData/codegen/box/vararg/varargInJava.kt"); 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 @Test
@TestMetadata("varargsAndFunctionLiterals.kt") @TestMetadata("varargsAndFunctionLiterals.kt")
public void testVarargsAndFunctionLiterals() throws Exception { public void testVarargsAndFunctionLiterals() throws Exception {
@@ -35,6 +35,7 @@ class JvmFir2IrExtensions(
private val irDeserializer: JvmIrDeserializer, private val irDeserializer: JvmIrDeserializer,
private val mangler: KotlinMangler.IrMangler, private val mangler: KotlinMangler.IrMangler,
) : Fir2IrExtensions, JvmGeneratorExtensions { ) : Fir2IrExtensions, JvmGeneratorExtensions {
override val parametersAreAssignable: Boolean get() = true
override val externalOverridabilityConditions: List<IrExternalOverridabilityCondition> = emptyList() // TODO: KT-61370, KT-61804 override val externalOverridabilityConditions: List<IrExternalOverridabilityCondition> = emptyList() // TODO: KT-61370, KT-61804
override val classNameOverride: MutableMap<IrClass, JvmClassName> = mutableMapOf() override val classNameOverride: MutableMap<IrClass, JvmClassName> = mutableMapOf()
override val cachedFields = CachedFieldsForObjectInstances(IrFactoryImpl, configuration.languageVersionSettings) override val cachedFields = CachedFieldsForObjectInstances(IrFactoryImpl, configuration.languageVersionSettings)
@@ -562,6 +562,7 @@ internal fun IrDeclarationParent.declareThisReceiverParameter(
endOffset: Int = this.endOffset, endOffset: Int = this.endOffset,
name: Name = SpecialNames.THIS, name: Name = SpecialNames.THIS,
explicitReceiver: FirReceiverParameter? = null, explicitReceiver: FirReceiverParameter? = null,
isAssignable: Boolean = false
): IrValueParameter { ): IrValueParameter {
return symbolTable.irFactory.createValueParameter( return symbolTable.irFactory.createValueParameter(
startOffset = startOffset, startOffset = startOffset,
@@ -569,7 +570,7 @@ internal fun IrDeclarationParent.declareThisReceiverParameter(
origin = thisOrigin, origin = thisOrigin,
name = name, name = name,
type = thisType, type = thisType,
isAssignable = false, isAssignable = isAssignable,
symbol = IrValueParameterSymbolImpl(), symbol = IrValueParameterSymbolImpl(),
index = UNDEFINED_PARAMETER_INDEX, index = UNDEFINED_PARAMETER_INDEX,
varargElementType = null, varargElementType = null,
@@ -16,6 +16,12 @@ import org.jetbrains.kotlin.ir.util.SymbolTable
interface Fir2IrExtensions { interface Fir2IrExtensions {
val irNeedsDeserialization: Boolean val irNeedsDeserialization: Boolean
/**
* Determines if parameters of tailrec functions should be generated with isAssignable = true
*/
val parametersAreAssignable: Boolean
val externalOverridabilityConditions: List<IrExternalOverridabilityCondition> val externalOverridabilityConditions: List<IrExternalOverridabilityCondition>
fun generateOrGetFacadeClass(declaration: IrMemberWithContainerSource, components: Fir2IrComponents): IrClass? fun generateOrGetFacadeClass(declaration: IrMemberWithContainerSource, components: Fir2IrComponents): IrClass?
@@ -35,6 +41,9 @@ interface Fir2IrExtensions {
override val irNeedsDeserialization: Boolean override val irNeedsDeserialization: Boolean
get() = false get() = false
override val parametersAreAssignable: Boolean
get() = false
override val externalOverridabilityConditions: List<IrExternalOverridabilityCondition> = emptyList() override val externalOverridabilityConditions: List<IrExternalOverridabilityCondition> = emptyList()
override fun generateOrGetFacadeClass(declaration: IrMemberWithContainerSource, components: Fir2IrComponents): IrClass? = null override fun generateOrGetFacadeClass(declaration: IrMemberWithContainerSource, components: Fir2IrComponents): IrClass? = null
override fun deserializeToplevelClass(irClass: IrClass, components: Fir2IrComponents): Boolean = false override fun deserializeToplevelClass(irClass: IrClass, components: Fir2IrComponents): Boolean = false
@@ -705,6 +705,7 @@ class Fir2IrCallableDeclarationsGenerator(val components: Fir2IrComponents) : Fi
endOffset = endOffset, endOffset = endOffset,
name = name, name = name,
explicitReceiver = receiver, explicitReceiver = receiver,
isAssignable = function.shouldParametersBeAssignable()
) )
} }
} }
@@ -750,7 +751,7 @@ class Fir2IrCallableDeclarationsGenerator(val components: Fir2IrComponents) : Fi
origin = origin, origin = origin,
name = valueParameter.name, name = valueParameter.name,
type = type, type = type,
isAssignable = false, isAssignable = valueParameter.containingFunctionSymbol.fir.shouldParametersBeAssignable(),
symbol = IrValueParameterSymbolImpl(), symbol = IrValueParameterSymbolImpl(),
index = index, index = index,
varargElementType = valueParameter.varargElementType?.toIrType(typeOrigin), varargElementType = valueParameter.varargElementType?.toIrType(typeOrigin),
@@ -1026,3 +1027,8 @@ internal fun IrDeclarationParent?.isExternalParent(): Boolean {
} }
return this is Fir2IrLazyClass || this is IrExternalPackageFragment 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"); 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 @Test
@TestMetadata("varargsAndFunctionLiterals.kt") @TestMetadata("varargsAndFunctionLiterals.kt")
public void testVarargsAndFunctionLiterals() throws Exception { public void testVarargsAndFunctionLiterals() throws Exception {
@@ -54597,6 +54597,12 @@ public class FirLightTreeBlackBoxCodegenWithIrFakeOverrideGeneratorTestGenerated
runTest("compiler/testData/codegen/box/vararg/varargInJava.kt"); 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 @Test
@TestMetadata("varargsAndFunctionLiterals.kt") @TestMetadata("varargsAndFunctionLiterals.kt")
public void testVarargsAndFunctionLiterals() throws Exception { public void testVarargsAndFunctionLiterals() throws Exception {
@@ -54597,6 +54597,12 @@ public class FirPsiBlackBoxCodegenTestGenerated extends AbstractFirPsiBlackBoxCo
runTest("compiler/testData/codegen/box/vararg/varargInJava.kt"); 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 @Test
@TestMetadata("varargsAndFunctionLiterals.kt") @TestMetadata("varargsAndFunctionLiterals.kt")
public void testVarargsAndFunctionLiterals() throws Exception { 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"); 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 @Test
@TestMetadata("varargsAndFunctionLiterals.kt") @TestMetadata("varargsAndFunctionLiterals.kt")
public void testVarargsAndFunctionLiterals() throws Exception { public void testVarargsAndFunctionLiterals() throws Exception {
@@ -53949,6 +53949,12 @@ public class IrBlackBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTes
runTest("compiler/testData/codegen/box/vararg/varargInJava.kt"); 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 @Test
@TestMetadata("varargsAndFunctionLiterals.kt") @TestMetadata("varargsAndFunctionLiterals.kt")
public void testVarargsAndFunctionLiterals() throws Exception { public void testVarargsAndFunctionLiterals() throws Exception {
@@ -53949,6 +53949,12 @@ public class IrBlackBoxCodegenWithIrInlinerTestGenerated extends AbstractIrBlack
runTest("compiler/testData/codegen/box/vararg/varargInJava.kt"); 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 @Test
@TestMetadata("varargsAndFunctionLiterals.kt") @TestMetadata("varargsAndFunctionLiterals.kt")
public void testVarargsAndFunctionLiterals() throws Exception { public void testVarargsAndFunctionLiterals() throws Exception {
@@ -43626,6 +43626,11 @@ public class LightAnalysisModeTestGenerated extends AbstractLightAnalysisModeTes
runTest("compiler/testData/codegen/box/vararg/varargInJava.kt"); 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") @TestMetadata("varargsAndFunctionLiterals.kt")
public void testVarargsAndFunctionLiterals() throws Exception { public void testVarargsAndFunctionLiterals() throws Exception {
runTest("compiler/testData/codegen/box/vararg/varargsAndFunctionLiterals.kt"); 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"); 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 @Test
@TestMetadata("varargsAndFunctionLiterals.kt") @TestMetadata("varargsAndFunctionLiterals.kt")
public void testVarargsAndFunctionLiterals() throws Exception { public void testVarargsAndFunctionLiterals() throws Exception {
@@ -37923,6 +37923,12 @@ public class FirJsES6CodegenBoxTestGenerated extends AbstractFirJsES6CodegenBoxT
runTest("compiler/testData/codegen/box/vararg/varargInFunParam.kt"); 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 @Test
@TestMetadata("varargsAndFunctionLiterals.kt") @TestMetadata("varargsAndFunctionLiterals.kt")
public void testVarargsAndFunctionLiterals() throws Exception { public void testVarargsAndFunctionLiterals() throws Exception {
@@ -37377,6 +37377,12 @@ public class IrJsCodegenBoxTestGenerated extends AbstractIrJsCodegenBoxTest {
runTest("compiler/testData/codegen/box/vararg/varargInFunParam.kt"); 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 @Test
@TestMetadata("varargsAndFunctionLiterals.kt") @TestMetadata("varargsAndFunctionLiterals.kt")
public void testVarargsAndFunctionLiterals() throws Exception { public void testVarargsAndFunctionLiterals() throws Exception {
@@ -37377,6 +37377,12 @@ public class IrJsES6CodegenBoxTestGenerated extends AbstractIrJsES6CodegenBoxTes
runTest("compiler/testData/codegen/box/vararg/varargInFunParam.kt"); 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 @Test
@TestMetadata("varargsAndFunctionLiterals.kt") @TestMetadata("varargsAndFunctionLiterals.kt")
public void testVarargsAndFunctionLiterals() throws Exception { public void testVarargsAndFunctionLiterals() throws Exception {
@@ -53,6 +53,7 @@ internal val KlibFactories = KlibMetadataFactories(::KonanBuiltIns, DynamicTypeD
internal object NativeFir2IrExtensions : Fir2IrExtensions { internal object NativeFir2IrExtensions : Fir2IrExtensions {
override val irNeedsDeserialization = false override val irNeedsDeserialization = false
override val parametersAreAssignable: Boolean get() = false
override val externalOverridabilityConditions = listOf(IrObjCOverridabilityCondition) override val externalOverridabilityConditions = listOf(IrObjCOverridabilityCondition)
override fun generateOrGetFacadeClass(declaration: IrMemberWithContainerSource, components: Fir2IrComponents) = null override fun generateOrGetFacadeClass(declaration: IrMemberWithContainerSource, components: Fir2IrComponents) = null
override fun deserializeToplevelClass(irClass: IrClass, components: Fir2IrComponents) = false 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"); 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 @Test
@TestMetadata("varargsAndFunctionLiterals.kt") @TestMetadata("varargsAndFunctionLiterals.kt")
public void testVarargsAndFunctionLiterals() throws Exception { public void testVarargsAndFunctionLiterals() throws Exception {
@@ -42760,6 +42760,12 @@ public class FirNativeCodegenBoxTestNoPLGenerated extends AbstractNativeCodegenB
runTest("compiler/testData/codegen/box/vararg/varargInFunParam.kt"); 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 @Test
@TestMetadata("varargsAndFunctionLiterals.kt") @TestMetadata("varargsAndFunctionLiterals.kt")
public void testVarargsAndFunctionLiterals() throws Exception { public void testVarargsAndFunctionLiterals() throws Exception {
@@ -40074,6 +40074,12 @@ public class NativeCodegenBoxTestGenerated extends AbstractNativeCodegenBoxTest
runTest("compiler/testData/codegen/box/vararg/varargInFunParam.kt"); 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 @Test
@TestMetadata("varargsAndFunctionLiterals.kt") @TestMetadata("varargsAndFunctionLiterals.kt")
public void testVarargsAndFunctionLiterals() throws Exception { public void testVarargsAndFunctionLiterals() throws Exception {
@@ -41127,6 +41127,12 @@ public class NativeCodegenBoxTestNoPLGenerated extends AbstractNativeCodegenBoxT
runTest("compiler/testData/codegen/box/vararg/varargInFunParam.kt"); 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 @Test
@TestMetadata("varargsAndFunctionLiterals.kt") @TestMetadata("varargsAndFunctionLiterals.kt")
public void testVarargsAndFunctionLiterals() throws Exception { public void testVarargsAndFunctionLiterals() throws Exception {
@@ -37815,6 +37815,12 @@ public class FirWasmCodegenBoxTestGenerated extends AbstractFirWasmCodegenBoxTes
runTest("compiler/testData/codegen/box/vararg/varargInFunParam.kt"); 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 @Test
@TestMetadata("varargsAndFunctionLiterals.kt") @TestMetadata("varargsAndFunctionLiterals.kt")
public void testVarargsAndFunctionLiterals() throws Exception { public void testVarargsAndFunctionLiterals() throws Exception {
@@ -37269,6 +37269,12 @@ public class K1WasmCodegenBoxTestGenerated extends AbstractK1WasmCodegenBoxTest
runTest("compiler/testData/codegen/box/vararg/varargInFunParam.kt"); 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 @Test
@TestMetadata("varargsAndFunctionLiterals.kt") @TestMetadata("varargsAndFunctionLiterals.kt")
public void testVarargsAndFunctionLiterals() throws Exception { public void testVarargsAndFunctionLiterals() throws Exception {