[FIR] Approximate captured types during approximation of local types

^KT-57222 Fixed
This commit is contained in:
Dmitriy Novozhilov
2023-04-27 16:11:12 +03:00
committed by Space Team
parent ad002437b4
commit f7733e819d
17 changed files with 127 additions and 5 deletions
@@ -33811,6 +33811,12 @@ public class FirLightTreeBlackBoxCodegenTestGenerated extends AbstractFirLightTr
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/box/objects"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JVM_IR, true);
}
@Test
@TestMetadata("anonymousObjectAndContrvariantProjection.kt")
public void testAnonymousObjectAndContrvariantProjection() throws Exception {
runTest("compiler/testData/codegen/box/objects/anonymousObjectAndContrvariantProjection.kt");
}
@Test
@TestMetadata("anonymousObjectPropertyInitialization.kt")
public void testAnonymousObjectPropertyInitialization() throws Exception {
@@ -33811,6 +33811,12 @@ public class FirPsiBlackBoxCodegenTestGenerated extends AbstractFirPsiBlackBoxCo
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/box/objects"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JVM_IR, true);
}
@Test
@TestMetadata("anonymousObjectAndContrvariantProjection.kt")
public void testAnonymousObjectAndContrvariantProjection() throws Exception {
runTest("compiler/testData/codegen/box/objects/anonymousObjectAndContrvariantProjection.kt");
}
@Test
@TestMetadata("anonymousObjectPropertyInitialization.kt")
public void testAnonymousObjectPropertyInitialization() throws Exception {
@@ -168,7 +168,12 @@ abstract class AbstractTypeApproximator(
}
}
private fun approximateLocalTypes(type: SimpleTypeMarker, conf: TypeApproximatorConfiguration, toSuper: Boolean): SimpleTypeMarker? {
private fun approximateLocalTypes(
type: SimpleTypeMarker,
conf: TypeApproximatorConfiguration,
toSuper: Boolean,
depth: Int
): SimpleTypeMarker? {
if (!toSuper) return null
if (!conf.localTypes && !conf.anonymous) return null
val constructor = type.typeConstructor()
@@ -179,8 +184,28 @@ abstract class AbstractTypeApproximator(
errorTypesEqualToAnything = false,
stubTypesEqualToAnything = false
)
return AbstractTypeChecker.findCorrespondingSupertypes(typeCheckerContext, type, superConstructor).firstOrNull()
val result = AbstractTypeChecker.findCorrespondingSupertypes(typeCheckerContext, type, superConstructor)
.firstOrNull()
?.withNullability(type.isMarkedNullable())
?: return null
/*
* AbstractTypeChecker captures any projections in the super type by default, which may lead to the situation, when some local
* type with projection is approximated to some public type with captured (from subtyping) type argument (which is obviously
* incorrect)
*
* interface Invariant<A>
* private fun <B> Invariant<B>.privateFunc() = object : Invariant<B> {}
*
* fun Invariant<in Number>.publicFunc() = privateFunc()
*
* Here type of `privateFunc()` is _anonymous_<in Number>, and `findCorrespondingSupertypes` for it and `Invariant` as type
* constructor returns `Invariant<Captured(in Number)>`
*/
return if (ctx.isK2) {
(approximateTo(result, TypeApproximatorConfiguration.SubtypeCapturedTypesApproximation, toSuper, depth) ?: result) as SimpleTypeMarker?
} else {
result
}
}
private fun isIntersectionTypeEffectivelyNothing(constructor: IntersectionTypeConstructorMarker): Boolean {
@@ -365,7 +390,7 @@ abstract class AbstractTypeApproximator(
}
}
return approximateLocalTypes(type, conf, toSuper) // simple classifier type
return approximateLocalTypes(type, conf, toSuper, depth) // simple classifier type
}
private fun approximateDefinitelyNotNullType(
@@ -572,11 +597,11 @@ abstract class AbstractTypeApproximator(
}
}
if (newArguments.all { it == null }) return approximateLocalTypes(type, conf, toSuper)
if (newArguments.all { it == null }) return approximateLocalTypes(type, conf, toSuper, depth)
val newArgumentsList = List(type.argumentsCount()) { index -> newArguments[index] ?: type.getArgument(index) }
val approximatedType = type.replaceArguments(newArgumentsList)
return approximateLocalTypes(approximatedType, conf, toSuper) ?: approximatedType
return approximateLocalTypes(approximatedType, conf, toSuper, depth) ?: approximatedType
}
private fun shouldUseSubTypeForCapturedArgument(
@@ -0,0 +1,9 @@
// ISSUE: KT-57222
interface Invariant<A>
fun Invariant<in Number>.publicFunc() = privateFunc()
private fun <B> Invariant<B>.privateFunc() = object : Invariant<B> {}
fun box() = "OK"
@@ -32311,6 +32311,12 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest {
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/box/objects"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JVM, true);
}
@Test
@TestMetadata("anonymousObjectAndContrvariantProjection.kt")
public void testAnonymousObjectAndContrvariantProjection() throws Exception {
runTest("compiler/testData/codegen/box/objects/anonymousObjectAndContrvariantProjection.kt");
}
@Test
@TestMetadata("anonymousObjectPropertyInitialization.kt")
public void testAnonymousObjectPropertyInitialization() throws Exception {
@@ -33811,6 +33811,12 @@ public class IrBlackBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTes
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/box/objects"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JVM_IR, true);
}
@Test
@TestMetadata("anonymousObjectAndContrvariantProjection.kt")
public void testAnonymousObjectAndContrvariantProjection() throws Exception {
runTest("compiler/testData/codegen/box/objects/anonymousObjectAndContrvariantProjection.kt");
}
@Test
@TestMetadata("anonymousObjectPropertyInitialization.kt")
public void testAnonymousObjectPropertyInitialization() throws Exception {
@@ -33811,6 +33811,12 @@ public class IrBlackBoxCodegenWithIrInlinerTestGenerated extends AbstractIrBlack
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/box/objects"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JVM_IR, true);
}
@Test
@TestMetadata("anonymousObjectAndContrvariantProjection.kt")
public void testAnonymousObjectAndContrvariantProjection() throws Exception {
runTest("compiler/testData/codegen/box/objects/anonymousObjectAndContrvariantProjection.kt");
}
@Test
@TestMetadata("anonymousObjectPropertyInitialization.kt")
public void testAnonymousObjectPropertyInitialization() throws Exception {
@@ -27586,6 +27586,11 @@ public class LightAnalysisModeTestGenerated extends AbstractLightAnalysisModeTes
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/box/objects"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JVM, true);
}
@TestMetadata("anonymousObjectAndContrvariantProjection.kt")
public void testAnonymousObjectAndContrvariantProjection() throws Exception {
runTest("compiler/testData/codegen/box/objects/anonymousObjectAndContrvariantProjection.kt");
}
@TestMetadata("anonymousObjectPropertyInitialization.kt")
public void testAnonymousObjectPropertyInitialization() throws Exception {
runTest("compiler/testData/codegen/box/objects/anonymousObjectPropertyInitialization.kt");
@@ -23629,6 +23629,12 @@ public class JsCodegenBoxTestGenerated extends AbstractJsCodegenBoxTest {
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/box/objects"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JS, true);
}
@Test
@TestMetadata("anonymousObjectAndContrvariantProjection.kt")
public void testAnonymousObjectAndContrvariantProjection() throws Exception {
runTest("compiler/testData/codegen/box/objects/anonymousObjectAndContrvariantProjection.kt");
}
@Test
@TestMetadata("anonymousObjectPropertyInitialization.kt")
public void testAnonymousObjectPropertyInitialization() throws Exception {
@@ -23767,6 +23767,12 @@ public class FirJsCodegenBoxTestGenerated extends AbstractFirJsCodegenBoxTest {
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/box/objects"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JS_IR, true);
}
@Test
@TestMetadata("anonymousObjectAndContrvariantProjection.kt")
public void testAnonymousObjectAndContrvariantProjection() throws Exception {
runTest("compiler/testData/codegen/box/objects/anonymousObjectAndContrvariantProjection.kt");
}
@Test
@TestMetadata("anonymousObjectPropertyInitialization.kt")
public void testAnonymousObjectPropertyInitialization() throws Exception {
@@ -23767,6 +23767,12 @@ public class IrJsCodegenBoxTestGenerated extends AbstractIrJsCodegenBoxTest {
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/box/objects"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JS_IR, true);
}
@Test
@TestMetadata("anonymousObjectAndContrvariantProjection.kt")
public void testAnonymousObjectAndContrvariantProjection() throws Exception {
runTest("compiler/testData/codegen/box/objects/anonymousObjectAndContrvariantProjection.kt");
}
@Test
@TestMetadata("anonymousObjectPropertyInitialization.kt")
public void testAnonymousObjectPropertyInitialization() throws Exception {
@@ -23767,6 +23767,12 @@ public class IrJsES6CodegenBoxTestGenerated extends AbstractIrJsES6CodegenBoxTes
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/box/objects"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JS_IR_ES6, true);
}
@Test
@TestMetadata("anonymousObjectAndContrvariantProjection.kt")
public void testAnonymousObjectAndContrvariantProjection() throws Exception {
runTest("compiler/testData/codegen/box/objects/anonymousObjectAndContrvariantProjection.kt");
}
@Test
@TestMetadata("anonymousObjectPropertyInitialization.kt")
public void testAnonymousObjectPropertyInitialization() throws Exception {
@@ -27189,6 +27189,12 @@ public class FirNativeCodegenBoxTestGenerated extends AbstractNativeCodegenBoxTe
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/box/objects"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.NATIVE, true);
}
@Test
@TestMetadata("anonymousObjectAndContrvariantProjection.kt")
public void testAnonymousObjectAndContrvariantProjection() throws Exception {
runTest("compiler/testData/codegen/box/objects/anonymousObjectAndContrvariantProjection.kt");
}
@Test
@TestMetadata("anonymousObjectPropertyInitialization.kt")
public void testAnonymousObjectPropertyInitialization() throws Exception {
@@ -27811,6 +27811,12 @@ public class FirNativeCodegenBoxTestNoPLGenerated extends AbstractNativeCodegenB
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/box/objects"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.NATIVE, true);
}
@Test
@TestMetadata("anonymousObjectAndContrvariantProjection.kt")
public void testAnonymousObjectAndContrvariantProjection() throws Exception {
runTest("compiler/testData/codegen/box/objects/anonymousObjectAndContrvariantProjection.kt");
}
@Test
@TestMetadata("anonymousObjectPropertyInitialization.kt")
public void testAnonymousObjectPropertyInitialization() throws Exception {
@@ -26878,6 +26878,12 @@ public class NativeCodegenBoxTestGenerated extends AbstractNativeCodegenBoxTest
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/box/objects"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.NATIVE, true);
}
@Test
@TestMetadata("anonymousObjectAndContrvariantProjection.kt")
public void testAnonymousObjectAndContrvariantProjection() throws Exception {
runTest("compiler/testData/codegen/box/objects/anonymousObjectAndContrvariantProjection.kt");
}
@Test
@TestMetadata("anonymousObjectPropertyInitialization.kt")
public void testAnonymousObjectPropertyInitialization() throws Exception {
@@ -27500,6 +27500,12 @@ public class NativeCodegenBoxTestNoPLGenerated extends AbstractNativeCodegenBoxT
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/box/objects"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.NATIVE, true);
}
@Test
@TestMetadata("anonymousObjectAndContrvariantProjection.kt")
public void testAnonymousObjectAndContrvariantProjection() throws Exception {
runTest("compiler/testData/codegen/box/objects/anonymousObjectAndContrvariantProjection.kt");
}
@Test
@TestMetadata("anonymousObjectPropertyInitialization.kt")
public void testAnonymousObjectPropertyInitialization() throws Exception {
@@ -21164,6 +21164,11 @@ public class IrCodegenBoxWasmTestGenerated extends AbstractIrCodegenBoxWasmTest
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/box/objects"), Pattern.compile("^([^_](.+))\\.kt$"), null, TargetBackend.WASM, true);
}
@TestMetadata("anonymousObjectAndContrvariantProjection.kt")
public void testAnonymousObjectAndContrvariantProjection() throws Exception {
runTest("compiler/testData/codegen/box/objects/anonymousObjectAndContrvariantProjection.kt");
}
@TestMetadata("anonymousObjectPropertyInitialization.kt")
public void testAnonymousObjectPropertyInitialization() throws Exception {
runTest("compiler/testData/codegen/box/objects/anonymousObjectPropertyInitialization.kt");