IR: close over the set of captured type parameters

This commit is contained in:
pyos
2020-01-16 11:18:04 +01:00
committed by Georgy Bronnikov
parent e9cea3358d
commit 6e6f4d0503
8 changed files with 49 additions and 15 deletions
@@ -55,7 +55,7 @@ class ClosureAnnotator(irFile: IrFile) {
}
private class ClosureBuilder(val owner: IrDeclaration) {
val capturedValues = mutableSetOf<IrValueSymbol>()
private val capturedValues = mutableSetOf<IrValueSymbol>()
private val declaredValues = mutableSetOf<IrValueDeclaration>()
private val includes = mutableSetOf<ClosureBuilder>()
@@ -70,15 +70,16 @@ class ClosureAnnotator(irFile: IrFile) {
* variables declared in the node.
*/
fun buildClosure(): Closure {
val result = mutableSetOf<IrValueSymbol>().apply { addAll(capturedValues) }
includes.forEach { builder ->
if (!builder.processed) {
builder.processed = true
builder.buildClosure().capturedValues.filterTo(result) { isExternal(it.owner) }
val subClosure = builder.buildClosure()
subClosure.capturedValues.filterTo(capturedValues) { isExternal(it.owner) }
subClosure.capturedTypeParameters.filterTo(capturedTypeParameters) { isExternal(it) }
}
}
// TODO: We can save the closure and reuse it.
return Closure(result.toList(), capturedTypeParameters.toList())
return Closure(capturedValues.toList(), capturedTypeParameters.toList())
}
@@ -110,18 +111,14 @@ class ClosureAnnotator(irFile: IrFile) {
fun seeType(type: IrType) {
if (type !is IrSimpleType) return
(type.classifier as? IrTypeParameterSymbol)?.let { typeParameterSymbol ->
val typeParameter = typeParameterSymbol.owner
if (isExternal(typeParameter))
capturedTypeParameters.add(typeParameter)
val classifier = type.classifier
if (classifier is IrTypeParameterSymbol && isExternal(classifier.owner) && capturedTypeParameters.add(classifier.owner))
classifier.owner.superTypes.forEach(::seeType)
type.arguments.forEach {
(it as? IrTypeProjection)?.type?.let(::seeType)
}
for (arg in type.arguments) {
(arg as? IrTypeProjection)?.let { seeType(arg.type) }
}
type.abbreviation?.let { abbreviation ->
for (arg in abbreviation.arguments) {
(arg as? IrTypeProjection)?.let { seeType(arg.type) }
}
type.abbreviation?.arguments?.forEach {
(it as? IrTypeProjection)?.type?.let(::seeType)
}
}
}
@@ -0,0 +1,7 @@
// IGNORE_BACKEND_FIR: JVM_IR
fun <T, V : T> f(x: V): V {
fun g(y: V) = y
return g(x)
}
fun box() = f<Any, String>("OK")
@@ -12023,6 +12023,11 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest {
runTest("compiler/testData/codegen/box/functions/localFunctions/callInlineLocalInLambda.kt");
}
@TestMetadata("captureUpperBoundedTypeParameter.kt")
public void testCaptureUpperBoundedTypeParameter() throws Exception {
runTest("compiler/testData/codegen/box/functions/localFunctions/captureUpperBoundedTypeParameter.kt");
}
@TestMetadata("definedWithinLambda.kt")
public void testDefinedWithinLambda() throws Exception {
runTest("compiler/testData/codegen/box/functions/localFunctions/definedWithinLambda.kt");
@@ -12023,6 +12023,11 @@ public class LightAnalysisModeTestGenerated extends AbstractLightAnalysisModeTes
runTest("compiler/testData/codegen/box/functions/localFunctions/callInlineLocalInLambda.kt");
}
@TestMetadata("captureUpperBoundedTypeParameter.kt")
public void testCaptureUpperBoundedTypeParameter() throws Exception {
runTest("compiler/testData/codegen/box/functions/localFunctions/captureUpperBoundedTypeParameter.kt");
}
@TestMetadata("definedWithinLambda.kt")
public void testDefinedWithinLambda() throws Exception {
runTest("compiler/testData/codegen/box/functions/localFunctions/definedWithinLambda.kt");
@@ -10873,6 +10873,11 @@ public class FirBlackBoxCodegenTestGenerated extends AbstractFirBlackBoxCodegenT
runTest("compiler/testData/codegen/box/functions/localFunctions/callInlineLocalInLambda.kt");
}
@TestMetadata("captureUpperBoundedTypeParameter.kt")
public void testCaptureUpperBoundedTypeParameter() throws Exception {
runTest("compiler/testData/codegen/box/functions/localFunctions/captureUpperBoundedTypeParameter.kt");
}
@TestMetadata("definedWithinLambda.kt")
public void testDefinedWithinLambda() throws Exception {
runTest("compiler/testData/codegen/box/functions/localFunctions/definedWithinLambda.kt");
@@ -10873,6 +10873,11 @@ public class IrBlackBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTes
runTest("compiler/testData/codegen/box/functions/localFunctions/callInlineLocalInLambda.kt");
}
@TestMetadata("captureUpperBoundedTypeParameter.kt")
public void testCaptureUpperBoundedTypeParameter() throws Exception {
runTest("compiler/testData/codegen/box/functions/localFunctions/captureUpperBoundedTypeParameter.kt");
}
@TestMetadata("definedWithinLambda.kt")
public void testDefinedWithinLambda() throws Exception {
runTest("compiler/testData/codegen/box/functions/localFunctions/definedWithinLambda.kt");
@@ -9383,6 +9383,11 @@ public class IrJsCodegenBoxTestGenerated extends AbstractIrJsCodegenBoxTest {
runTest("compiler/testData/codegen/box/functions/localFunctions/callInlineLocalInLambda.kt");
}
@TestMetadata("captureUpperBoundedTypeParameter.kt")
public void testCaptureUpperBoundedTypeParameter() throws Exception {
runTest("compiler/testData/codegen/box/functions/localFunctions/captureUpperBoundedTypeParameter.kt");
}
@TestMetadata("definedWithinLambda.kt")
public void testDefinedWithinLambda() throws Exception {
runTest("compiler/testData/codegen/box/functions/localFunctions/definedWithinLambda.kt");
@@ -10458,6 +10458,11 @@ public class JsCodegenBoxTestGenerated extends AbstractJsCodegenBoxTest {
runTest("compiler/testData/codegen/box/functions/localFunctions/callInlineLocalInLambda.kt");
}
@TestMetadata("captureUpperBoundedTypeParameter.kt")
public void testCaptureUpperBoundedTypeParameter() throws Exception {
runTest("compiler/testData/codegen/box/functions/localFunctions/captureUpperBoundedTypeParameter.kt");
}
@TestMetadata("definedWithinLambda.kt")
public void testDefinedWithinLambda() throws Exception {
runTest("compiler/testData/codegen/box/functions/localFunctions/definedWithinLambda.kt");