Add additional test cases and notes for KT44429
This commit is contained in:
+6
@@ -1500,6 +1500,12 @@ public class FirLightTreeBlackBoxInlineCodegenWithBytecodeInlinerTestGenerated e
|
||||
runTest("compiler/testData/codegen/boxInline/complex/kt44429.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("kt44429MustFail.kt")
|
||||
public void testKt44429MustFail() throws Exception {
|
||||
runTest("compiler/testData/codegen/boxInline/complex/kt44429MustFail.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("lambdaInLambda.kt")
|
||||
public void testLambdaInLambda() throws Exception {
|
||||
|
||||
+6
@@ -1500,6 +1500,12 @@ public class FirLightTreeBlackBoxInlineCodegenWithIrInlinerTestGenerated extends
|
||||
runTest("compiler/testData/codegen/boxInline/complex/kt44429.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("kt44429MustFail.kt")
|
||||
public void testKt44429MustFail() throws Exception {
|
||||
runTest("compiler/testData/codegen/boxInline/complex/kt44429MustFail.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("lambdaInLambda.kt")
|
||||
public void testLambdaInLambda() throws Exception {
|
||||
|
||||
+6
@@ -1500,6 +1500,12 @@ public class FirLightTreeSerializeCompileKotlinAgainstInlineKotlinTestGenerated
|
||||
runTest("compiler/testData/codegen/boxInline/complex/kt44429.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("kt44429MustFail.kt")
|
||||
public void testKt44429MustFail() throws Exception {
|
||||
runTest("compiler/testData/codegen/boxInline/complex/kt44429MustFail.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("lambdaInLambda.kt")
|
||||
public void testLambdaInLambda() throws Exception {
|
||||
|
||||
+6
@@ -1500,6 +1500,12 @@ public class FirPsiBlackBoxInlineCodegenWithBytecodeInlinerTestGenerated extends
|
||||
runTest("compiler/testData/codegen/boxInline/complex/kt44429.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("kt44429MustFail.kt")
|
||||
public void testKt44429MustFail() throws Exception {
|
||||
runTest("compiler/testData/codegen/boxInline/complex/kt44429MustFail.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("lambdaInLambda.kt")
|
||||
public void testLambdaInLambda() throws Exception {
|
||||
|
||||
+6
@@ -1500,6 +1500,12 @@ public class FirPsiBlackBoxInlineCodegenWithIrInlinerTestGenerated extends Abstr
|
||||
runTest("compiler/testData/codegen/boxInline/complex/kt44429.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("kt44429MustFail.kt")
|
||||
public void testKt44429MustFail() throws Exception {
|
||||
runTest("compiler/testData/codegen/boxInline/complex/kt44429MustFail.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("lambdaInLambda.kt")
|
||||
public void testLambdaInLambda() throws Exception {
|
||||
|
||||
+6
@@ -1500,6 +1500,12 @@ public class FirPsiSerializeCompileKotlinAgainstInlineKotlinTestGenerated extend
|
||||
runTest("compiler/testData/codegen/boxInline/complex/kt44429.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("kt44429MustFail.kt")
|
||||
public void testKt44429MustFail() throws Exception {
|
||||
runTest("compiler/testData/codegen/boxInline/complex/kt44429MustFail.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("lambdaInLambda.kt")
|
||||
public void testLambdaInLambda() throws Exception {
|
||||
|
||||
+27
-8
@@ -726,23 +726,42 @@ class FunctionInlining(
|
||||
}
|
||||
|
||||
// In short this is needed for `kt44429` test. We need to get original generic type to trick type system on JVM backend.
|
||||
// Probably this it is relevant only for numeric types in JVM.
|
||||
private fun IrValueParameter.getOriginalType(): IrType {
|
||||
if (this.parent !is IrFunction) return type
|
||||
val callee = this.parent as IrFunction
|
||||
val original = callee.originalFunction
|
||||
val copy = this.parent as IrFunction // contains substituted type parameters with corresponding type arguments
|
||||
val original = copy.originalFunction // contains original unsubstituted type parameters
|
||||
|
||||
// Note 1: the following method will replace super types fow the owner type parameter. So in every other IrSimpleType that
|
||||
// refers this type parameter we will see substituted values. This should not be a problem because earlier we replace all type
|
||||
// parameters with corresponding type arguments.
|
||||
// Note 2: this substitution can be dropped if we will learn how to copy IR function and leave its type parameters as they are.
|
||||
// But this sounds a little complicated.
|
||||
fun IrType.substituteSuperTypes(): IrType {
|
||||
val typeClassifier = this.classifierOrNull?.owner as? IrTypeParameter ?: return this
|
||||
typeClassifier.superTypes = original.typeParameters[typeClassifier.index].superTypes.map {
|
||||
val superTypeClassifier = it.classifierOrNull?.owner as? IrTypeParameter ?: return@map it
|
||||
copy.typeParameters[superTypeClassifier.index].defaultType.substituteSuperTypes()
|
||||
}
|
||||
return this
|
||||
}
|
||||
|
||||
fun IrValueParameter?.getTypeIfFromTypeParameter(): IrType? {
|
||||
val typeClassifier = this?.type?.classifierOrNull?.owner as? IrTypeParameter ?: return null
|
||||
if (typeClassifier.parent != this.parent) return null
|
||||
return callee.typeParameters[typeClassifier.index].defaultType
|
||||
|
||||
// We take type parameter from copied callee and not from original because we need an actual copy. Without this copy,
|
||||
// in case of recursive call, we can get a situation there the same type parameter will be mapped on different type arguments.
|
||||
// (see compiler/testData/codegen/boxInline/complex/use.kt test file)
|
||||
return copy.typeParameters[typeClassifier.index].defaultType.substituteSuperTypes()
|
||||
}
|
||||
|
||||
return when (this) {
|
||||
callee.dispatchReceiverParameter -> original.dispatchReceiverParameter?.getTypeIfFromTypeParameter()
|
||||
?: callee.dispatchReceiverParameter!!.type
|
||||
callee.extensionReceiverParameter -> original.extensionReceiverParameter?.getTypeIfFromTypeParameter()
|
||||
?: callee.extensionReceiverParameter!!.type
|
||||
else -> callee.valueParameters.first { it == this }.let { valueParameter ->
|
||||
copy.dispatchReceiverParameter -> original.dispatchReceiverParameter?.getTypeIfFromTypeParameter()
|
||||
?: copy.dispatchReceiverParameter!!.type
|
||||
copy.extensionReceiverParameter -> original.extensionReceiverParameter?.getTypeIfFromTypeParameter()
|
||||
?: copy.extensionReceiverParameter!!.type
|
||||
else -> copy.valueParameters.first { it == this }.let { valueParameter ->
|
||||
original.valueParameters[valueParameter.index].getTypeIfFromTypeParameter()
|
||||
?: valueParameter.type
|
||||
}
|
||||
|
||||
@@ -5,6 +5,10 @@
|
||||
package test
|
||||
|
||||
inline fun <T> takeT(t: T) {}
|
||||
inline fun <T : Any> takeTSuperAny(t: T) {}
|
||||
inline fun <T, U : T> takeU(u: U) {}
|
||||
inline fun <T, U : T, R : U> takeR(r: R) {}
|
||||
inline fun <A, B, T : Map<A, List<B>>> takeTWithMap(t: T) {}
|
||||
|
||||
// FILE: 2.kt
|
||||
import test.*
|
||||
@@ -12,5 +16,14 @@ import test.*
|
||||
fun box(): String {
|
||||
val f = { null } as () -> Int
|
||||
takeT(f())
|
||||
// Without fix we are going to get following instructions
|
||||
// CHECKCAST java/lang/Number
|
||||
// INVOKEVIRTUAL java/lang/Number.intValue ()I // <- this one leads to NPE
|
||||
takeTSuperAny(f())
|
||||
takeU(f())
|
||||
takeR(f())
|
||||
|
||||
val g = { null } as () -> Map<Int, List<String>>
|
||||
takeTWithMap(g())
|
||||
return "OK"
|
||||
}
|
||||
|
||||
@@ -0,0 +1,29 @@
|
||||
// TARGET_BACKEND: JVM
|
||||
// NO_CHECK_LAMBDA_INLINING
|
||||
// FILE: 1.kt
|
||||
package test
|
||||
|
||||
// Following examples expected to fail
|
||||
inline fun <T : Int> takeTFail(t: T) {}
|
||||
inline fun <T : Int, U : T> takeUSuperInt(u: U) {}
|
||||
|
||||
// FILE: 2.kt
|
||||
import test.*
|
||||
|
||||
inline fun <reified T> assertThrows(block: () -> Unit) {
|
||||
try {
|
||||
block.invoke()
|
||||
} catch (t: Throwable) {
|
||||
if (t is T) return
|
||||
throw t
|
||||
}
|
||||
throw AssertionError("Exception was expected")
|
||||
}
|
||||
|
||||
fun box(): String {
|
||||
val f = { null } as () -> Int
|
||||
|
||||
assertThrows<NullPointerException> { takeTFail(f()) }
|
||||
assertThrows<NullPointerException> { takeUSuperInt(f()) }
|
||||
return "OK"
|
||||
}
|
||||
+6
@@ -1476,6 +1476,12 @@ public class BlackBoxInlineCodegenTestGenerated extends AbstractBlackBoxInlineCo
|
||||
runTest("compiler/testData/codegen/boxInline/complex/kt44429.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("kt44429MustFail.kt")
|
||||
public void testKt44429MustFail() throws Exception {
|
||||
runTest("compiler/testData/codegen/boxInline/complex/kt44429MustFail.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("lambdaInLambda.kt")
|
||||
public void testLambdaInLambda() throws Exception {
|
||||
|
||||
+6
@@ -1476,6 +1476,12 @@ public class CompileKotlinAgainstInlineKotlinTestGenerated extends AbstractCompi
|
||||
runTest("compiler/testData/codegen/boxInline/complex/kt44429.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("kt44429MustFail.kt")
|
||||
public void testKt44429MustFail() throws Exception {
|
||||
runTest("compiler/testData/codegen/boxInline/complex/kt44429MustFail.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("lambdaInLambda.kt")
|
||||
public void testLambdaInLambda() throws Exception {
|
||||
|
||||
+6
@@ -1500,6 +1500,12 @@ public class IrBlackBoxInlineCodegenWithBytecodeInlinerTestGenerated extends Abs
|
||||
runTest("compiler/testData/codegen/boxInline/complex/kt44429.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("kt44429MustFail.kt")
|
||||
public void testKt44429MustFail() throws Exception {
|
||||
runTest("compiler/testData/codegen/boxInline/complex/kt44429MustFail.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("lambdaInLambda.kt")
|
||||
public void testLambdaInLambda() throws Exception {
|
||||
|
||||
+6
@@ -1500,6 +1500,12 @@ public class IrBlackBoxInlineCodegenWithIrInlinerTestGenerated extends AbstractI
|
||||
runTest("compiler/testData/codegen/boxInline/complex/kt44429.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("kt44429MustFail.kt")
|
||||
public void testKt44429MustFail() throws Exception {
|
||||
runTest("compiler/testData/codegen/boxInline/complex/kt44429MustFail.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("lambdaInLambda.kt")
|
||||
public void testLambdaInLambda() throws Exception {
|
||||
|
||||
+6
@@ -1500,6 +1500,12 @@ public class IrCompileKotlinAgainstInlineKotlinTestGenerated extends AbstractIrC
|
||||
runTest("compiler/testData/codegen/boxInline/complex/kt44429.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("kt44429MustFail.kt")
|
||||
public void testKt44429MustFail() throws Exception {
|
||||
runTest("compiler/testData/codegen/boxInline/complex/kt44429MustFail.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("lambdaInLambda.kt")
|
||||
public void testLambdaInLambda() throws Exception {
|
||||
|
||||
+6
@@ -1500,6 +1500,12 @@ public class IrSerializeCompileKotlinAgainstInlineKotlinTestGenerated extends Ab
|
||||
runTest("compiler/testData/codegen/boxInline/complex/kt44429.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("kt44429MustFail.kt")
|
||||
public void testKt44429MustFail() throws Exception {
|
||||
runTest("compiler/testData/codegen/boxInline/complex/kt44429MustFail.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("lambdaInLambda.kt")
|
||||
public void testLambdaInLambda() throws Exception {
|
||||
|
||||
+6
@@ -1500,6 +1500,12 @@ public class JvmIrAgainstOldBoxInlineTestGenerated extends AbstractJvmIrAgainstO
|
||||
runTest("compiler/testData/codegen/boxInline/complex/kt44429.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("kt44429MustFail.kt")
|
||||
public void testKt44429MustFail() throws Exception {
|
||||
runTest("compiler/testData/codegen/boxInline/complex/kt44429MustFail.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("lambdaInLambda.kt")
|
||||
public void testLambdaInLambda() throws Exception {
|
||||
|
||||
+6
@@ -1476,6 +1476,12 @@ public class JvmOldAgainstIrBoxInlineTestGenerated extends AbstractJvmOldAgainst
|
||||
runTest("compiler/testData/codegen/boxInline/complex/kt44429.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("kt44429MustFail.kt")
|
||||
public void testKt44429MustFail() throws Exception {
|
||||
runTest("compiler/testData/codegen/boxInline/complex/kt44429MustFail.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("lambdaInLambda.kt")
|
||||
public void testLambdaInLambda() throws Exception {
|
||||
|
||||
Reference in New Issue
Block a user