diff --git a/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/lower/ClosureAnnotator.kt b/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/lower/ClosureAnnotator.kt index 0186962c0c8..4dd4d399813 100644 --- a/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/lower/ClosureAnnotator.kt +++ b/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/lower/ClosureAnnotator.kt @@ -55,7 +55,7 @@ class ClosureAnnotator(irFile: IrFile) { } private class ClosureBuilder(val owner: IrDeclaration) { - val capturedValues = mutableSetOf() + private val capturedValues = mutableSetOf() private val declaredValues = mutableSetOf() private val includes = mutableSetOf() @@ -70,15 +70,16 @@ class ClosureAnnotator(irFile: IrFile) { * variables declared in the node. */ fun buildClosure(): Closure { - val result = mutableSetOf().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) } } } diff --git a/compiler/testData/codegen/box/functions/localFunctions/captureUpperBoundedTypeParameter.kt b/compiler/testData/codegen/box/functions/localFunctions/captureUpperBoundedTypeParameter.kt new file mode 100644 index 00000000000..98dadda9421 --- /dev/null +++ b/compiler/testData/codegen/box/functions/localFunctions/captureUpperBoundedTypeParameter.kt @@ -0,0 +1,7 @@ +// IGNORE_BACKEND_FIR: JVM_IR +fun f(x: V): V { + fun g(y: V) = y + return g(x) +} + +fun box() = f("OK") diff --git a/compiler/tests/org/jetbrains/kotlin/codegen/BlackBoxCodegenTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/codegen/BlackBoxCodegenTestGenerated.java index a5659d25810..688de975dbb 100644 --- a/compiler/tests/org/jetbrains/kotlin/codegen/BlackBoxCodegenTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/codegen/BlackBoxCodegenTestGenerated.java @@ -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"); diff --git a/compiler/tests/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java index 4eb805e115b..e73244c73a4 100644 --- a/compiler/tests/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java @@ -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"); diff --git a/compiler/tests/org/jetbrains/kotlin/codegen/ir/FirBlackBoxCodegenTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/codegen/ir/FirBlackBoxCodegenTestGenerated.java index 3462893016c..c94a189cddc 100644 --- a/compiler/tests/org/jetbrains/kotlin/codegen/ir/FirBlackBoxCodegenTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/codegen/ir/FirBlackBoxCodegenTestGenerated.java @@ -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"); diff --git a/compiler/tests/org/jetbrains/kotlin/codegen/ir/IrBlackBoxCodegenTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/codegen/ir/IrBlackBoxCodegenTestGenerated.java index 85cd454a3a9..b6d30a8b6cc 100644 --- a/compiler/tests/org/jetbrains/kotlin/codegen/ir/IrBlackBoxCodegenTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/codegen/ir/IrBlackBoxCodegenTestGenerated.java @@ -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"); diff --git a/js/js.tests/test/org/jetbrains/kotlin/js/test/ir/semantics/IrJsCodegenBoxTestGenerated.java b/js/js.tests/test/org/jetbrains/kotlin/js/test/ir/semantics/IrJsCodegenBoxTestGenerated.java index 2a3553d1f31..f33f0780e42 100644 --- a/js/js.tests/test/org/jetbrains/kotlin/js/test/ir/semantics/IrJsCodegenBoxTestGenerated.java +++ b/js/js.tests/test/org/jetbrains/kotlin/js/test/ir/semantics/IrJsCodegenBoxTestGenerated.java @@ -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"); diff --git a/js/js.tests/test/org/jetbrains/kotlin/js/test/semantics/JsCodegenBoxTestGenerated.java b/js/js.tests/test/org/jetbrains/kotlin/js/test/semantics/JsCodegenBoxTestGenerated.java index d94246b0ec6..9abe1c4fc8b 100644 --- a/js/js.tests/test/org/jetbrains/kotlin/js/test/semantics/JsCodegenBoxTestGenerated.java +++ b/js/js.tests/test/org/jetbrains/kotlin/js/test/semantics/JsCodegenBoxTestGenerated.java @@ -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");