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) { private class ClosureBuilder(val owner: IrDeclaration) {
val capturedValues = mutableSetOf<IrValueSymbol>() private val capturedValues = mutableSetOf<IrValueSymbol>()
private val declaredValues = mutableSetOf<IrValueDeclaration>() private val declaredValues = mutableSetOf<IrValueDeclaration>()
private val includes = mutableSetOf<ClosureBuilder>() private val includes = mutableSetOf<ClosureBuilder>()
@@ -70,15 +70,16 @@ class ClosureAnnotator(irFile: IrFile) {
* variables declared in the node. * variables declared in the node.
*/ */
fun buildClosure(): Closure { fun buildClosure(): Closure {
val result = mutableSetOf<IrValueSymbol>().apply { addAll(capturedValues) }
includes.forEach { builder -> includes.forEach { builder ->
if (!builder.processed) { if (!builder.processed) {
builder.processed = true 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. // 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) { fun seeType(type: IrType) {
if (type !is IrSimpleType) return if (type !is IrSimpleType) return
(type.classifier as? IrTypeParameterSymbol)?.let { typeParameterSymbol -> val classifier = type.classifier
val typeParameter = typeParameterSymbol.owner if (classifier is IrTypeParameterSymbol && isExternal(classifier.owner) && capturedTypeParameters.add(classifier.owner))
if (isExternal(typeParameter)) classifier.owner.superTypes.forEach(::seeType)
capturedTypeParameters.add(typeParameter) type.arguments.forEach {
(it as? IrTypeProjection)?.type?.let(::seeType)
} }
for (arg in type.arguments) { type.abbreviation?.arguments?.forEach {
(arg as? IrTypeProjection)?.let { seeType(arg.type) } (it as? IrTypeProjection)?.type?.let(::seeType)
}
type.abbreviation?.let { abbreviation ->
for (arg in abbreviation.arguments) {
(arg as? IrTypeProjection)?.let { seeType(arg.type) }
}
} }
} }
} }
@@ -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"); 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") @TestMetadata("definedWithinLambda.kt")
public void testDefinedWithinLambda() throws Exception { public void testDefinedWithinLambda() throws Exception {
runTest("compiler/testData/codegen/box/functions/localFunctions/definedWithinLambda.kt"); 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"); 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") @TestMetadata("definedWithinLambda.kt")
public void testDefinedWithinLambda() throws Exception { public void testDefinedWithinLambda() throws Exception {
runTest("compiler/testData/codegen/box/functions/localFunctions/definedWithinLambda.kt"); 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"); 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") @TestMetadata("definedWithinLambda.kt")
public void testDefinedWithinLambda() throws Exception { public void testDefinedWithinLambda() throws Exception {
runTest("compiler/testData/codegen/box/functions/localFunctions/definedWithinLambda.kt"); 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"); 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") @TestMetadata("definedWithinLambda.kt")
public void testDefinedWithinLambda() throws Exception { public void testDefinedWithinLambda() throws Exception {
runTest("compiler/testData/codegen/box/functions/localFunctions/definedWithinLambda.kt"); 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"); 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") @TestMetadata("definedWithinLambda.kt")
public void testDefinedWithinLambda() throws Exception { public void testDefinedWithinLambda() throws Exception {
runTest("compiler/testData/codegen/box/functions/localFunctions/definedWithinLambda.kt"); 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"); 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") @TestMetadata("definedWithinLambda.kt")
public void testDefinedWithinLambda() throws Exception { public void testDefinedWithinLambda() throws Exception {
runTest("compiler/testData/codegen/box/functions/localFunctions/definedWithinLambda.kt"); runTest("compiler/testData/codegen/box/functions/localFunctions/definedWithinLambda.kt");