JVM: do not reify methods of objects in lambdas
All type parameters used in them are not from the inline function anyway.
This commit is contained in:
+6
-6
@@ -295,7 +295,6 @@ class AnonymousObjectTransformer(
|
|||||||
capturedBuilder: ParametersBuilder,
|
capturedBuilder: ParametersBuilder,
|
||||||
isConstructor: Boolean
|
isConstructor: Boolean
|
||||||
): InlineResult {
|
): InlineResult {
|
||||||
val typeParametersToReify = inliningContext.root.inlineMethodReifier.reifyInstructions(sourceNode)
|
|
||||||
val parameters =
|
val parameters =
|
||||||
if (isConstructor) capturedBuilder.buildParameters() else getMethodParametersWithCaptured(capturedBuilder, sourceNode)
|
if (isConstructor) capturedBuilder.buildParameters() else getMethodParametersWithCaptured(capturedBuilder, sourceNode)
|
||||||
|
|
||||||
@@ -304,7 +303,10 @@ class AnonymousObjectTransformer(
|
|||||||
transformationInfo.capturedLambdasToInline, parentRemapper, isConstructor
|
transformationInfo.capturedLambdasToInline, parentRemapper, isConstructor
|
||||||
)
|
)
|
||||||
|
|
||||||
val inliner = MethodInliner(
|
val reifiedTypeParametersUsages = if (inliningContext.shouldReifyTypeParametersInObjects)
|
||||||
|
inliningContext.root.inlineMethodReifier.reifyInstructions(sourceNode)
|
||||||
|
else null
|
||||||
|
val result = MethodInliner(
|
||||||
sourceNode,
|
sourceNode,
|
||||||
parameters,
|
parameters,
|
||||||
inliningContext.subInline(transformationInfo.nameGenerator),
|
inliningContext.subInline(transformationInfo.nameGenerator),
|
||||||
@@ -319,10 +321,8 @@ class AnonymousObjectTransformer(
|
|||||||
inliningContext.callSiteInfo.file,
|
inliningContext.callSiteInfo.file,
|
||||||
inliningContext.callSiteInfo.lineNumber
|
inliningContext.callSiteInfo.lineNumber
|
||||||
), null
|
), null
|
||||||
)
|
).doInline(deferringVisitor, LocalVarRemapper(parameters, 0), false, mapOf())
|
||||||
|
reifiedTypeParametersUsages?.let(result.reifiedTypeParametersUsages::mergeAll)
|
||||||
val result = inliner.doInline(deferringVisitor, LocalVarRemapper(parameters, 0), false, mapOf())
|
|
||||||
result.reifiedTypeParametersUsages.mergeAll(typeParametersToReify)
|
|
||||||
deferringVisitor.visitMaxs(-1, -1)
|
deferringVisitor.visitMaxs(-1, -1)
|
||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -44,8 +44,16 @@ open class InliningContext(
|
|||||||
val lambdaInfo: LambdaInfo?,
|
val lambdaInfo: LambdaInfo?,
|
||||||
val classRegeneration: Boolean
|
val classRegeneration: Boolean
|
||||||
) {
|
) {
|
||||||
|
val isInliningLambda
|
||||||
|
get() = lambdaInfo != null
|
||||||
|
|
||||||
val isInliningLambda = lambdaInfo != null
|
// Consider this arrangement:
|
||||||
|
// inline fun <reified T> f(x: () -> Unit = { /* uses `T` in a local class */ }) = x()
|
||||||
|
// inline fun <reified V> g() = f<...> { /* uses `V` in a local class */ }
|
||||||
|
// When inlining `f` into `g`, we need to reify the contents of the default for `x` (if it was used), but not the
|
||||||
|
// contents of the lambda passed as the argument in `g` as all reified type parameters used by the latter are not from `f`.
|
||||||
|
val shouldReifyTypeParametersInObjects: Boolean
|
||||||
|
get() = lambdaInfo == null || lambdaInfo is DefaultLambda
|
||||||
|
|
||||||
var generateAssertField = false
|
var generateAssertField = false
|
||||||
|
|
||||||
@@ -54,7 +62,8 @@ open class InliningContext(
|
|||||||
|
|
||||||
var isContinuation: Boolean = false
|
var isContinuation: Boolean = false
|
||||||
|
|
||||||
val isRoot: Boolean = parent == null
|
val isRoot: Boolean
|
||||||
|
get() = parent == null
|
||||||
|
|
||||||
val root: RootInliningContext
|
val root: RootInliningContext
|
||||||
get() = if (isRoot) this as RootInliningContext else parent!!.root
|
get() = if (isRoot) this as RootInliningContext else parent!!.root
|
||||||
|
|||||||
@@ -318,14 +318,8 @@ class MethodInliner(
|
|||||||
super.visitMethodInsn(opcode, owner, name, desc, itf)
|
super.visitMethodInsn(opcode, owner, name, desc, itf)
|
||||||
}
|
}
|
||||||
} else if (ReifiedTypeInliner.isNeedClassReificationMarker(MethodInsnNode(opcode, owner, name, desc, false))) {
|
} else if (ReifiedTypeInliner.isNeedClassReificationMarker(MethodInsnNode(opcode, owner, name, desc, false))) {
|
||||||
// Consider this arrangement:
|
// If objects are reified, the marker will be recreated by `handleAnonymousObjectRegeneration` above.
|
||||||
// inline fun <reified T> f(x: () -> Unit = { /* uses `T` in a local class */ }) = x()
|
if (!inliningContext.shouldReifyTypeParametersInObjects) {
|
||||||
// inline fun <reified V> g() = f<...> { /* uses `V` in a local class */ }
|
|
||||||
// When inlining `f` into `g`, we need to erase class reification markers from `f` and the default lambda
|
|
||||||
// (they will be recreated by `handleAnonymousObjectRegeneration` above if `T` is instantiated with another
|
|
||||||
// reified type parameter), but not from the lambda passed to `f` in `g` (as reified type parameters inside
|
|
||||||
// it do not belong to `f`, thus we cannot substitute them yet).
|
|
||||||
if (inliningContext.isInliningLambda && inliningContext.lambdaInfo !is DefaultLambda) {
|
|
||||||
super.visitMethodInsn(opcode, owner, name, desc, itf)
|
super.visitMethodInsn(opcode, owner, name, desc, itf)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
+6
@@ -3822,6 +3822,12 @@ public class FirBlackBoxInlineCodegenTestGenerated extends AbstractFirBlackBoxIn
|
|||||||
runTest("compiler/testData/codegen/boxInline/reified/kt9637_2.kt");
|
runTest("compiler/testData/codegen/boxInline/reified/kt9637_2.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("nameClash.kt")
|
||||||
|
public void testNameClash() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/boxInline/reified/nameClash.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@TestMetadata("nonCapturingObjectInLambda.kt")
|
@TestMetadata("nonCapturingObjectInLambda.kt")
|
||||||
public void testNonCapturingObjectInLambda() throws Exception {
|
public void testNonCapturingObjectInLambda() throws Exception {
|
||||||
|
|||||||
@@ -0,0 +1,16 @@
|
|||||||
|
// FILE: 1.kt
|
||||||
|
package test
|
||||||
|
|
||||||
|
inline fun <reified T> f(x: () -> String) = x()
|
||||||
|
|
||||||
|
inline fun <reified T> g() = f<Unit> {
|
||||||
|
val x = { T::class.simpleName }
|
||||||
|
x()!!
|
||||||
|
}
|
||||||
|
|
||||||
|
// FILE: 2.kt
|
||||||
|
import test.*
|
||||||
|
|
||||||
|
class OK
|
||||||
|
|
||||||
|
fun box() = g<OK>()
|
||||||
+6
@@ -3822,6 +3822,12 @@ public class BlackBoxInlineCodegenTestGenerated extends AbstractBlackBoxInlineCo
|
|||||||
runTest("compiler/testData/codegen/boxInline/reified/kt9637_2.kt");
|
runTest("compiler/testData/codegen/boxInline/reified/kt9637_2.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("nameClash.kt")
|
||||||
|
public void testNameClash() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/boxInline/reified/nameClash.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@TestMetadata("nonCapturingObjectInLambda.kt")
|
@TestMetadata("nonCapturingObjectInLambda.kt")
|
||||||
public void testNonCapturingObjectInLambda() throws Exception {
|
public void testNonCapturingObjectInLambda() throws Exception {
|
||||||
|
|||||||
+6
@@ -3822,6 +3822,12 @@ public class CompileKotlinAgainstInlineKotlinTestGenerated extends AbstractCompi
|
|||||||
runTest("compiler/testData/codegen/boxInline/reified/kt9637_2.kt");
|
runTest("compiler/testData/codegen/boxInline/reified/kt9637_2.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("nameClash.kt")
|
||||||
|
public void testNameClash() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/boxInline/reified/nameClash.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@TestMetadata("nonCapturingObjectInLambda.kt")
|
@TestMetadata("nonCapturingObjectInLambda.kt")
|
||||||
public void testNonCapturingObjectInLambda() throws Exception {
|
public void testNonCapturingObjectInLambda() throws Exception {
|
||||||
|
|||||||
+6
@@ -3822,6 +3822,12 @@ public class IrBlackBoxInlineCodegenTestGenerated extends AbstractIrBlackBoxInli
|
|||||||
runTest("compiler/testData/codegen/boxInline/reified/kt9637_2.kt");
|
runTest("compiler/testData/codegen/boxInline/reified/kt9637_2.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("nameClash.kt")
|
||||||
|
public void testNameClash() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/boxInline/reified/nameClash.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@TestMetadata("nonCapturingObjectInLambda.kt")
|
@TestMetadata("nonCapturingObjectInLambda.kt")
|
||||||
public void testNonCapturingObjectInLambda() throws Exception {
|
public void testNonCapturingObjectInLambda() throws Exception {
|
||||||
|
|||||||
+6
@@ -3822,6 +3822,12 @@ public class IrCompileKotlinAgainstInlineKotlinTestGenerated extends AbstractIrC
|
|||||||
runTest("compiler/testData/codegen/boxInline/reified/kt9637_2.kt");
|
runTest("compiler/testData/codegen/boxInline/reified/kt9637_2.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("nameClash.kt")
|
||||||
|
public void testNameClash() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/boxInline/reified/nameClash.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@TestMetadata("nonCapturingObjectInLambda.kt")
|
@TestMetadata("nonCapturingObjectInLambda.kt")
|
||||||
public void testNonCapturingObjectInLambda() throws Exception {
|
public void testNonCapturingObjectInLambda() throws Exception {
|
||||||
|
|||||||
+6
@@ -3822,6 +3822,12 @@ public class JvmIrAgainstOldBoxInlineTestGenerated extends AbstractJvmIrAgainstO
|
|||||||
runTest("compiler/testData/codegen/boxInline/reified/kt9637_2.kt");
|
runTest("compiler/testData/codegen/boxInline/reified/kt9637_2.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("nameClash.kt")
|
||||||
|
public void testNameClash() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/boxInline/reified/nameClash.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@TestMetadata("nonCapturingObjectInLambda.kt")
|
@TestMetadata("nonCapturingObjectInLambda.kt")
|
||||||
public void testNonCapturingObjectInLambda() throws Exception {
|
public void testNonCapturingObjectInLambda() throws Exception {
|
||||||
|
|||||||
+6
@@ -3822,6 +3822,12 @@ public class JvmOldAgainstIrBoxInlineTestGenerated extends AbstractJvmOldAgainst
|
|||||||
runTest("compiler/testData/codegen/boxInline/reified/kt9637_2.kt");
|
runTest("compiler/testData/codegen/boxInline/reified/kt9637_2.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("nameClash.kt")
|
||||||
|
public void testNameClash() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/boxInline/reified/nameClash.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@TestMetadata("nonCapturingObjectInLambda.kt")
|
@TestMetadata("nonCapturingObjectInLambda.kt")
|
||||||
public void testNonCapturingObjectInLambda() throws Exception {
|
public void testNonCapturingObjectInLambda() throws Exception {
|
||||||
|
|||||||
+5
@@ -3085,6 +3085,11 @@ public class IrJsCodegenInlineES6TestGenerated extends AbstractIrJsCodegenInline
|
|||||||
runTest("compiler/testData/codegen/boxInline/reified/kt9637_2.kt");
|
runTest("compiler/testData/codegen/boxInline/reified/kt9637_2.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("nameClash.kt")
|
||||||
|
public void testNameClash() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/boxInline/reified/nameClash.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("nonCapturingObjectInLambda.kt")
|
@TestMetadata("nonCapturingObjectInLambda.kt")
|
||||||
public void testNonCapturingObjectInLambda() throws Exception {
|
public void testNonCapturingObjectInLambda() throws Exception {
|
||||||
runTest("compiler/testData/codegen/boxInline/reified/nonCapturingObjectInLambda.kt");
|
runTest("compiler/testData/codegen/boxInline/reified/nonCapturingObjectInLambda.kt");
|
||||||
|
|||||||
Generated
+5
@@ -3085,6 +3085,11 @@ public class IrJsCodegenInlineTestGenerated extends AbstractIrJsCodegenInlineTes
|
|||||||
runTest("compiler/testData/codegen/boxInline/reified/kt9637_2.kt");
|
runTest("compiler/testData/codegen/boxInline/reified/kt9637_2.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("nameClash.kt")
|
||||||
|
public void testNameClash() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/boxInline/reified/nameClash.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("nonCapturingObjectInLambda.kt")
|
@TestMetadata("nonCapturingObjectInLambda.kt")
|
||||||
public void testNonCapturingObjectInLambda() throws Exception {
|
public void testNonCapturingObjectInLambda() throws Exception {
|
||||||
runTest("compiler/testData/codegen/boxInline/reified/nonCapturingObjectInLambda.kt");
|
runTest("compiler/testData/codegen/boxInline/reified/nonCapturingObjectInLambda.kt");
|
||||||
|
|||||||
Generated
+5
@@ -3085,6 +3085,11 @@ public class JsCodegenInlineTestGenerated extends AbstractJsCodegenInlineTest {
|
|||||||
runTest("compiler/testData/codegen/boxInline/reified/kt9637_2.kt");
|
runTest("compiler/testData/codegen/boxInline/reified/kt9637_2.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("nameClash.kt")
|
||||||
|
public void testNameClash() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/boxInline/reified/nameClash.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("nonCapturingObjectInLambda.kt")
|
@TestMetadata("nonCapturingObjectInLambda.kt")
|
||||||
public void testNonCapturingObjectInLambda() throws Exception {
|
public void testNonCapturingObjectInLambda() throws Exception {
|
||||||
runTest("compiler/testData/codegen/boxInline/reified/nonCapturingObjectInLambda.kt");
|
runTest("compiler/testData/codegen/boxInline/reified/nonCapturingObjectInLambda.kt");
|
||||||
|
|||||||
Reference in New Issue
Block a user