[FIR] Support makeDefinitelyNotNull for intersection types
This commit is contained in:
+3
-1
@@ -211,7 +211,9 @@ interface ConeInferenceContext : TypeSystemInferenceExtensionContext, ConeTypeCo
|
||||
}
|
||||
|
||||
private fun ConeKotlinType.makeDefinitelyNotNullOrNotNull(): ConeKotlinType {
|
||||
// TODO: add intersection types, see fun SimpleType.makeSimpleTypeDefinitelyNotNullOrNotNull() in SpecialTypes.kt
|
||||
if (this is ConeIntersectionType) {
|
||||
return ConeIntersectionType(intersectedTypes.map { it.makeDefinitelyNotNullOrNotNull() })
|
||||
}
|
||||
return ConeDefinitelyNotNullType.create(this) ?: this.withNullability(false) as ConeKotlinType
|
||||
}
|
||||
|
||||
|
||||
+7
@@ -0,0 +1,7 @@
|
||||
fun <X> test_1(a: X) {
|
||||
if (a is String?) {
|
||||
takeString(a!!)
|
||||
}
|
||||
}
|
||||
|
||||
fun takeString(s: String) {}
|
||||
+2
-2
@@ -1,8 +1,8 @@
|
||||
FILE: smartcastOnBangBang.kt
|
||||
FILE: definitelyNotNullIntersectionType.kt
|
||||
public final fun <X> test_1(a: R|X|): R|kotlin/Unit| {
|
||||
when () {
|
||||
(R|<local>/a| is R|kotlin/String?|) -> {
|
||||
<Inapplicable(INAPPLICABLE): [/takeString]>#(R|<local>/a|!!)
|
||||
R|/takeString|(R|<local>/a|!!)
|
||||
}
|
||||
}
|
||||
|
||||
-59
@@ -1,59 +0,0 @@
|
||||
digraph smartcastOnBangBang_kt {
|
||||
graph [splines=ortho nodesep=3]
|
||||
node [shape=box penwidth=2]
|
||||
edge [penwidth=2]
|
||||
|
||||
subgraph cluster_0 {
|
||||
color=red
|
||||
0 [label="Enter function test_1" style="filled" fillcolor=red];
|
||||
subgraph cluster_1 {
|
||||
color=blue
|
||||
1 [label="Enter when"];
|
||||
subgraph cluster_2 {
|
||||
color=blue
|
||||
2 [label="Enter when branch condition "];
|
||||
3 [label="Access variable R|<local>/a|"];
|
||||
4 [label="Type operator: a is String?"];
|
||||
5 [label="Exit when branch condition"];
|
||||
}
|
||||
6 [label="Synthetic else branch"];
|
||||
7 [label="Enter when branch result"];
|
||||
subgraph cluster_3 {
|
||||
color=blue
|
||||
8 [label="Enter block"];
|
||||
9 [label="Access variable R|<local>/a|"];
|
||||
10 [label="Check not null: R|<local>/a|!!"];
|
||||
11 [label="Function call: <Inapplicable(INAPPLICABLE): [/takeString]>#(R|<local>/a|!!)"];
|
||||
12 [label="Exit block"];
|
||||
}
|
||||
13 [label="Exit when branch result"];
|
||||
14 [label="Exit when"];
|
||||
}
|
||||
15 [label="Exit function test_1" style="filled" fillcolor=red];
|
||||
}
|
||||
|
||||
0 -> {1};
|
||||
1 -> {2};
|
||||
2 -> {3};
|
||||
3 -> {4};
|
||||
4 -> {5};
|
||||
5 -> {7 6};
|
||||
6 -> {14};
|
||||
7 -> {8};
|
||||
8 -> {9};
|
||||
9 -> {10};
|
||||
10 -> {11};
|
||||
11 -> {12};
|
||||
12 -> {13};
|
||||
13 -> {14};
|
||||
14 -> {15};
|
||||
|
||||
subgraph cluster_4 {
|
||||
color=red
|
||||
16 [label="Enter function takeString" style="filled" fillcolor=red];
|
||||
17 [label="Exit function takeString" style="filled" fillcolor=red];
|
||||
}
|
||||
|
||||
16 -> {17};
|
||||
|
||||
}
|
||||
-8
@@ -1,8 +0,0 @@
|
||||
// !DUMP_CFG
|
||||
fun <X> test_1(a: X) {
|
||||
if (a is String?) {
|
||||
<!INAPPLICABLE_CANDIDATE!>takeString<!>(a!!)
|
||||
}
|
||||
}
|
||||
|
||||
fun takeString(s: String) {}
|
||||
+5
-18
@@ -1082,6 +1082,11 @@ public class FirDiagnosticsTestGenerated extends AbstractFirDiagnosticsTest {
|
||||
runTest("compiler/fir/resolve/testData/resolve/inference/capturedTypeForJavaTypeParameter.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("definitelyNotNullIntersectionType.kt")
|
||||
public void testDefinitelyNotNullIntersectionType() throws Exception {
|
||||
runTest("compiler/fir/resolve/testData/resolve/inference/definitelyNotNullIntersectionType.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("nestedLambdas.kt")
|
||||
public void testNestedLambdas() throws Exception {
|
||||
runTest("compiler/fir/resolve/testData/resolve/inference/nestedLambdas.kt");
|
||||
@@ -1576,24 +1581,6 @@ public class FirDiagnosticsTestGenerated extends AbstractFirDiagnosticsTest {
|
||||
}
|
||||
}
|
||||
|
||||
@TestMetadata("compiler/fir/resolve/testData/resolve/smartcasts/problems")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
public static class Problems extends AbstractFirDiagnosticsTest {
|
||||
private void runTest(String testDataFilePath) throws Exception {
|
||||
KotlinTestUtils.runTest(this::doTest, this, testDataFilePath);
|
||||
}
|
||||
|
||||
public void testAllFilesPresentInProblems() throws Exception {
|
||||
KotlinTestUtils.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/fir/resolve/testData/resolve/smartcasts/problems"), Pattern.compile("^([^.]+)\\.kt$"), null, true);
|
||||
}
|
||||
|
||||
@TestMetadata("smartcastOnBangBang.kt")
|
||||
public void testSmartcastOnBangBang() throws Exception {
|
||||
runTest("compiler/fir/resolve/testData/resolve/smartcasts/problems/smartcastOnBangBang.kt");
|
||||
}
|
||||
}
|
||||
|
||||
@TestMetadata("compiler/fir/resolve/testData/resolve/smartcasts/receivers")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
|
||||
Generated
+5
-18
@@ -1082,6 +1082,11 @@ public class FirDiagnosticsWithLightTreeTestGenerated extends AbstractFirDiagnos
|
||||
runTest("compiler/fir/resolve/testData/resolve/inference/capturedTypeForJavaTypeParameter.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("definitelyNotNullIntersectionType.kt")
|
||||
public void testDefinitelyNotNullIntersectionType() throws Exception {
|
||||
runTest("compiler/fir/resolve/testData/resolve/inference/definitelyNotNullIntersectionType.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("nestedLambdas.kt")
|
||||
public void testNestedLambdas() throws Exception {
|
||||
runTest("compiler/fir/resolve/testData/resolve/inference/nestedLambdas.kt");
|
||||
@@ -1576,24 +1581,6 @@ public class FirDiagnosticsWithLightTreeTestGenerated extends AbstractFirDiagnos
|
||||
}
|
||||
}
|
||||
|
||||
@TestMetadata("compiler/fir/resolve/testData/resolve/smartcasts/problems")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
public static class Problems extends AbstractFirDiagnosticsWithLightTreeTest {
|
||||
private void runTest(String testDataFilePath) throws Exception {
|
||||
KotlinTestUtils.runTest(this::doTest, this, testDataFilePath);
|
||||
}
|
||||
|
||||
public void testAllFilesPresentInProblems() throws Exception {
|
||||
KotlinTestUtils.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/fir/resolve/testData/resolve/smartcasts/problems"), Pattern.compile("^([^.]+)\\.kt$"), null, true);
|
||||
}
|
||||
|
||||
@TestMetadata("smartcastOnBangBang.kt")
|
||||
public void testSmartcastOnBangBang() throws Exception {
|
||||
runTest("compiler/fir/resolve/testData/resolve/smartcasts/problems/smartcastOnBangBang.kt");
|
||||
}
|
||||
}
|
||||
|
||||
@TestMetadata("compiler/fir/resolve/testData/resolve/smartcasts/receivers")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
|
||||
@@ -33,7 +33,7 @@ FILE fqName:<root> fileName:/bangbang.kt
|
||||
BRANCH
|
||||
if: TYPE_OP type=kotlin.Boolean origin=INSTANCEOF typeOperand=kotlin.String?
|
||||
GET_VAR 'a: X of <root>.test4 declared in <root>.test4' type=X of <root>.test4 origin=null
|
||||
then: CALL 'public final fun CHECK_NOT_NULL <T0> (arg0: T0 of kotlin.internal.ir.CHECK_NOT_NULL?): T0 of kotlin.internal.ir.CHECK_NOT_NULL declared in kotlin.internal.ir' type=kotlin.String? origin=EXCLEXCL
|
||||
then: CALL 'public final fun CHECK_NOT_NULL <T0> (arg0: T0 of kotlin.internal.ir.CHECK_NOT_NULL?): T0 of kotlin.internal.ir.CHECK_NOT_NULL declared in kotlin.internal.ir' type=kotlin.String origin=EXCLEXCL
|
||||
<T0>: kotlin.String
|
||||
arg0: TYPE_OP type=kotlin.String? origin=IMPLICIT_CAST typeOperand=kotlin.String?
|
||||
GET_VAR 'a: X of <root>.test4 declared in <root>.test4' type=X of <root>.test4 origin=null
|
||||
@@ -41,8 +41,8 @@ FILE fqName:<root> fileName:/bangbang.kt
|
||||
BRANCH
|
||||
if: TYPE_OP type=kotlin.Boolean origin=INSTANCEOF typeOperand=kotlin.String?
|
||||
GET_VAR 'a: X of <root>.test4 declared in <root>.test4' type=X of <root>.test4 origin=null
|
||||
then: ERROR_CALL 'Unresolved reference: <Inapplicable(INAPPLICABLE): [/useString]>#' type=IrErrorType
|
||||
CALL 'public final fun CHECK_NOT_NULL <T0> (arg0: T0 of kotlin.internal.ir.CHECK_NOT_NULL?): T0 of kotlin.internal.ir.CHECK_NOT_NULL declared in kotlin.internal.ir' type=kotlin.String? origin=EXCLEXCL
|
||||
then: CALL 'public final fun useString (s: kotlin.String): kotlin.Unit declared in <root>' type=kotlin.Unit origin=null
|
||||
s: CALL 'public final fun CHECK_NOT_NULL <T0> (arg0: T0 of kotlin.internal.ir.CHECK_NOT_NULL?): T0 of kotlin.internal.ir.CHECK_NOT_NULL declared in kotlin.internal.ir' type=kotlin.String origin=EXCLEXCL
|
||||
<T0>: kotlin.String
|
||||
arg0: TYPE_OP type=kotlin.String? origin=IMPLICIT_CAST typeOperand=kotlin.String?
|
||||
GET_VAR 'a: X of <root>.test4 declared in <root>.test4' type=X of <root>.test4 origin=null
|
||||
|
||||
Reference in New Issue
Block a user