JVM: push down implicit coercion to Unit in IR
This is basically a workaround for a slightly different IR generated by
fir2ir vs psi2ir. Simplified, psi2ir generates something like this for
the sample from KT-59218:
TRY type=Unit
try: BLOCK type=Unit
VAR methodHandle [...]
TYPE_OP type=Unit origin=IMPLICIT_COERCION_TO_UNIT
CALL invokeExact [...]
While fir2ir generates the following:
TYPE_OP type=Unit origin=IMPLICIT_COERCION_TO_UNIT
TRY type=Any?
try: BLOCK type=Any?
VAR methodHandle [...]
CALL invokeExact [...]
The lowering relies on the fact that a polymorphic call (`invokeExact`
in this case) is a direct argument to the TYPE_OP, to determine the
correct return type (Unit in this case) to be generated in the bytecode.
The solution here is to push the type coercion "through" all the
block-like structures (`try`, `when`, container expression) so that if
the last statement in the block is a polymorphic call, it gets properly
converted even if the whole block is under a type coercion operation, as
it happens in fir2ir. We achieve that by using the "data" parameter of
the IR transformer: appropriate immediate children of
IrTypeOperatorCall/IrTry/IrWhen/IrContainerExpression get the type that
the expression needs to be coerced to, and all the other expressions
ignore that type and set it to null when transforming their children.
A proper solution would be to ensure fir2ir generates exactly the same
IR as psi2ir (KT-59781), but since PolymorphicSignatureLowering is the
only lowering affected so far, and polymorphic calls occur very rarely,
it seems safe to workaround it in the lowering for now.
#KT-59218 Fixed
This commit is contained in:
committed by
Space Team
parent
69059362b8
commit
1cb1420e43
+20
@@ -30447,6 +30447,26 @@ public class LightAnalysisModeTestGenerated extends AbstractLightAnalysisModeTes
|
||||
runTest("compiler/testData/codegen/box/polymorphicSignature/anonymousSubclass.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("insideComplexExpression.kt")
|
||||
public void testInsideComplexExpression() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/polymorphicSignature/insideComplexExpression.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("insideIf.kt")
|
||||
public void testInsideIf() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/polymorphicSignature/insideIf.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("insideTry.kt")
|
||||
public void testInsideTry() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/polymorphicSignature/insideTry.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("insideWhen.kt")
|
||||
public void testInsideWhen() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/polymorphicSignature/insideWhen.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("invoke.kt")
|
||||
public void testInvoke() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/polymorphicSignature/invoke.kt");
|
||||
|
||||
Reference in New Issue
Block a user