From ee020ef2903ca25154973ff7d9f93a1213068bf2 Mon Sep 17 00:00:00 2001 From: Dmitry Petrov Date: Tue, 4 Feb 2020 15:27:00 +0300 Subject: [PATCH] KT-36336 @EnhancedNullability and null checks Don't insert implicit null check on a value of @EnhancedNullability type used where @EnhancedNullability type is expected. This uncovers a bunch of other problems in FE and BE. KT-36343 and KT-36347 are bugs in StrictJavaNullabilityAssertions implementation which should most likely be fixed in next major language version (with proper breaking change notice). KT-36344 is a design problem which should be addressed after 1.4 issues are resolved. --- .../kotlin/fir/Fir2IrTextTestGenerated.java | 73 +++-- .../transformations/InsertImplicitCasts.kt | 7 +- .../javaArrayOfInheritedNotNullFailFast.kt | 5 +- ...javaCollectionOfExplicitNotNullFailFast.kt | 5 +- ...avaCollectionOfInheritedNotNullFailFast.kt | 5 +- ...CollectionOfNotNullToTypedArrayFailFast.kt | 5 +- .../javaIteratorOfNotNullFailFast.kt | 5 +- ...rrayOfInheritedNotNullWithIndexFailFast.kt | 5 +- ...ctionOfExplicitNotNullWithIndexFailFast.kt | 5 +- .../javaIteratorOfNotNullWithIndexFailFast.kt | 5 +- .../deterministicNotNullChecks.kt | 6 +- .../irText/types/enhancedNullability.fir.txt | 31 -- .../ir/irText/types/enhancedNullability.kt | 23 -- .../nullChecks/enhancedNullability.fir.txt | 47 +++ .../types/nullChecks/enhancedNullability.kt | 39 +++ .../{ => nullChecks}/enhancedNullability.txt | 27 +- ...llabilityInDestructuringAssignment.fir.txt | 186 ++++++++++++ ...cedNullabilityInDestructuringAssignment.kt | 59 ++++ ...edNullabilityInDestructuringAssignment.txt | 206 +++++++++++++ .../enhancedNullabilityInForLoop.fir.txt | 187 ++++++++++++ .../enhancedNullabilityInForLoop.kt | 63 ++++ .../enhancedNullabilityInForLoop.txt | 270 ++++++++++++++++++ ...mpareToCallsOnPlatformTypeReceiver.fir.txt | 0 ...AndCompareToCallsOnPlatformTypeReceiver.kt | 0 ...ndCompareToCallsOnPlatformTypeReceiver.txt | 0 .../implicitNotNullOnPlatformType.fir.txt | 0 .../implicitNotNullOnPlatformType.kt | 0 .../implicitNotNullOnPlatformType.txt | 0 ...bilityAssertionOnExtensionReceiver.fir.txt | 0 ...nullabilityAssertionOnExtensionReceiver.kt | 0 ...ullabilityAssertionOnExtensionReceiver.txt | 0 .../platformTypeReceiver.fir.txt | 0 .../{ => nullChecks}/platformTypeReceiver.kt | 0 .../{ => nullChecks}/platformTypeReceiver.txt | 0 .../kotlin/ir/IrTextTestCaseGenerated.java | 73 +++-- 35 files changed, 1216 insertions(+), 121 deletions(-) delete mode 100644 compiler/testData/ir/irText/types/enhancedNullability.fir.txt delete mode 100644 compiler/testData/ir/irText/types/enhancedNullability.kt create mode 100644 compiler/testData/ir/irText/types/nullChecks/enhancedNullability.fir.txt create mode 100644 compiler/testData/ir/irText/types/nullChecks/enhancedNullability.kt rename compiler/testData/ir/irText/types/{ => nullChecks}/enhancedNullability.txt (52%) create mode 100644 compiler/testData/ir/irText/types/nullChecks/enhancedNullabilityInDestructuringAssignment.fir.txt create mode 100644 compiler/testData/ir/irText/types/nullChecks/enhancedNullabilityInDestructuringAssignment.kt create mode 100644 compiler/testData/ir/irText/types/nullChecks/enhancedNullabilityInDestructuringAssignment.txt create mode 100644 compiler/testData/ir/irText/types/nullChecks/enhancedNullabilityInForLoop.fir.txt create mode 100644 compiler/testData/ir/irText/types/nullChecks/enhancedNullabilityInForLoop.kt create mode 100644 compiler/testData/ir/irText/types/nullChecks/enhancedNullabilityInForLoop.txt rename compiler/testData/ir/irText/types/{ => nullChecks}/explicitEqualsAndCompareToCallsOnPlatformTypeReceiver.fir.txt (100%) rename compiler/testData/ir/irText/types/{ => nullChecks}/explicitEqualsAndCompareToCallsOnPlatformTypeReceiver.kt (100%) rename compiler/testData/ir/irText/types/{ => nullChecks}/explicitEqualsAndCompareToCallsOnPlatformTypeReceiver.txt (100%) rename compiler/testData/ir/irText/types/{ => nullChecks}/implicitNotNullOnPlatformType.fir.txt (100%) rename compiler/testData/ir/irText/types/{ => nullChecks}/implicitNotNullOnPlatformType.kt (100%) rename compiler/testData/ir/irText/types/{ => nullChecks}/implicitNotNullOnPlatformType.txt (100%) rename compiler/testData/ir/irText/types/{ => nullChecks}/nullabilityAssertionOnExtensionReceiver.fir.txt (100%) rename compiler/testData/ir/irText/types/{ => nullChecks}/nullabilityAssertionOnExtensionReceiver.kt (100%) rename compiler/testData/ir/irText/types/{ => nullChecks}/nullabilityAssertionOnExtensionReceiver.txt (100%) rename compiler/testData/ir/irText/types/{ => nullChecks}/platformTypeReceiver.fir.txt (100%) rename compiler/testData/ir/irText/types/{ => nullChecks}/platformTypeReceiver.kt (100%) rename compiler/testData/ir/irText/types/{ => nullChecks}/platformTypeReceiver.txt (100%) diff --git a/compiler/fir/fir2ir/tests/org/jetbrains/kotlin/fir/Fir2IrTextTestGenerated.java b/compiler/fir/fir2ir/tests/org/jetbrains/kotlin/fir/Fir2IrTextTestGenerated.java index fe47b4eefb6..362f866c085 100644 --- a/compiler/fir/fir2ir/tests/org/jetbrains/kotlin/fir/Fir2IrTextTestGenerated.java +++ b/compiler/fir/fir2ir/tests/org/jetbrains/kotlin/fir/Fir2IrTextTestGenerated.java @@ -1807,26 +1807,11 @@ public class Fir2IrTextTestGenerated extends AbstractFir2IrTextTest { runTest("compiler/testData/ir/irText/types/asOnPlatformType.kt"); } - @TestMetadata("enhancedNullability.kt") - public void testEnhancedNullability() throws Exception { - runTest("compiler/testData/ir/irText/types/enhancedNullability.kt"); - } - - @TestMetadata("explicitEqualsAndCompareToCallsOnPlatformTypeReceiver.kt") - public void testExplicitEqualsAndCompareToCallsOnPlatformTypeReceiver() throws Exception { - runTest("compiler/testData/ir/irText/types/explicitEqualsAndCompareToCallsOnPlatformTypeReceiver.kt"); - } - @TestMetadata("genericPropertyReferenceType.kt") public void testGenericPropertyReferenceType() throws Exception { runTest("compiler/testData/ir/irText/types/genericPropertyReferenceType.kt"); } - @TestMetadata("implicitNotNullOnPlatformType.kt") - public void testImplicitNotNullOnPlatformType() throws Exception { - runTest("compiler/testData/ir/irText/types/implicitNotNullOnPlatformType.kt"); - } - @TestMetadata("intersectionType1_NI.kt") public void testIntersectionType1_NI() throws Exception { runTest("compiler/testData/ir/irText/types/intersectionType1_NI.kt"); @@ -1862,16 +1847,6 @@ public class Fir2IrTextTestGenerated extends AbstractFir2IrTextTest { runTest("compiler/testData/ir/irText/types/localVariableOfIntersectionType_NI.kt"); } - @TestMetadata("nullabilityAssertionOnExtensionReceiver.kt") - public void testNullabilityAssertionOnExtensionReceiver() throws Exception { - runTest("compiler/testData/ir/irText/types/nullabilityAssertionOnExtensionReceiver.kt"); - } - - @TestMetadata("platformTypeReceiver.kt") - public void testPlatformTypeReceiver() throws Exception { - runTest("compiler/testData/ir/irText/types/platformTypeReceiver.kt"); - } - @TestMetadata("smartCastOnFakeOverrideReceiver.kt") public void testSmartCastOnFakeOverrideReceiver() throws Exception { runTest("compiler/testData/ir/irText/types/smartCastOnFakeOverrideReceiver.kt"); @@ -1886,5 +1861,53 @@ public class Fir2IrTextTestGenerated extends AbstractFir2IrTextTest { public void testSmartCastOnReceiverOfGenericType() throws Exception { runTest("compiler/testData/ir/irText/types/smartCastOnReceiverOfGenericType.kt"); } + + @TestMetadata("compiler/testData/ir/irText/types/nullChecks") + @TestDataPath("$PROJECT_ROOT") + @RunWith(JUnit3RunnerWithInners.class) + public static class NullChecks extends AbstractFir2IrTextTest { + private void runTest(String testDataFilePath) throws Exception { + KotlinTestUtils.runTestWithCustomIgnoreDirective(this::doTest, TargetBackend.ANY, testDataFilePath, "// IGNORE_BACKEND_FIR: "); + } + + public void testAllFilesPresentInNullChecks() throws Exception { + KotlinTestUtils.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/ir/irText/types/nullChecks"), Pattern.compile("^(.+)\\.kt$"), null, true); + } + + @TestMetadata("enhancedNullability.kt") + public void testEnhancedNullability() throws Exception { + runTest("compiler/testData/ir/irText/types/nullChecks/enhancedNullability.kt"); + } + + @TestMetadata("enhancedNullabilityInDestructuringAssignment.kt") + public void testEnhancedNullabilityInDestructuringAssignment() throws Exception { + runTest("compiler/testData/ir/irText/types/nullChecks/enhancedNullabilityInDestructuringAssignment.kt"); + } + + @TestMetadata("enhancedNullabilityInForLoop.kt") + public void testEnhancedNullabilityInForLoop() throws Exception { + runTest("compiler/testData/ir/irText/types/nullChecks/enhancedNullabilityInForLoop.kt"); + } + + @TestMetadata("explicitEqualsAndCompareToCallsOnPlatformTypeReceiver.kt") + public void testExplicitEqualsAndCompareToCallsOnPlatformTypeReceiver() throws Exception { + runTest("compiler/testData/ir/irText/types/nullChecks/explicitEqualsAndCompareToCallsOnPlatformTypeReceiver.kt"); + } + + @TestMetadata("implicitNotNullOnPlatformType.kt") + public void testImplicitNotNullOnPlatformType() throws Exception { + runTest("compiler/testData/ir/irText/types/nullChecks/implicitNotNullOnPlatformType.kt"); + } + + @TestMetadata("nullabilityAssertionOnExtensionReceiver.kt") + public void testNullabilityAssertionOnExtensionReceiver() throws Exception { + runTest("compiler/testData/ir/irText/types/nullChecks/nullabilityAssertionOnExtensionReceiver.kt"); + } + + @TestMetadata("platformTypeReceiver.kt") + public void testPlatformTypeReceiver() throws Exception { + runTest("compiler/testData/ir/irText/types/nullChecks/platformTypeReceiver.kt"); + } + } } } diff --git a/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/transformations/InsertImplicitCasts.kt b/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/transformations/InsertImplicitCasts.kt index 16160c94f09..84ee88727bf 100644 --- a/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/transformations/InsertImplicitCasts.kt +++ b/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/transformations/InsertImplicitCasts.kt @@ -326,10 +326,10 @@ internal class InsertImplicitCasts( else implicitCast(expectedType, IrTypeOperator.IMPLICIT_DYNAMIC_CAST) - (valueType.isNullabilityFlexible() && valueType.containsNull()) && !expectedType.containsNull() -> + valueType.isNullabilityFlexible() && valueType.containsNull() && !expectedType.acceptsNullValues() -> implicitNonNull(valueType, expectedType) - (valueType.hasEnhancedNullability() && !isLambdaReturnValue) && !expectedType.containsNull() -> + (valueType.hasEnhancedNullability() && !isLambdaReturnValue) && !expectedType.acceptsNullValues() -> implicitNonNull(valueType, expectedType) KotlinTypeChecker.DEFAULT.isSubtypeOf(valueType, expectedType.makeNullable()) -> @@ -359,6 +359,9 @@ internal class InsertImplicitCasts( } } + private fun KotlinType.acceptsNullValues() = + containsNull() || hasEnhancedNullability() + private fun KotlinType.hasEnhancedNullability() = generatorExtensions.enhancedNullability.hasEnhancedNullability(this) diff --git a/compiler/testData/codegen/box/ranges/javaInterop/javaArrayOfInheritedNotNullFailFast.kt b/compiler/testData/codegen/box/ranges/javaInterop/javaArrayOfInheritedNotNullFailFast.kt index f6cf34f139c..b019fd5d59f 100644 --- a/compiler/testData/codegen/box/ranges/javaInterop/javaArrayOfInheritedNotNullFailFast.kt +++ b/compiler/testData/codegen/box/ranges/javaInterop/javaArrayOfInheritedNotNullFailFast.kt @@ -1,13 +1,16 @@ // !LANGUAGE: +StrictJavaNullabilityAssertions // TARGET_BACKEND: JVM // IGNORE_BACKEND_FIR: JVM_IR -// IGNORE_BACKEND: JVM +// IGNORE_BACKEND: JVM, JVM_IR // WITH_RUNTIME // Note: This fails on JVM (non-IR) with "Fail: should throw on get() in loop header". The not-null assertion is not generated when // assigning to the loop variable. The root cause seems to be that the loop variable is a KtParameter and // CodegenAnnotatingVisitor/RuntimeAssertionsOnDeclarationBodyChecker do not analyze the need for not-null assertions on KtParameters. +// Note: this fails on JVM_IR because of KT-36343. +// It requires potentially breaking changes in FE, so please, don't touch it until the language design decision. + // FILE: box.kt import kotlin.test.* diff --git a/compiler/testData/codegen/box/ranges/javaInterop/javaCollectionOfExplicitNotNullFailFast.kt b/compiler/testData/codegen/box/ranges/javaInterop/javaCollectionOfExplicitNotNullFailFast.kt index 48e03727950..4ee8d6b25bc 100644 --- a/compiler/testData/codegen/box/ranges/javaInterop/javaCollectionOfExplicitNotNullFailFast.kt +++ b/compiler/testData/codegen/box/ranges/javaInterop/javaCollectionOfExplicitNotNullFailFast.kt @@ -1,6 +1,6 @@ // !LANGUAGE: +StrictJavaNullabilityAssertions // TARGET_BACKEND: JVM -// IGNORE_BACKEND: JVM +// IGNORE_BACKEND: JVM, JVM_IR // IGNORE_BACKEND_FIR: JVM_IR // WITH_RUNTIME // JVM_TARGET: 1.8 @@ -10,6 +10,9 @@ // CodegenAnnotatingVisitor/RuntimeAssertionsOnDeclarationBodyChecker do not analyze the need for not-null assertions on KtParameters. // See KT-35698. +// Note: this fails on JVM_IR because of KT-36343. +// It requires potentially breaking changes in FE, so please, don't touch it until the language design decision. + // FILE: box.kt import kotlin.test.* diff --git a/compiler/testData/codegen/box/ranges/javaInterop/javaCollectionOfInheritedNotNullFailFast.kt b/compiler/testData/codegen/box/ranges/javaInterop/javaCollectionOfInheritedNotNullFailFast.kt index 5180ee7758c..529ae6b3f23 100644 --- a/compiler/testData/codegen/box/ranges/javaInterop/javaCollectionOfInheritedNotNullFailFast.kt +++ b/compiler/testData/codegen/box/ranges/javaInterop/javaCollectionOfInheritedNotNullFailFast.kt @@ -1,6 +1,6 @@ // !LANGUAGE: +StrictJavaNullabilityAssertions // TARGET_BACKEND: JVM -// IGNORE_BACKEND: JVM +// IGNORE_BACKEND: JVM, JVM_IR // IGNORE_BACKEND_FIR: JVM_IR // WITH_RUNTIME @@ -8,6 +8,9 @@ // assigning to the loop variable. The root cause seems to be that the loop variable is a KtParameter and // CodegenAnnotatingVisitor/RuntimeAssertionsOnDeclarationBodyChecker do not analyze the need for not-null assertions on KtParameters. +// Note: this fails on JVM_IR because of KT-36343. +// It requires potentially breaking changes in FE, so please, don't touch it until the language design decision. + // FILE: box.kt import kotlin.test.* diff --git a/compiler/testData/codegen/box/ranges/javaInterop/javaCollectionOfNotNullToTypedArrayFailFast.kt b/compiler/testData/codegen/box/ranges/javaInterop/javaCollectionOfNotNullToTypedArrayFailFast.kt index 6abb1d7d5a8..930853557c8 100644 --- a/compiler/testData/codegen/box/ranges/javaInterop/javaCollectionOfNotNullToTypedArrayFailFast.kt +++ b/compiler/testData/codegen/box/ranges/javaInterop/javaCollectionOfNotNullToTypedArrayFailFast.kt @@ -1,7 +1,7 @@ // !LANGUAGE: +StrictJavaNullabilityAssertions // TARGET_BACKEND: JVM // IGNORE_BACKEND_FIR: JVM_IR -// IGNORE_BACKEND: JVM +// IGNORE_BACKEND: JVM, JVM_IR // WITH_RUNTIME // JVM_TARGET: 1.8 @@ -9,6 +9,9 @@ // assigning to the loop variable. The root cause seems to be that the loop variable is a KtParameter and // CodegenAnnotatingVisitor/RuntimeAssertionsOnDeclarationBodyChecker do not analyze the need for not-null assertions on KtParameters. +// Note: this fails on JVM_IR because of KT-36343. +// It requires potentially breaking changes in FE, so please, don't touch it until the language design decision. + // FILE: box.kt import kotlin.test.* diff --git a/compiler/testData/codegen/box/ranges/javaInterop/javaIteratorOfNotNullFailFast.kt b/compiler/testData/codegen/box/ranges/javaInterop/javaIteratorOfNotNullFailFast.kt index 625617d1b0c..7002ecb1953 100644 --- a/compiler/testData/codegen/box/ranges/javaInterop/javaIteratorOfNotNullFailFast.kt +++ b/compiler/testData/codegen/box/ranges/javaInterop/javaIteratorOfNotNullFailFast.kt @@ -1,6 +1,6 @@ // !LANGUAGE: +StrictJavaNullabilityAssertions // TARGET_BACKEND: JVM -// IGNORE_BACKEND: JVM +// IGNORE_BACKEND: JVM, JVM_IR // IGNORE_BACKEND_FIR: JVM_IR // WITH_RUNTIME // JVM_TARGET: 1.8 @@ -9,6 +9,9 @@ // assigning to the loop variable. The root cause seems to be that the loop variable is a KtParameter and // CodegenAnnotatingVisitor/RuntimeAssertionsOnDeclarationBodyChecker do not analyze the need for not-null assertions on KtParameters. +// Note: this fails on JVM_IR because of KT-36343. +// It requires potentially breaking changes in FE, so please, don't touch it until the language design decision. + // FILE: box.kt import kotlin.test.* diff --git a/compiler/testData/codegen/box/ranges/javaInterop/withIndex/javaArrayOfInheritedNotNullWithIndexFailFast.kt b/compiler/testData/codegen/box/ranges/javaInterop/withIndex/javaArrayOfInheritedNotNullWithIndexFailFast.kt index c091c276431..3f24018f696 100644 --- a/compiler/testData/codegen/box/ranges/javaInterop/withIndex/javaArrayOfInheritedNotNullWithIndexFailFast.kt +++ b/compiler/testData/codegen/box/ranges/javaInterop/withIndex/javaArrayOfInheritedNotNullWithIndexFailFast.kt @@ -1,6 +1,6 @@ // !LANGUAGE: +StrictJavaNullabilityAssertions // TARGET_BACKEND: JVM -// IGNORE_BACKEND: JVM +// IGNORE_BACKEND: JVM, JVM_IR // IGNORE_BACKEND_FIR: JVM_IR // WITH_RUNTIME @@ -9,6 +9,9 @@ // CodegenAnnotatingVisitor/RuntimeAssertionsOnDeclarationBodyChecker do not analyze the need for not-null assertions on // KtDestructuringDeclarations and their entries. +// Note: this fails on JVM_IR because of KT-36347. +// It requires potentially breaking changes in FE, so please, don't touch it until the language design decision. + // FILE: box.kt import kotlin.test.* diff --git a/compiler/testData/codegen/box/ranges/javaInterop/withIndex/javaCollectionOfExplicitNotNullWithIndexFailFast.kt b/compiler/testData/codegen/box/ranges/javaInterop/withIndex/javaCollectionOfExplicitNotNullWithIndexFailFast.kt index 589e6d60c35..c2c80b32eb3 100644 --- a/compiler/testData/codegen/box/ranges/javaInterop/withIndex/javaCollectionOfExplicitNotNullWithIndexFailFast.kt +++ b/compiler/testData/codegen/box/ranges/javaInterop/withIndex/javaCollectionOfExplicitNotNullWithIndexFailFast.kt @@ -1,6 +1,6 @@ // !LANGUAGE: +StrictJavaNullabilityAssertions // TARGET_BACKEND: JVM -// IGNORE_BACKEND: JVM +// IGNORE_BACKEND: JVM, JVM_IR // IGNORE_BACKEND_FIR: JVM_IR // WITH_RUNTIME // JVM_TARGET: 1.8 @@ -10,6 +10,9 @@ // CodegenAnnotatingVisitor/RuntimeAssertionsOnDeclarationBodyChecker do not analyze the need for not-null assertions on // KtDestructuringDeclarations and their entries. +// Note: this fails on JVM_IR because of KT-36347. +// It requires potentially breaking changes in FE, so please, don't touch it until the language design decision. + // FILE: box.kt import kotlin.test.* diff --git a/compiler/testData/codegen/box/ranges/javaInterop/withIndex/javaIteratorOfNotNullWithIndexFailFast.kt b/compiler/testData/codegen/box/ranges/javaInterop/withIndex/javaIteratorOfNotNullWithIndexFailFast.kt index 3a23610f996..85de0b55bb2 100644 --- a/compiler/testData/codegen/box/ranges/javaInterop/withIndex/javaIteratorOfNotNullWithIndexFailFast.kt +++ b/compiler/testData/codegen/box/ranges/javaInterop/withIndex/javaIteratorOfNotNullWithIndexFailFast.kt @@ -1,6 +1,6 @@ // !LANGUAGE: +StrictJavaNullabilityAssertions // TARGET_BACKEND: JVM -// IGNORE_BACKEND: JVM +// IGNORE_BACKEND: JVM, JVM_IR // IGNORE_BACKEND_FIR: JVM_IR // WITH_RUNTIME // JVM_TARGET: 1.8 @@ -10,6 +10,9 @@ // CodegenAnnotatingVisitor/RuntimeAssertionsOnDeclarationBodyChecker do not analyze the need for not-null assertions on // KtDestructuringDeclarations and their entries. +// Note: this fails on JVM_IR because of KT-36347. +// It requires potentially breaking changes in FE, so please, don't touch it until the language design decision. + // FILE: box.kt import kotlin.test.* diff --git a/compiler/testData/codegen/bytecodeText/nullCheckOptimization/deterministicNotNullChecks.kt b/compiler/testData/codegen/bytecodeText/nullCheckOptimization/deterministicNotNullChecks.kt index c276005eb0c..3d470da336a 100644 --- a/compiler/testData/codegen/bytecodeText/nullCheckOptimization/deterministicNotNullChecks.kt +++ b/compiler/testData/codegen/bytecodeText/nullCheckOptimization/deterministicNotNullChecks.kt @@ -1,7 +1,9 @@ // FILE: test/CallableDescriptor.java -// IGNORE_BACKEND: JVM_IR -// See KT-35656, here JMV_IR correctly generates a nullability assertion for an argument of 'Iterable.contains(T)'. +// JVM_IR: +// Here in 'original in emptySet()' T = '@EnhancedNullability CallableDescriptor' is inferred for 'Iterable.contains(T)'. +// Using value of '@EnhancedNullability CallableDescriptor' type where '@EnhancedNullability CallableDescriptor' is expected +// doesn't cause a null check. package test; diff --git a/compiler/testData/ir/irText/types/enhancedNullability.fir.txt b/compiler/testData/ir/irText/types/enhancedNullability.fir.txt deleted file mode 100644 index 986052738d6..00000000000 --- a/compiler/testData/ir/irText/types/enhancedNullability.fir.txt +++ /dev/null @@ -1,31 +0,0 @@ -FILE fqName: fileName:/enhancedNullability.kt - FUN name:use visibility:public modality:FINAL <> (s:kotlin.String) returnType:kotlin.Unit - VALUE_PARAMETER name:s index:0 type:kotlin.String - BLOCK_BODY - FUN name:testUse visibility:public modality:FINAL <> () returnType:kotlin.Unit - BLOCK_BODY - CALL 'public final fun use (s: kotlin.String): kotlin.Unit declared in ' type=kotlin.Unit origin=null - s: CALL 'public open fun s (): kotlin.String [operator] declared in .J' type=kotlin.String origin=null - FUN name:testLocalVal visibility:public modality:FINAL <> () returnType:kotlin.Unit - BLOCK_BODY - VAR name:local type:kotlin.String [val] - CALL 'public open fun s (): kotlin.String [operator] declared in .J' type=kotlin.String origin=null - FUN name:testReturnValue visibility:public modality:FINAL <> () returnType:kotlin.String - BLOCK_BODY - RETURN type=kotlin.Nothing from='public final fun testReturnValue (): kotlin.String declared in ' - CALL 'public open fun s (): kotlin.String [operator] declared in .J' type=kotlin.String origin=null - PROPERTY name:testGlobalVal visibility:public modality:FINAL [val] - FIELD PROPERTY_BACKING_FIELD name:testGlobalVal type:kotlin.String visibility:private [final,static] - EXPRESSION_BODY - CALL 'public open fun s (): kotlin.String [operator] declared in .J' type=kotlin.String origin=null - FUN DEFAULT_PROPERTY_ACCESSOR name: visibility:public modality:FINAL <> () returnType:kotlin.String - correspondingProperty: PROPERTY name:testGlobalVal visibility:public modality:FINAL [val] - BLOCK_BODY - RETURN type=kotlin.Nothing from='public final fun (): kotlin.String declared in ' - GET_FIELD 'FIELD PROPERTY_BACKING_FIELD name:testGlobalVal type:kotlin.String visibility:private [final,static]' type=kotlin.String origin=null - PROPERTY name:testGlobalValGetter visibility:public modality:FINAL [val] - FUN name: visibility:public modality:FINAL <> () returnType:kotlin.String - correspondingProperty: PROPERTY name:testGlobalValGetter visibility:public modality:FINAL [val] - BLOCK_BODY - RETURN type=kotlin.Nothing from='public final fun (): kotlin.String declared in ' - CALL 'public open fun s (): kotlin.String [operator] declared in .J' type=kotlin.String origin=null diff --git a/compiler/testData/ir/irText/types/enhancedNullability.kt b/compiler/testData/ir/irText/types/enhancedNullability.kt deleted file mode 100644 index b0e32bc5d94..00000000000 --- a/compiler/testData/ir/irText/types/enhancedNullability.kt +++ /dev/null @@ -1,23 +0,0 @@ -// FILE: enhancedNullability.kt -fun use(s: String) {} - -fun testUse() { - use(J.s()) -} - -fun testLocalVal() { - val local = J.s() -} - -fun testReturnValue() = J.s() - -val testGlobalVal = J.s() - -val testGlobalValGetter get() = J.s() - -// FILE: J.java -import org.jetbrains.annotations.* - -public class J { - public static @NotNull String s() { return null; } -} diff --git a/compiler/testData/ir/irText/types/nullChecks/enhancedNullability.fir.txt b/compiler/testData/ir/irText/types/nullChecks/enhancedNullability.fir.txt new file mode 100644 index 00000000000..d02262b210a --- /dev/null +++ b/compiler/testData/ir/irText/types/nullChecks/enhancedNullability.fir.txt @@ -0,0 +1,47 @@ +FILE fqName: fileName:/enhancedNullability.kt + FUN name:use visibility:public modality:FINAL <> (s:kotlin.String) returnType:kotlin.Unit + VALUE_PARAMETER name:s index:0 type:kotlin.String + BLOCK_BODY + FUN name:testUse visibility:public modality:FINAL <> () returnType:kotlin.Unit + BLOCK_BODY + CALL 'public final fun use (s: kotlin.String): kotlin.Unit declared in ' type=kotlin.Unit origin=null + s: CALL 'public open fun notNullString (): kotlin.String [operator] declared in .J' type=kotlin.String origin=null + FUN name:testLocalVal visibility:public modality:FINAL <> () returnType:kotlin.Unit + BLOCK_BODY + VAR name:local type:kotlin.String [val] + CALL 'public open fun notNullString (): kotlin.String [operator] declared in .J' type=kotlin.String origin=null + FUN name:testReturnValue visibility:public modality:FINAL <> () returnType:kotlin.String + BLOCK_BODY + RETURN type=kotlin.Nothing from='public final fun testReturnValue (): kotlin.String declared in ' + CALL 'public open fun notNullString (): kotlin.String [operator] declared in .J' type=kotlin.String origin=null + PROPERTY name:testGlobalVal visibility:public modality:FINAL [val] + FIELD PROPERTY_BACKING_FIELD name:testGlobalVal type:kotlin.String visibility:private [final,static] + EXPRESSION_BODY + CALL 'public open fun notNullString (): kotlin.String [operator] declared in .J' type=kotlin.String origin=null + FUN DEFAULT_PROPERTY_ACCESSOR name: visibility:public modality:FINAL <> () returnType:kotlin.String + correspondingProperty: PROPERTY name:testGlobalVal visibility:public modality:FINAL [val] + BLOCK_BODY + RETURN type=kotlin.Nothing from='public final fun (): kotlin.String declared in ' + GET_FIELD 'FIELD PROPERTY_BACKING_FIELD name:testGlobalVal type:kotlin.String visibility:private [final,static]' type=kotlin.String origin=null + PROPERTY name:testGlobalValGetter visibility:public modality:FINAL [val] + FUN name: visibility:public modality:FINAL <> () returnType:kotlin.String + correspondingProperty: PROPERTY name:testGlobalValGetter visibility:public modality:FINAL [val] + BLOCK_BODY + RETURN type=kotlin.Nothing from='public final fun (): kotlin.String declared in ' + CALL 'public open fun notNullString (): kotlin.String [operator] declared in .J' type=kotlin.String origin=null + FUN name:testJUse visibility:public modality:FINAL <> () returnType:kotlin.Unit + BLOCK_BODY + CALL 'public open fun use (s: kotlin.String): kotlin.Unit [operator] declared in .J' type=kotlin.Unit origin=null + s: CALL 'public open fun nullString (): kotlin.String? [operator] declared in .J' type=kotlin.String? origin=null + CALL 'public open fun use (s: kotlin.String): kotlin.Unit [operator] declared in .J' type=kotlin.Unit origin=null + s: CALL 'public open fun notNullString (): kotlin.String [operator] declared in .J' type=kotlin.String origin=null + FUN name:testLocalVarUse visibility:public modality:FINAL <> () returnType:kotlin.Unit + BLOCK_BODY + VAR name:ns type:kotlin.String? [val] + CALL 'public open fun nullString (): kotlin.String? [operator] declared in .J' type=kotlin.String? origin=null + CALL 'public open fun use (s: kotlin.String): kotlin.Unit [operator] declared in .J' type=kotlin.Unit origin=null + s: GET_VAR 'val ns: kotlin.String? [val] declared in .testLocalVarUse' type=kotlin.String? origin=null + VAR name:nns type:kotlin.String [val] + CALL 'public open fun notNullString (): kotlin.String [operator] declared in .J' type=kotlin.String origin=null + CALL 'public open fun use (s: kotlin.String): kotlin.Unit [operator] declared in .J' type=kotlin.Unit origin=null + s: GET_VAR 'val nns: kotlin.String [val] declared in .testLocalVarUse' type=kotlin.String origin=null diff --git a/compiler/testData/ir/irText/types/nullChecks/enhancedNullability.kt b/compiler/testData/ir/irText/types/nullChecks/enhancedNullability.kt new file mode 100644 index 00000000000..71cb62cdbfa --- /dev/null +++ b/compiler/testData/ir/irText/types/nullChecks/enhancedNullability.kt @@ -0,0 +1,39 @@ +// FILE: enhancedNullability.kt +// WITH_JDK +fun use(s: String) {} + +fun testUse() { + use(J.notNullString()) +} + +fun testLocalVal() { + val local = J.notNullString() +} + +fun testReturnValue() = J.notNullString() + +val testGlobalVal = J.notNullString() + +val testGlobalValGetter get() = J.notNullString() + +fun testJUse() { + J.use(J.nullString()) + J.use(J.notNullString()) +} + +fun testLocalVarUse() { + val ns = J.nullString() + J.use(ns) + + val nns = J.notNullString() + J.use(nns) +} + +// FILE: J.java +import org.jetbrains.annotations.*; + +public class J { + public static void use(@NotNull String s) {} + public static String nullString() { return null; } + public static @NotNull String notNullString() { return null; } +} diff --git a/compiler/testData/ir/irText/types/enhancedNullability.txt b/compiler/testData/ir/irText/types/nullChecks/enhancedNullability.txt similarity index 52% rename from compiler/testData/ir/irText/types/enhancedNullability.txt rename to compiler/testData/ir/irText/types/nullChecks/enhancedNullability.txt index 0f43c87601e..4349ca7d457 100644 --- a/compiler/testData/ir/irText/types/enhancedNullability.txt +++ b/compiler/testData/ir/irText/types/nullChecks/enhancedNullability.txt @@ -6,22 +6,22 @@ FILE fqName: fileName:/enhancedNullability.kt BLOCK_BODY CALL 'public final fun use (s: kotlin.String): kotlin.Unit declared in ' type=kotlin.Unit origin=null s: TYPE_OP type=kotlin.String origin=IMPLICIT_NOTNULL typeOperand=kotlin.String - CALL 'public open fun s (): kotlin.String declared in .J' type=kotlin.String origin=null + CALL 'public open fun notNullString (): kotlin.String declared in .J' type=kotlin.String origin=null FUN name:testLocalVal visibility:public modality:FINAL <> () returnType:kotlin.Unit BLOCK_BODY VAR name:local type:kotlin.String [val] TYPE_OP type=kotlin.String origin=IMPLICIT_NOTNULL typeOperand=kotlin.String - CALL 'public open fun s (): kotlin.String declared in .J' type=kotlin.String origin=null + CALL 'public open fun notNullString (): kotlin.String declared in .J' type=kotlin.String origin=null FUN name:testReturnValue visibility:public modality:FINAL <> () returnType:kotlin.String BLOCK_BODY RETURN type=kotlin.Nothing from='public final fun testReturnValue (): kotlin.String declared in ' TYPE_OP type=kotlin.String origin=IMPLICIT_NOTNULL typeOperand=kotlin.String - CALL 'public open fun s (): kotlin.String declared in .J' type=kotlin.String origin=null + CALL 'public open fun notNullString (): kotlin.String declared in .J' type=kotlin.String origin=null PROPERTY name:testGlobalVal visibility:public modality:FINAL [val] FIELD PROPERTY_BACKING_FIELD name:testGlobalVal type:kotlin.String visibility:private [final,static] EXPRESSION_BODY TYPE_OP type=kotlin.String origin=IMPLICIT_NOTNULL typeOperand=kotlin.String - CALL 'public open fun s (): kotlin.String declared in .J' type=kotlin.String origin=null + CALL 'public open fun notNullString (): kotlin.String declared in .J' type=kotlin.String origin=null FUN DEFAULT_PROPERTY_ACCESSOR name: visibility:public modality:FINAL <> () returnType:kotlin.String correspondingProperty: PROPERTY name:testGlobalVal visibility:public modality:FINAL [val] BLOCK_BODY @@ -33,4 +33,21 @@ FILE fqName: fileName:/enhancedNullability.kt BLOCK_BODY RETURN type=kotlin.Nothing from='public final fun (): kotlin.String declared in ' TYPE_OP type=kotlin.String origin=IMPLICIT_NOTNULL typeOperand=kotlin.String - CALL 'public open fun s (): kotlin.String declared in .J' type=kotlin.String origin=null + CALL 'public open fun notNullString (): kotlin.String declared in .J' type=kotlin.String origin=null + FUN name:testJUse visibility:public modality:FINAL <> () returnType:kotlin.Unit + BLOCK_BODY + CALL 'public open fun use (s: kotlin.String): kotlin.Unit declared in .J' type=kotlin.Unit origin=null + s: CALL 'public open fun nullString (): kotlin.String? declared in .J' type=kotlin.String? origin=null + CALL 'public open fun use (s: kotlin.String): kotlin.Unit declared in .J' type=kotlin.Unit origin=null + s: CALL 'public open fun notNullString (): kotlin.String declared in .J' type=kotlin.String origin=null + FUN name:testLocalVarUse visibility:public modality:FINAL <> () returnType:kotlin.Unit + BLOCK_BODY + VAR name:ns type:kotlin.String? [val] + CALL 'public open fun nullString (): kotlin.String? declared in .J' type=kotlin.String? origin=null + CALL 'public open fun use (s: kotlin.String): kotlin.Unit declared in .J' type=kotlin.Unit origin=null + s: GET_VAR 'val ns: kotlin.String? [val] declared in .testLocalVarUse' type=kotlin.String? origin=null + VAR name:nns type:kotlin.String [val] + TYPE_OP type=kotlin.String origin=IMPLICIT_NOTNULL typeOperand=kotlin.String + CALL 'public open fun notNullString (): kotlin.String declared in .J' type=kotlin.String origin=null + CALL 'public open fun use (s: kotlin.String): kotlin.Unit declared in .J' type=kotlin.Unit origin=null + s: GET_VAR 'val nns: kotlin.String [val] declared in .testLocalVarUse' type=kotlin.String origin=null diff --git a/compiler/testData/ir/irText/types/nullChecks/enhancedNullabilityInDestructuringAssignment.fir.txt b/compiler/testData/ir/irText/types/nullChecks/enhancedNullabilityInDestructuringAssignment.fir.txt new file mode 100644 index 00000000000..53be7425f47 --- /dev/null +++ b/compiler/testData/ir/irText/types/nullChecks/enhancedNullabilityInDestructuringAssignment.fir.txt @@ -0,0 +1,186 @@ +FILE fqName: fileName:/enhancedNullabilityInDestructuringAssignment.kt + FUN name:use visibility:public modality:FINAL <> (x:kotlin.Any, y:kotlin.Any) returnType:kotlin.Unit + VALUE_PARAMETER name:x index:0 type:kotlin.Any + VALUE_PARAMETER name:y index:1 type:kotlin.Any + BLOCK_BODY + CLASS CLASS name:P modality:FINAL visibility:public superTypes:[kotlin.Any] + $this: VALUE_PARAMETER INSTANCE_RECEIVER name: type:.P + CONSTRUCTOR visibility:public <> (x:kotlin.Int, y:kotlin.Int) returnType:.P [primary] + VALUE_PARAMETER name:x index:0 type:kotlin.Int + VALUE_PARAMETER name:y index:1 type:kotlin.Int + BLOCK_BODY + DELEGATING_CONSTRUCTOR_CALL 'public constructor () [primary] declared in kotlin.Any' + INSTANCE_INITIALIZER_CALL classDescriptor='CLASS CLASS name:P modality:FINAL visibility:public superTypes:[kotlin.Any]' + PROPERTY name:x visibility:public modality:FINAL [val] + FIELD PROPERTY_BACKING_FIELD name:x type:kotlin.Int visibility:private [final] + EXPRESSION_BODY + GET_VAR 'x: kotlin.Int declared in .P.' type=kotlin.Int origin=INITIALIZE_PROPERTY_FROM_PARAMETER + FUN DEFAULT_PROPERTY_ACCESSOR name: visibility:public modality:FINAL <> ($this:.P) returnType:kotlin.Int + correspondingProperty: PROPERTY name:x visibility:public modality:FINAL [val] + $this: VALUE_PARAMETER name: type:.P + BLOCK_BODY + RETURN type=kotlin.Nothing from='public final fun (): kotlin.Int declared in .P' + GET_FIELD 'FIELD PROPERTY_BACKING_FIELD name:x type:kotlin.Int visibility:private [final]' type=kotlin.Int origin=null + receiver: GET_VAR ': .P declared in .P.' type=.P origin=null + PROPERTY name:y visibility:public modality:FINAL [val] + FIELD PROPERTY_BACKING_FIELD name:y type:kotlin.Int visibility:private [final] + EXPRESSION_BODY + GET_VAR 'y: kotlin.Int declared in .P.' type=kotlin.Int origin=INITIALIZE_PROPERTY_FROM_PARAMETER + FUN DEFAULT_PROPERTY_ACCESSOR name: visibility:public modality:FINAL <> ($this:.P) returnType:kotlin.Int + correspondingProperty: PROPERTY name:y visibility:public modality:FINAL [val] + $this: VALUE_PARAMETER name: type:.P + BLOCK_BODY + RETURN type=kotlin.Nothing from='public final fun (): kotlin.Int declared in .P' + GET_FIELD 'FIELD PROPERTY_BACKING_FIELD name:y type:kotlin.Int visibility:private [final]' type=kotlin.Int origin=null + receiver: GET_VAR ': .P declared in .P.' type=.P origin=null + FUN name:component1 visibility:public modality:FINAL <> ($this:.P) returnType:kotlin.Int [operator] + $this: VALUE_PARAMETER name: type:.P + BLOCK_BODY + RETURN type=kotlin.Nothing from='public final fun component1 (): kotlin.Int [operator] declared in .P' + CALL 'public final fun (): kotlin.Int declared in .P' type=kotlin.Int origin=null + $this: GET_VAR ': .P declared in .P.component1' type=.P origin=null + FUN name:component2 visibility:public modality:FINAL <> ($this:.P) returnType:kotlin.Int [operator] + $this: VALUE_PARAMETER name: type:.P + BLOCK_BODY + RETURN type=kotlin.Nothing from='public final fun component2 (): kotlin.Int [operator] declared in .P' + CALL 'public final fun (): kotlin.Int declared in .P' type=kotlin.Int origin=null + $this: GET_VAR ': .P declared in .P.component2' type=.P origin=null + FUN FAKE_OVERRIDE name:equals visibility:public modality:OPEN <> ($this:kotlin.Any, other:kotlin.Any?) returnType:kotlin.Boolean [fake_override,operator] + overridden: + public open fun equals (other: kotlin.Any?): kotlin.Boolean [operator] declared in kotlin.Any + $this: VALUE_PARAMETER name: type:kotlin.Any + VALUE_PARAMETER name:other index:0 type:kotlin.Any? + FUN FAKE_OVERRIDE name:hashCode visibility:public modality:OPEN <> ($this:kotlin.Any) returnType:kotlin.Int [fake_override] + overridden: + public open fun hashCode (): kotlin.Int declared in kotlin.Any + $this: VALUE_PARAMETER name: type:kotlin.Any + FUN FAKE_OVERRIDE name:toString visibility:public modality:OPEN <> ($this:kotlin.Any) returnType:kotlin.String [fake_override] + overridden: + public open fun toString (): kotlin.String declared in kotlin.Any + $this: VALUE_PARAMETER name: type:kotlin.Any + CLASS CLASS name:Q modality:FINAL visibility:public superTypes:[kotlin.Any] + $this: VALUE_PARAMETER INSTANCE_RECEIVER name: type:.Q + TYPE_PARAMETER name:T1 index:0 variance: superTypes:[kotlin.Any?] + TYPE_PARAMETER name:T2 index:1 variance: superTypes:[kotlin.Any?] + CONSTRUCTOR visibility:public <> (x:T1 of .Q, y:T2 of .Q) returnType:.Q.Q, T2 of .Q> [primary] + VALUE_PARAMETER name:x index:0 type:T1 of .Q + VALUE_PARAMETER name:y index:1 type:T2 of .Q + BLOCK_BODY + DELEGATING_CONSTRUCTOR_CALL 'public constructor () [primary] declared in kotlin.Any' + INSTANCE_INITIALIZER_CALL classDescriptor='CLASS CLASS name:Q modality:FINAL visibility:public superTypes:[kotlin.Any]' + PROPERTY name:x visibility:public modality:FINAL [val] + FIELD PROPERTY_BACKING_FIELD name:x type:T1 of .Q visibility:private [final] + EXPRESSION_BODY + GET_VAR 'x: T1 of .Q declared in .Q.' type=T1 of .Q origin=INITIALIZE_PROPERTY_FROM_PARAMETER + FUN DEFAULT_PROPERTY_ACCESSOR name: visibility:public modality:FINAL <> ($this:.Q) returnType:T1 of .Q + correspondingProperty: PROPERTY name:x visibility:public modality:FINAL [val] + $this: VALUE_PARAMETER name: type:.Q + BLOCK_BODY + RETURN type=kotlin.Nothing from='public final fun (): T1 of .Q declared in .Q' + GET_FIELD 'FIELD PROPERTY_BACKING_FIELD name:x type:T1 of .Q visibility:private [final]' type=T1 of .Q origin=null + receiver: GET_VAR ': .Q declared in .Q.' type=.Q origin=null + PROPERTY name:y visibility:public modality:FINAL [val] + FIELD PROPERTY_BACKING_FIELD name:y type:T2 of .Q visibility:private [final] + EXPRESSION_BODY + GET_VAR 'y: T2 of .Q declared in .Q.' type=T2 of .Q origin=INITIALIZE_PROPERTY_FROM_PARAMETER + FUN DEFAULT_PROPERTY_ACCESSOR name: visibility:public modality:FINAL <> ($this:.Q) returnType:T2 of .Q + correspondingProperty: PROPERTY name:y visibility:public modality:FINAL [val] + $this: VALUE_PARAMETER name: type:.Q + BLOCK_BODY + RETURN type=kotlin.Nothing from='public final fun (): T2 of .Q declared in .Q' + GET_FIELD 'FIELD PROPERTY_BACKING_FIELD name:y type:T2 of .Q visibility:private [final]' type=T2 of .Q origin=null + receiver: GET_VAR ': .Q declared in .Q.' type=.Q origin=null + FUN name:component1 visibility:public modality:FINAL <> ($this:.Q) returnType:T1 of .Q [operator] + $this: VALUE_PARAMETER name: type:.Q + BLOCK_BODY + RETURN type=kotlin.Nothing from='public final fun component1 (): T1 of .Q [operator] declared in .Q' + CALL 'public final fun (): T1 of .Q declared in .Q' type=T1 of .Q origin=null + $this: GET_VAR ': .Q declared in .Q.component1' type=.Q origin=null + FUN name:component2 visibility:public modality:FINAL <> ($this:.Q) returnType:T2 of .Q [operator] + $this: VALUE_PARAMETER name: type:.Q + BLOCK_BODY + RETURN type=kotlin.Nothing from='public final fun component2 (): T2 of .Q [operator] declared in .Q' + CALL 'public final fun (): T2 of .Q declared in .Q' type=T2 of .Q origin=null + $this: GET_VAR ': .Q declared in .Q.component2' type=.Q origin=null + FUN FAKE_OVERRIDE name:equals visibility:public modality:OPEN <> ($this:kotlin.Any, other:kotlin.Any?) returnType:kotlin.Boolean [fake_override,operator] + overridden: + public open fun equals (other: kotlin.Any?): kotlin.Boolean [operator] declared in kotlin.Any + $this: VALUE_PARAMETER name: type:kotlin.Any + VALUE_PARAMETER name:other index:0 type:kotlin.Any? + FUN FAKE_OVERRIDE name:hashCode visibility:public modality:OPEN <> ($this:kotlin.Any) returnType:kotlin.Int [fake_override] + overridden: + public open fun hashCode (): kotlin.Int declared in kotlin.Any + $this: VALUE_PARAMETER name: type:kotlin.Any + FUN FAKE_OVERRIDE name:toString visibility:public modality:OPEN <> ($this:kotlin.Any) returnType:kotlin.String [fake_override] + overridden: + public open fun toString (): kotlin.String declared in kotlin.Any + $this: VALUE_PARAMETER name: type:kotlin.Any + FUN name:test1 visibility:public modality:FINAL <> () returnType:kotlin.Unit + BLOCK_BODY + VAR IR_TEMPORARY_VARIABLE name:tmp_0 type:.P [val] + CALL 'public open fun notNullP (): .P [operator] declared in .J' type=.P origin=null + VAR name:x type:kotlin.Int [val] + CALL 'public final fun component1 (): kotlin.Int [operator] declared in .P' type=kotlin.Int origin=null + $this: GET_VAR 'val tmp_0: .P [val] declared in .test1' type=.P origin=null + VAR name:y type:kotlin.Int [val] + CALL 'public final fun component2 (): kotlin.Int [operator] declared in .P' type=kotlin.Int origin=null + $this: GET_VAR 'val tmp_0: .P [val] declared in .test1' type=.P origin=null + CALL 'public final fun use (x: kotlin.Any, y: kotlin.Any): kotlin.Unit declared in ' type=kotlin.Unit origin=null + x: GET_VAR 'val x: kotlin.Int [val] declared in .test1' type=kotlin.Int origin=null + y: GET_VAR 'val y: kotlin.Int [val] declared in .test1' type=kotlin.Int origin=null + FUN name:test2 visibility:public modality:FINAL <> () returnType:kotlin.Unit + BLOCK_BODY + VAR IR_TEMPORARY_VARIABLE name:tmp_1 type:.Q? [val] + CALL 'public open fun notNullComponents (): .Q? [operator] declared in .J' type=.Q? origin=null + VAR name:x type:kotlin.String [val] + CALL 'public final fun component1 (): kotlin.String [operator] declared in .Q' type=kotlin.String origin=null + $this: GET_VAR 'val tmp_1: .Q? [val] declared in .test2' type=.Q? origin=null + VAR name:y type:kotlin.String [val] + CALL 'public final fun component2 (): kotlin.String [operator] declared in .Q' type=kotlin.String origin=null + $this: GET_VAR 'val tmp_1: .Q? [val] declared in .test2' type=.Q? origin=null + CALL 'public final fun use (x: kotlin.Any, y: kotlin.Any): kotlin.Unit declared in ' type=kotlin.Unit origin=null + x: GET_VAR 'val x: kotlin.String [val] declared in .test2' type=kotlin.String origin=null + y: GET_VAR 'val y: kotlin.String [val] declared in .test2' type=kotlin.String origin=null + FUN name:test2Desugared visibility:public modality:FINAL <> () returnType:kotlin.Unit + BLOCK_BODY + VAR name:tmp type:.Q? [val] + CALL 'public open fun notNullComponents (): .Q? [operator] declared in .J' type=.Q? origin=null + VAR name:x type:kotlin.String [val] + CALL 'public final fun component1 (): kotlin.String [operator] declared in .Q' type=kotlin.String origin=null + $this: GET_VAR 'val tmp: .Q? [val] declared in .test2Desugared' type=.Q? origin=null + VAR name:y type:kotlin.String [val] + CALL 'public final fun component2 (): kotlin.String [operator] declared in .Q' type=kotlin.String origin=null + $this: GET_VAR 'val tmp: .Q? [val] declared in .test2Desugared' type=.Q? origin=null + CALL 'public final fun use (x: kotlin.Any, y: kotlin.Any): kotlin.Unit declared in ' type=kotlin.Unit origin=null + x: GET_VAR 'val x: kotlin.String [val] declared in .test2Desugared' type=kotlin.String origin=null + y: GET_VAR 'val y: kotlin.String [val] declared in .test2Desugared' type=kotlin.String origin=null + FUN name:test3 visibility:public modality:FINAL <> () returnType:kotlin.Unit + BLOCK_BODY + VAR IR_TEMPORARY_VARIABLE name:tmp_2 type:.Q [val] + CALL 'public open fun notNullQAndComponents (): .Q [operator] declared in .J' type=.Q origin=null + VAR name:x type:kotlin.String [val] + CALL 'public final fun component1 (): kotlin.String [operator] declared in .Q' type=kotlin.String origin=null + $this: GET_VAR 'val tmp_2: .Q [val] declared in .test3' type=.Q origin=null + VAR name:y type:kotlin.String [val] + CALL 'public final fun component2 (): kotlin.String [operator] declared in .Q' type=kotlin.String origin=null + $this: GET_VAR 'val tmp_2: .Q [val] declared in .test3' type=.Q origin=null + CALL 'public final fun use (x: kotlin.Any, y: kotlin.Any): kotlin.Unit declared in ' type=kotlin.Unit origin=null + x: GET_VAR 'val x: kotlin.String [val] declared in .test3' type=kotlin.String origin=null + y: GET_VAR 'val y: kotlin.String [val] declared in .test3' type=kotlin.String origin=null + FUN name:test4 visibility:public modality:FINAL <> () returnType:kotlin.Unit + BLOCK_BODY + VAR IR_TEMPORARY_VARIABLE name:tmp_3 type:kotlin.collections.IndexedValue<.P> [val] + CALL 'public final fun first (): T of kotlin.collections.first declared in kotlin.collections' type=kotlin.collections.IndexedValue<.P> origin=null + : kotlin.collections.IndexedValue<.P> + $receiver: CALL 'public final fun withIndex (): kotlin.collections.Iterable> declared in kotlin.collections' type=kotlin.collections.Iterable.P>> origin=null + : .P + $receiver: CALL 'public open fun listOfNotNull (): kotlin.collections.List<.P>? [operator] declared in .J' type=kotlin.collections.List<.P>? origin=null + VAR name:x type:kotlin.Int [val] + CALL 'public final fun component1 (): kotlin.Int [operator] declared in kotlin.collections.IndexedValue' type=kotlin.Int origin=null + $this: GET_VAR 'val tmp_3: kotlin.collections.IndexedValue<.P> [val] declared in .test4' type=kotlin.collections.IndexedValue<.P> origin=null + VAR name:y type:.P [val] + CALL 'public final fun component2 (): .P [operator] declared in kotlin.collections.IndexedValue' type=.P origin=null + $this: GET_VAR 'val tmp_3: kotlin.collections.IndexedValue<.P> [val] declared in .test4' type=kotlin.collections.IndexedValue<.P> origin=null + CALL 'public final fun use (x: kotlin.Any, y: kotlin.Any): kotlin.Unit declared in ' type=kotlin.Unit origin=null + x: GET_VAR 'val x: kotlin.Int [val] declared in .test4' type=kotlin.Int origin=null + y: GET_VAR 'val y: .P [val] declared in .test4' type=.P origin=null diff --git a/compiler/testData/ir/irText/types/nullChecks/enhancedNullabilityInDestructuringAssignment.kt b/compiler/testData/ir/irText/types/nullChecks/enhancedNullabilityInDestructuringAssignment.kt new file mode 100644 index 00000000000..854ac712de1 --- /dev/null +++ b/compiler/testData/ir/irText/types/nullChecks/enhancedNullabilityInDestructuringAssignment.kt @@ -0,0 +1,59 @@ +// FILE: enhancedNullabilityInDestructuringAssignment.kt +// WITH_RUNTIME + +fun use(x: Any, y: Any) {} + +class P(val x: Int, val y: Int) { + operator fun component1() = x + operator fun component2() = y +} + +class Q(val x: T1, val y: T2) { + operator fun component1() = x + operator fun component2() = y +} + +fun test1() { + // See KT-36344 + val (x, y) = J.notNullP() + use(x, y) +} + +fun test2() { + // See KT-36347 + val (x, y) = J.notNullComponents() + use(x, y) +} + +fun test2Desugared() { + val tmp = J.notNullComponents() + val x = tmp.component1() + val y = tmp.component2() + use(x, y) +} + +fun test3() { + // See KT-36347 + val (x, y) = J.notNullQAndComponents() + use(x, y) +} + +fun test4() { + // See KT-36347 + val (x, y) = J.listOfNotNull().withIndex().first() + use(x, y) +} + +// FILE: J.java +import java.util.*; +import org.jetbrains.annotations.*; + +public static class J { + public static @NotNull P notNullP() { return null; } + + public static Q<@NotNull String, @NotNull String> notNullComponents() { return null; } + + public static @NotNull Q<@NotNull String, @NotNull String> notNullQAndComponents() { return null; } + + public static List<@NotNull P> listOfNotNull() { return null; } +} \ No newline at end of file diff --git a/compiler/testData/ir/irText/types/nullChecks/enhancedNullabilityInDestructuringAssignment.txt b/compiler/testData/ir/irText/types/nullChecks/enhancedNullabilityInDestructuringAssignment.txt new file mode 100644 index 00000000000..2c86ba652f4 --- /dev/null +++ b/compiler/testData/ir/irText/types/nullChecks/enhancedNullabilityInDestructuringAssignment.txt @@ -0,0 +1,206 @@ +FILE fqName: fileName:/enhancedNullabilityInDestructuringAssignment.kt + FUN name:use visibility:public modality:FINAL <> (x:kotlin.Any, y:kotlin.Any) returnType:kotlin.Unit + VALUE_PARAMETER name:x index:0 type:kotlin.Any + VALUE_PARAMETER name:y index:1 type:kotlin.Any + BLOCK_BODY + CLASS CLASS name:P modality:FINAL visibility:public superTypes:[kotlin.Any] + $this: VALUE_PARAMETER INSTANCE_RECEIVER name: type:.P + CONSTRUCTOR visibility:public <> (x:kotlin.Int, y:kotlin.Int) returnType:.P [primary] + VALUE_PARAMETER name:x index:0 type:kotlin.Int + VALUE_PARAMETER name:y index:1 type:kotlin.Int + BLOCK_BODY + DELEGATING_CONSTRUCTOR_CALL 'public constructor () [primary] declared in kotlin.Any' + INSTANCE_INITIALIZER_CALL classDescriptor='CLASS CLASS name:P modality:FINAL visibility:public superTypes:[kotlin.Any]' + PROPERTY name:x visibility:public modality:FINAL [val] + FIELD PROPERTY_BACKING_FIELD name:x type:kotlin.Int visibility:private [final] + EXPRESSION_BODY + GET_VAR 'x: kotlin.Int declared in .P.' type=kotlin.Int origin=INITIALIZE_PROPERTY_FROM_PARAMETER + FUN DEFAULT_PROPERTY_ACCESSOR name: visibility:public modality:FINAL <> ($this:.P) returnType:kotlin.Int + correspondingProperty: PROPERTY name:x visibility:public modality:FINAL [val] + $this: VALUE_PARAMETER name: type:.P + BLOCK_BODY + RETURN type=kotlin.Nothing from='public final fun (): kotlin.Int declared in .P' + GET_FIELD 'FIELD PROPERTY_BACKING_FIELD name:x type:kotlin.Int visibility:private [final]' type=kotlin.Int origin=null + receiver: GET_VAR ': .P declared in .P.' type=.P origin=null + PROPERTY name:y visibility:public modality:FINAL [val] + FIELD PROPERTY_BACKING_FIELD name:y type:kotlin.Int visibility:private [final] + EXPRESSION_BODY + GET_VAR 'y: kotlin.Int declared in .P.' type=kotlin.Int origin=INITIALIZE_PROPERTY_FROM_PARAMETER + FUN DEFAULT_PROPERTY_ACCESSOR name: visibility:public modality:FINAL <> ($this:.P) returnType:kotlin.Int + correspondingProperty: PROPERTY name:y visibility:public modality:FINAL [val] + $this: VALUE_PARAMETER name: type:.P + BLOCK_BODY + RETURN type=kotlin.Nothing from='public final fun (): kotlin.Int declared in .P' + GET_FIELD 'FIELD PROPERTY_BACKING_FIELD name:y type:kotlin.Int visibility:private [final]' type=kotlin.Int origin=null + receiver: GET_VAR ': .P declared in .P.' type=.P origin=null + FUN name:component1 visibility:public modality:FINAL <> ($this:.P) returnType:kotlin.Int [operator] + $this: VALUE_PARAMETER name: type:.P + BLOCK_BODY + RETURN type=kotlin.Nothing from='public final fun component1 (): kotlin.Int [operator] declared in .P' + CALL 'public final fun (): kotlin.Int declared in .P' type=kotlin.Int origin=GET_PROPERTY + $this: GET_VAR ': .P declared in .P.component1' type=.P origin=null + FUN name:component2 visibility:public modality:FINAL <> ($this:.P) returnType:kotlin.Int [operator] + $this: VALUE_PARAMETER name: type:.P + BLOCK_BODY + RETURN type=kotlin.Nothing from='public final fun component2 (): kotlin.Int [operator] declared in .P' + CALL 'public final fun (): kotlin.Int declared in .P' type=kotlin.Int origin=GET_PROPERTY + $this: GET_VAR ': .P declared in .P.component2' type=.P origin=null + FUN FAKE_OVERRIDE name:equals visibility:public modality:OPEN <> ($this:kotlin.Any, other:kotlin.Any?) returnType:kotlin.Boolean [fake_override,operator] + overridden: + public open fun equals (other: kotlin.Any?): kotlin.Boolean [operator] declared in kotlin.Any + $this: VALUE_PARAMETER name: type:kotlin.Any + VALUE_PARAMETER name:other index:0 type:kotlin.Any? + FUN FAKE_OVERRIDE name:hashCode visibility:public modality:OPEN <> ($this:kotlin.Any) returnType:kotlin.Int [fake_override] + overridden: + public open fun hashCode (): kotlin.Int declared in kotlin.Any + $this: VALUE_PARAMETER name: type:kotlin.Any + FUN FAKE_OVERRIDE name:toString visibility:public modality:OPEN <> ($this:kotlin.Any) returnType:kotlin.String [fake_override] + overridden: + public open fun toString (): kotlin.String declared in kotlin.Any + $this: VALUE_PARAMETER name: type:kotlin.Any + CLASS CLASS name:Q modality:FINAL visibility:public superTypes:[kotlin.Any] + $this: VALUE_PARAMETER INSTANCE_RECEIVER name: type:.Q.Q, T2 of .Q> + TYPE_PARAMETER name:T1 index:0 variance: superTypes:[kotlin.Any?] + TYPE_PARAMETER name:T2 index:1 variance: superTypes:[kotlin.Any?] + CONSTRUCTOR visibility:public <> (x:T1 of .Q, y:T2 of .Q) returnType:.Q.Q, T2 of .Q> [primary] + VALUE_PARAMETER name:x index:0 type:T1 of .Q + VALUE_PARAMETER name:y index:1 type:T2 of .Q + BLOCK_BODY + DELEGATING_CONSTRUCTOR_CALL 'public constructor () [primary] declared in kotlin.Any' + INSTANCE_INITIALIZER_CALL classDescriptor='CLASS CLASS name:Q modality:FINAL visibility:public superTypes:[kotlin.Any]' + PROPERTY name:x visibility:public modality:FINAL [val] + FIELD PROPERTY_BACKING_FIELD name:x type:T1 of .Q visibility:private [final] + EXPRESSION_BODY + GET_VAR 'x: T1 of .Q declared in .Q.' type=T1 of .Q origin=INITIALIZE_PROPERTY_FROM_PARAMETER + FUN DEFAULT_PROPERTY_ACCESSOR name: visibility:public modality:FINAL <> ($this:.Q.Q, T2 of .Q>) returnType:T1 of .Q + correspondingProperty: PROPERTY name:x visibility:public modality:FINAL [val] + $this: VALUE_PARAMETER name: type:.Q.Q, T2 of .Q> + BLOCK_BODY + RETURN type=kotlin.Nothing from='public final fun (): T1 of .Q declared in .Q' + GET_FIELD 'FIELD PROPERTY_BACKING_FIELD name:x type:T1 of .Q visibility:private [final]' type=T1 of .Q origin=null + receiver: GET_VAR ': .Q.Q, T2 of .Q> declared in .Q.' type=.Q.Q, T2 of .Q> origin=null + PROPERTY name:y visibility:public modality:FINAL [val] + FIELD PROPERTY_BACKING_FIELD name:y type:T2 of .Q visibility:private [final] + EXPRESSION_BODY + GET_VAR 'y: T2 of .Q declared in .Q.' type=T2 of .Q origin=INITIALIZE_PROPERTY_FROM_PARAMETER + FUN DEFAULT_PROPERTY_ACCESSOR name: visibility:public modality:FINAL <> ($this:.Q.Q, T2 of .Q>) returnType:T2 of .Q + correspondingProperty: PROPERTY name:y visibility:public modality:FINAL [val] + $this: VALUE_PARAMETER name: type:.Q.Q, T2 of .Q> + BLOCK_BODY + RETURN type=kotlin.Nothing from='public final fun (): T2 of .Q declared in .Q' + GET_FIELD 'FIELD PROPERTY_BACKING_FIELD name:y type:T2 of .Q visibility:private [final]' type=T2 of .Q origin=null + receiver: GET_VAR ': .Q.Q, T2 of .Q> declared in .Q.' type=.Q.Q, T2 of .Q> origin=null + FUN name:component1 visibility:public modality:FINAL <> ($this:.Q.Q, T2 of .Q>) returnType:T1 of .Q [operator] + $this: VALUE_PARAMETER name: type:.Q.Q, T2 of .Q> + BLOCK_BODY + RETURN type=kotlin.Nothing from='public final fun component1 (): T1 of .Q [operator] declared in .Q' + CALL 'public final fun (): T1 of .Q declared in .Q' type=T1 of .Q origin=GET_PROPERTY + $this: GET_VAR ': .Q.Q, T2 of .Q> declared in .Q.component1' type=.Q.Q, T2 of .Q> origin=null + FUN name:component2 visibility:public modality:FINAL <> ($this:.Q.Q, T2 of .Q>) returnType:T2 of .Q [operator] + $this: VALUE_PARAMETER name: type:.Q.Q, T2 of .Q> + BLOCK_BODY + RETURN type=kotlin.Nothing from='public final fun component2 (): T2 of .Q [operator] declared in .Q' + CALL 'public final fun (): T2 of .Q declared in .Q' type=T2 of .Q origin=GET_PROPERTY + $this: GET_VAR ': .Q.Q, T2 of .Q> declared in .Q.component2' type=.Q.Q, T2 of .Q> origin=null + FUN FAKE_OVERRIDE name:equals visibility:public modality:OPEN <> ($this:kotlin.Any, other:kotlin.Any?) returnType:kotlin.Boolean [fake_override,operator] + overridden: + public open fun equals (other: kotlin.Any?): kotlin.Boolean [operator] declared in kotlin.Any + $this: VALUE_PARAMETER name: type:kotlin.Any + VALUE_PARAMETER name:other index:0 type:kotlin.Any? + FUN FAKE_OVERRIDE name:hashCode visibility:public modality:OPEN <> ($this:kotlin.Any) returnType:kotlin.Int [fake_override] + overridden: + public open fun hashCode (): kotlin.Int declared in kotlin.Any + $this: VALUE_PARAMETER name: type:kotlin.Any + FUN FAKE_OVERRIDE name:toString visibility:public modality:OPEN <> ($this:kotlin.Any) returnType:kotlin.String [fake_override] + overridden: + public open fun toString (): kotlin.String declared in kotlin.Any + $this: VALUE_PARAMETER name: type:kotlin.Any + FUN name:test1 visibility:public modality:FINAL <> () returnType:kotlin.Unit + BLOCK_BODY + COMPOSITE type=kotlin.Unit origin=DESTRUCTURING_DECLARATION + VAR IR_TEMPORARY_VARIABLE name:tmp_0 type:.P [val] + CALL 'public open fun notNullP (): .P declared in .J' type=.P origin=null + VAR name:x type:kotlin.Int [val] + CALL 'public final fun component1 (): kotlin.Int [operator] declared in .P' type=kotlin.Int origin=COMPONENT_N(index=1) + $this: TYPE_OP type=.P origin=IMPLICIT_NOTNULL typeOperand=.P + GET_VAR 'val tmp_0: .P [val] declared in .test1' type=.P origin=null + VAR name:y type:kotlin.Int [val] + CALL 'public final fun component2 (): kotlin.Int [operator] declared in .P' type=kotlin.Int origin=COMPONENT_N(index=2) + $this: TYPE_OP type=.P origin=IMPLICIT_NOTNULL typeOperand=.P + GET_VAR 'val tmp_0: .P [val] declared in .test1' type=.P origin=null + CALL 'public final fun use (x: kotlin.Any, y: kotlin.Any): kotlin.Unit declared in ' type=kotlin.Unit origin=null + x: GET_VAR 'val x: kotlin.Int [val] declared in .test1' type=kotlin.Int origin=null + y: GET_VAR 'val y: kotlin.Int [val] declared in .test1' type=kotlin.Int origin=null + FUN name:test2 visibility:public modality:FINAL <> () returnType:kotlin.Unit + BLOCK_BODY + COMPOSITE type=kotlin.Unit origin=DESTRUCTURING_DECLARATION + VAR IR_TEMPORARY_VARIABLE name:tmp_1 type:.Q<@[NotNull(value = )] kotlin.String, @[NotNull(value = )] kotlin.String>? [val] + CALL 'public open fun notNullComponents (): .Q<@[NotNull(value = )] kotlin.String, @[NotNull(value = )] kotlin.String>? declared in .J' type=.Q<@[NotNull(value = )] kotlin.String, @[NotNull(value = )] kotlin.String>? origin=null + VAR name:x type:@[NotNull(value = )] kotlin.String [val] + CALL 'public final fun component1 (): T1 of .Q [operator] declared in .Q' type=@[NotNull(value = )] kotlin.String origin=COMPONENT_N(index=1) + $this: TYPE_OP type=.Q<@[NotNull(value = )] kotlin.String, @[NotNull(value = )] kotlin.String> origin=IMPLICIT_NOTNULL typeOperand=.Q<@[NotNull(value = )] kotlin.String, @[NotNull(value = )] kotlin.String> + GET_VAR 'val tmp_1: .Q<@[NotNull(value = )] kotlin.String, @[NotNull(value = )] kotlin.String>? [val] declared in .test2' type=.Q<@[NotNull(value = )] kotlin.String, @[NotNull(value = )] kotlin.String>? origin=null + VAR name:y type:@[NotNull(value = )] kotlin.String [val] + CALL 'public final fun component2 (): T2 of .Q [operator] declared in .Q' type=@[NotNull(value = )] kotlin.String origin=COMPONENT_N(index=2) + $this: TYPE_OP type=.Q<@[NotNull(value = )] kotlin.String, @[NotNull(value = )] kotlin.String> origin=IMPLICIT_NOTNULL typeOperand=.Q<@[NotNull(value = )] kotlin.String, @[NotNull(value = )] kotlin.String> + GET_VAR 'val tmp_1: .Q<@[NotNull(value = )] kotlin.String, @[NotNull(value = )] kotlin.String>? [val] declared in .test2' type=.Q<@[NotNull(value = )] kotlin.String, @[NotNull(value = )] kotlin.String>? origin=null + CALL 'public final fun use (x: kotlin.Any, y: kotlin.Any): kotlin.Unit declared in ' type=kotlin.Unit origin=null + x: TYPE_OP type=@[NotNull(value = )] kotlin.String origin=IMPLICIT_NOTNULL typeOperand=@[NotNull(value = )] kotlin.String + GET_VAR 'val x: @[NotNull(value = )] kotlin.String [val] declared in .test2' type=@[NotNull(value = )] kotlin.String origin=null + y: TYPE_OP type=@[NotNull(value = )] kotlin.String origin=IMPLICIT_NOTNULL typeOperand=@[NotNull(value = )] kotlin.String + GET_VAR 'val y: @[NotNull(value = )] kotlin.String [val] declared in .test2' type=@[NotNull(value = )] kotlin.String origin=null + FUN name:test2Desugared visibility:public modality:FINAL <> () returnType:kotlin.Unit + BLOCK_BODY + VAR name:tmp type:.Q<@[NotNull(value = )] kotlin.String, @[NotNull(value = )] kotlin.String>? [val] + CALL 'public open fun notNullComponents (): .Q<@[NotNull(value = )] kotlin.String, @[NotNull(value = )] kotlin.String>? declared in .J' type=.Q<@[NotNull(value = )] kotlin.String, @[NotNull(value = )] kotlin.String>? origin=null + VAR name:x type:@[NotNull(value = )] kotlin.String [val] + TYPE_OP type=@[NotNull(value = )] kotlin.String origin=IMPLICIT_NOTNULL typeOperand=@[NotNull(value = )] kotlin.String + CALL 'public final fun component1 (): T1 of .Q [operator] declared in .Q' type=@[NotNull(value = )] kotlin.String origin=null + $this: TYPE_OP type=.Q<@[NotNull(value = )] kotlin.String, @[NotNull(value = )] kotlin.String> origin=IMPLICIT_NOTNULL typeOperand=.Q<@[NotNull(value = )] kotlin.String, @[NotNull(value = )] kotlin.String> + GET_VAR 'val tmp: .Q<@[NotNull(value = )] kotlin.String, @[NotNull(value = )] kotlin.String>? [val] declared in .test2Desugared' type=.Q<@[NotNull(value = )] kotlin.String, @[NotNull(value = )] kotlin.String>? origin=null + VAR name:y type:@[NotNull(value = )] kotlin.String [val] + TYPE_OP type=@[NotNull(value = )] kotlin.String origin=IMPLICIT_NOTNULL typeOperand=@[NotNull(value = )] kotlin.String + CALL 'public final fun component2 (): T2 of .Q [operator] declared in .Q' type=@[NotNull(value = )] kotlin.String origin=null + $this: TYPE_OP type=.Q<@[NotNull(value = )] kotlin.String, @[NotNull(value = )] kotlin.String> origin=IMPLICIT_NOTNULL typeOperand=.Q<@[NotNull(value = )] kotlin.String, @[NotNull(value = )] kotlin.String> + GET_VAR 'val tmp: .Q<@[NotNull(value = )] kotlin.String, @[NotNull(value = )] kotlin.String>? [val] declared in .test2Desugared' type=.Q<@[NotNull(value = )] kotlin.String, @[NotNull(value = )] kotlin.String>? origin=null + CALL 'public final fun use (x: kotlin.Any, y: kotlin.Any): kotlin.Unit declared in ' type=kotlin.Unit origin=null + x: GET_VAR 'val x: @[NotNull(value = )] kotlin.String [val] declared in .test2Desugared' type=@[NotNull(value = )] kotlin.String origin=null + y: GET_VAR 'val y: @[NotNull(value = )] kotlin.String [val] declared in .test2Desugared' type=@[NotNull(value = )] kotlin.String origin=null + FUN name:test3 visibility:public modality:FINAL <> () returnType:kotlin.Unit + BLOCK_BODY + COMPOSITE type=kotlin.Unit origin=DESTRUCTURING_DECLARATION + VAR IR_TEMPORARY_VARIABLE name:tmp_2 type:.Q<@[NotNull(value = )] kotlin.String, @[NotNull(value = )] kotlin.String> [val] + CALL 'public open fun notNullQAndComponents (): .Q<@[NotNull(value = )] kotlin.String, @[NotNull(value = )] kotlin.String> declared in .J' type=.Q<@[NotNull(value = )] kotlin.String, @[NotNull(value = )] kotlin.String> origin=null + VAR name:x type:@[NotNull(value = )] kotlin.String [val] + CALL 'public final fun component1 (): T1 of .Q [operator] declared in .Q' type=@[NotNull(value = )] kotlin.String origin=COMPONENT_N(index=1) + $this: TYPE_OP type=.Q<@[NotNull(value = )] kotlin.String, @[NotNull(value = )] kotlin.String> origin=IMPLICIT_NOTNULL typeOperand=.Q<@[NotNull(value = )] kotlin.String, @[NotNull(value = )] kotlin.String> + GET_VAR 'val tmp_2: .Q<@[NotNull(value = )] kotlin.String, @[NotNull(value = )] kotlin.String> [val] declared in .test3' type=.Q<@[NotNull(value = )] kotlin.String, @[NotNull(value = )] kotlin.String> origin=null + VAR name:y type:@[NotNull(value = )] kotlin.String [val] + CALL 'public final fun component2 (): T2 of .Q [operator] declared in .Q' type=@[NotNull(value = )] kotlin.String origin=COMPONENT_N(index=2) + $this: TYPE_OP type=.Q<@[NotNull(value = )] kotlin.String, @[NotNull(value = )] kotlin.String> origin=IMPLICIT_NOTNULL typeOperand=.Q<@[NotNull(value = )] kotlin.String, @[NotNull(value = )] kotlin.String> + GET_VAR 'val tmp_2: .Q<@[NotNull(value = )] kotlin.String, @[NotNull(value = )] kotlin.String> [val] declared in .test3' type=.Q<@[NotNull(value = )] kotlin.String, @[NotNull(value = )] kotlin.String> origin=null + CALL 'public final fun use (x: kotlin.Any, y: kotlin.Any): kotlin.Unit declared in ' type=kotlin.Unit origin=null + x: TYPE_OP type=@[NotNull(value = )] kotlin.String origin=IMPLICIT_NOTNULL typeOperand=@[NotNull(value = )] kotlin.String + GET_VAR 'val x: @[NotNull(value = )] kotlin.String [val] declared in .test3' type=@[NotNull(value = )] kotlin.String origin=null + y: TYPE_OP type=@[NotNull(value = )] kotlin.String origin=IMPLICIT_NOTNULL typeOperand=@[NotNull(value = )] kotlin.String + GET_VAR 'val y: @[NotNull(value = )] kotlin.String [val] declared in .test3' type=@[NotNull(value = )] kotlin.String origin=null + FUN name:test4 visibility:public modality:FINAL <> () returnType:kotlin.Unit + BLOCK_BODY + COMPOSITE type=kotlin.Unit origin=DESTRUCTURING_DECLARATION + VAR IR_TEMPORARY_VARIABLE name:tmp_3 type:kotlin.collections.IndexedValue<@[NotNull(value = )] .P> [val] + CALL 'public final fun first (): T of kotlin.collections.first declared in kotlin.collections' type=kotlin.collections.IndexedValue<@[NotNull(value = )] .P> origin=null + : kotlin.collections.IndexedValue<@[NotNull(value = )] .P> + $receiver: CALL 'public final fun withIndex (): kotlin.collections.Iterable> declared in kotlin.collections' type=kotlin.collections.Iterable)] .P>> origin=null + : @[NotNull(value = )] .P + $receiver: TYPE_OP type=kotlin.collections.List<@[NotNull(value = )] .P> origin=IMPLICIT_NOTNULL typeOperand=kotlin.collections.List<@[NotNull(value = )] .P> + CALL 'public open fun listOfNotNull (): kotlin.collections.List<@[NotNull(value = )] .P>? declared in .J' type=kotlin.collections.List<@[NotNull(value = )] .P>? origin=null + VAR name:x type:kotlin.Int [val] + CALL 'public final fun component1 (): kotlin.Int [operator] declared in kotlin.collections.IndexedValue' type=kotlin.Int origin=COMPONENT_N(index=1) + $this: GET_VAR 'val tmp_3: kotlin.collections.IndexedValue<@[NotNull(value = )] .P> [val] declared in .test4' type=kotlin.collections.IndexedValue<@[NotNull(value = )] .P> origin=null + VAR name:y type:@[NotNull(value = )] .P [val] + CALL 'public final fun component2 (): T of kotlin.collections.IndexedValue [operator] declared in kotlin.collections.IndexedValue' type=@[NotNull(value = )] .P origin=COMPONENT_N(index=2) + $this: GET_VAR 'val tmp_3: kotlin.collections.IndexedValue<@[NotNull(value = )] .P> [val] declared in .test4' type=kotlin.collections.IndexedValue<@[NotNull(value = )] .P> origin=null + CALL 'public final fun use (x: kotlin.Any, y: kotlin.Any): kotlin.Unit declared in ' type=kotlin.Unit origin=null + x: GET_VAR 'val x: kotlin.Int [val] declared in .test4' type=kotlin.Int origin=null + y: TYPE_OP type=@[NotNull(value = )] .P origin=IMPLICIT_NOTNULL typeOperand=@[NotNull(value = )] .P + GET_VAR 'val y: @[NotNull(value = )] .P [val] declared in .test4' type=@[NotNull(value = )] .P origin=null diff --git a/compiler/testData/ir/irText/types/nullChecks/enhancedNullabilityInForLoop.fir.txt b/compiler/testData/ir/irText/types/nullChecks/enhancedNullabilityInForLoop.fir.txt new file mode 100644 index 00000000000..97c0c11052e --- /dev/null +++ b/compiler/testData/ir/irText/types/nullChecks/enhancedNullabilityInForLoop.fir.txt @@ -0,0 +1,187 @@ +FILE fqName: fileName:/enhancedNullabilityInForLoop.kt + FUN name:use visibility:public modality:FINAL <> (s:.P) returnType:kotlin.Unit + VALUE_PARAMETER name:s index:0 type:.P + BLOCK_BODY + FUN name:testForInListUnused visibility:public modality:FINAL <> () returnType:kotlin.Unit + BLOCK_BODY + VAR IR_TEMPORARY_VARIABLE name:tmp_0 type:kotlin.collections.List<.P>? [val] + CALL 'public open fun listOfNotNull (): kotlin.collections.List<.P>? [operator] declared in .J' type=kotlin.collections.List<.P>? origin=null + VAR IR_TEMPORARY_VARIABLE name:tmp_1 type:kotlin.collections.MutableIterator<.P> [val] + CALL 'public abstract fun iterator (): kotlin.collections.MutableIterator<.P> [operator] declared in kotlin.collections.MutableCollection' type=kotlin.collections.MutableIterator<.P> origin=null + $this: GET_VAR 'val tmp_0: kotlin.collections.List<.P>? [val] declared in .testForInListUnused' type=kotlin.collections.List<.P>? origin=null + WHILE label=null origin=FOR_LOOP_INNER_WHILE + condition: CALL 'public abstract fun hasNext (): kotlin.Boolean [operator] declared in kotlin.collections.Iterator' type=kotlin.Boolean origin=null + $this: GET_VAR 'val tmp_1: kotlin.collections.MutableIterator<.P> [val] declared in .testForInListUnused' type=kotlin.collections.MutableIterator<.P> origin=null + body: BLOCK type=kotlin.Unit origin=null + VAR name:x type:.P [val] + CALL 'public abstract fun next (): .P [operator] declared in kotlin.collections.Iterator' type=.P origin=null + $this: GET_VAR 'val tmp_1: kotlin.collections.MutableIterator<.P> [val] declared in .testForInListUnused' type=kotlin.collections.MutableIterator<.P> origin=null + FUN name:testForInListDestructured visibility:public modality:FINAL <> () returnType:kotlin.Unit + BLOCK_BODY + VAR IR_TEMPORARY_VARIABLE name:tmp_2 type:kotlin.collections.List<.P>? [val] + CALL 'public open fun listOfNotNull (): kotlin.collections.List<.P>? [operator] declared in .J' type=kotlin.collections.List<.P>? origin=null + VAR IR_TEMPORARY_VARIABLE name:tmp_3 type:kotlin.collections.MutableIterator<.P> [val] + CALL 'public abstract fun iterator (): kotlin.collections.MutableIterator<.P> [operator] declared in kotlin.collections.MutableCollection' type=kotlin.collections.MutableIterator<.P> origin=null + $this: GET_VAR 'val tmp_2: kotlin.collections.List<.P>? [val] declared in .testForInListDestructured' type=kotlin.collections.List<.P>? origin=null + WHILE label=null origin=FOR_LOOP_INNER_WHILE + condition: CALL 'public abstract fun hasNext (): kotlin.Boolean [operator] declared in kotlin.collections.Iterator' type=kotlin.Boolean origin=null + $this: GET_VAR 'val tmp_3: kotlin.collections.MutableIterator<.P> [val] declared in .testForInListDestructured' type=kotlin.collections.MutableIterator<.P> origin=null + body: BLOCK type=kotlin.Unit origin=null + VAR IR_TEMPORARY_VARIABLE name:tmp_4 type:.P [val] + CALL 'public abstract fun next (): .P [operator] declared in kotlin.collections.Iterator' type=.P origin=null + $this: GET_VAR 'val tmp_3: kotlin.collections.MutableIterator<.P> [val] declared in .testForInListDestructured' type=kotlin.collections.MutableIterator<.P> origin=null + VAR name:x type:kotlin.Int [val] + CALL 'public final fun component1 (): kotlin.Int declared in .P' type=kotlin.Int origin=null + $this: GET_VAR 'val tmp_4: .P [val] declared in .testForInListDestructured' type=.P origin=null + VAR name:y type:kotlin.Int [val] + CALL 'public final fun component2 (): kotlin.Int declared in .P' type=kotlin.Int origin=null + $this: GET_VAR 'val tmp_4: .P [val] declared in .testForInListDestructured' type=.P origin=null + FUN name:testDesugaredForInList visibility:public modality:FINAL <> () returnType:kotlin.Unit + BLOCK_BODY + VAR name:iterator type:kotlin.collections.MutableIterator<.P> [val] + CALL 'public abstract fun iterator (): kotlin.collections.MutableIterator<.P> [operator] declared in kotlin.collections.MutableCollection' type=kotlin.collections.MutableIterator<.P> origin=null + $this: CALL 'public open fun listOfNotNull (): kotlin.collections.List<.P>? [operator] declared in .J' type=kotlin.collections.List<.P>? origin=null + WHILE label=null origin=WHILE_LOOP + condition: CALL 'public abstract fun hasNext (): kotlin.Boolean [operator] declared in kotlin.collections.Iterator' type=kotlin.Boolean origin=null + $this: GET_VAR 'val iterator: kotlin.collections.MutableIterator<.P> [val] declared in .testDesugaredForInList' type=kotlin.collections.MutableIterator<.P> origin=null + body: BLOCK type=kotlin.Unit origin=null + VAR name:x type:.P [val] + CALL 'public abstract fun next (): .P [operator] declared in kotlin.collections.Iterator' type=.P origin=null + $this: GET_VAR 'val iterator: kotlin.collections.MutableIterator<.P> [val] declared in .testDesugaredForInList' type=kotlin.collections.MutableIterator<.P> origin=null + FUN name:testForInArrayUnused visibility:public modality:FINAL <> (j:.J) returnType:kotlin.Unit + VALUE_PARAMETER name:j index:0 type:.J + BLOCK_BODY + VAR IR_TEMPORARY_VARIABLE name:tmp_5 type:kotlin.Array.P?>? [val] + CALL 'public open fun arrayOfNotNull (): kotlin.Array.P?>? [operator] declared in .J' type=kotlin.Array.P?>? origin=null + $this: GET_VAR 'j: .J declared in .testForInArrayUnused' type=.J origin=null + VAR IR_TEMPORARY_VARIABLE name:tmp_6 type:kotlin.collections.Iterator<.P?> [val] + CALL 'public final fun iterator (): kotlin.collections.Iterator<.P?> [operator] declared in kotlin.Array' type=kotlin.collections.Iterator<.P?> origin=null + $this: GET_VAR 'val tmp_5: kotlin.Array.P?>? [val] declared in .testForInArrayUnused' type=kotlin.Array.P?>? origin=null + WHILE label=null origin=FOR_LOOP_INNER_WHILE + condition: CALL 'public abstract fun hasNext (): kotlin.Boolean [operator] declared in kotlin.collections.Iterator' type=kotlin.Boolean origin=null + $this: GET_VAR 'val tmp_6: kotlin.collections.Iterator<.P?> [val] declared in .testForInArrayUnused' type=kotlin.collections.Iterator<.P?> origin=null + body: BLOCK type=kotlin.Unit origin=null + VAR name:x type:.P? [val] + CALL 'public abstract fun next (): .P? [operator] declared in kotlin.collections.Iterator' type=.P? origin=null + $this: GET_VAR 'val tmp_6: kotlin.collections.Iterator<.P?> [val] declared in .testForInArrayUnused' type=kotlin.collections.Iterator<.P?> origin=null + FUN name:testForInListUse visibility:public modality:FINAL <> () returnType:kotlin.Unit + BLOCK_BODY + VAR IR_TEMPORARY_VARIABLE name:tmp_7 type:kotlin.collections.List<.P>? [val] + CALL 'public open fun listOfNotNull (): kotlin.collections.List<.P>? [operator] declared in .J' type=kotlin.collections.List<.P>? origin=null + VAR IR_TEMPORARY_VARIABLE name:tmp_8 type:kotlin.collections.MutableIterator<.P> [val] + CALL 'public abstract fun iterator (): kotlin.collections.MutableIterator<.P> [operator] declared in kotlin.collections.MutableCollection' type=kotlin.collections.MutableIterator<.P> origin=null + $this: GET_VAR 'val tmp_7: kotlin.collections.List<.P>? [val] declared in .testForInListUse' type=kotlin.collections.List<.P>? origin=null + WHILE label=null origin=FOR_LOOP_INNER_WHILE + condition: CALL 'public abstract fun hasNext (): kotlin.Boolean [operator] declared in kotlin.collections.Iterator' type=kotlin.Boolean origin=null + $this: GET_VAR 'val tmp_8: kotlin.collections.MutableIterator<.P> [val] declared in .testForInListUse' type=kotlin.collections.MutableIterator<.P> origin=null + body: BLOCK type=kotlin.Unit origin=null + VAR name:x type:.P [val] + CALL 'public abstract fun next (): .P [operator] declared in kotlin.collections.Iterator' type=.P origin=null + $this: GET_VAR 'val tmp_8: kotlin.collections.MutableIterator<.P> [val] declared in .testForInListUse' type=kotlin.collections.MutableIterator<.P> origin=null + CALL 'public final fun use (s: .P): kotlin.Unit declared in ' type=kotlin.Unit origin=null + s: GET_VAR 'val x: .P [val] declared in .testForInListUse' type=.P origin=null + CALL 'public open fun use (s: .P): kotlin.Unit [operator] declared in .J' type=kotlin.Unit origin=null + s: GET_VAR 'val x: .P [val] declared in .testForInListUse' type=.P origin=null + FUN name:testForInArrayUse visibility:public modality:FINAL <> (j:.J) returnType:kotlin.Unit + VALUE_PARAMETER name:j index:0 type:.J + BLOCK_BODY + VAR IR_TEMPORARY_VARIABLE name:tmp_9 type:kotlin.Array.P?>? [val] + CALL 'public open fun arrayOfNotNull (): kotlin.Array.P?>? [operator] declared in .J' type=kotlin.Array.P?>? origin=null + $this: GET_VAR 'j: .J declared in .testForInArrayUse' type=.J origin=null + VAR IR_TEMPORARY_VARIABLE name:tmp_10 type:kotlin.collections.Iterator<.P?> [val] + CALL 'public final fun iterator (): kotlin.collections.Iterator<.P?> [operator] declared in kotlin.Array' type=kotlin.collections.Iterator<.P?> origin=null + $this: GET_VAR 'val tmp_9: kotlin.Array.P?>? [val] declared in .testForInArrayUse' type=kotlin.Array.P?>? origin=null + WHILE label=null origin=FOR_LOOP_INNER_WHILE + condition: CALL 'public abstract fun hasNext (): kotlin.Boolean [operator] declared in kotlin.collections.Iterator' type=kotlin.Boolean origin=null + $this: GET_VAR 'val tmp_10: kotlin.collections.Iterator<.P?> [val] declared in .testForInArrayUse' type=kotlin.collections.Iterator<.P?> origin=null + body: BLOCK type=kotlin.Unit origin=null + VAR name:x type:.P? [val] + CALL 'public abstract fun next (): .P? [operator] declared in kotlin.collections.Iterator' type=.P? origin=null + $this: GET_VAR 'val tmp_10: kotlin.collections.Iterator<.P?> [val] declared in .testForInArrayUse' type=kotlin.collections.Iterator<.P?> origin=null + CALL 'public final fun use (s: .P): kotlin.Unit declared in ' type=kotlin.Unit origin=null + s: GET_VAR 'val x: .P? [val] declared in .testForInArrayUse' type=.P? origin=null + CALL 'public open fun use (s: .P): kotlin.Unit [operator] declared in .J' type=kotlin.Unit origin=null + s: GET_VAR 'val x: .P? [val] declared in .testForInArrayUse' type=.P? origin=null + CLASS INTERFACE name:K modality:ABSTRACT visibility:public superTypes:[kotlin.Any] + $this: VALUE_PARAMETER INSTANCE_RECEIVER name: type:.K + FUN name:arrayOfNotNull visibility:public modality:ABSTRACT <> ($this:.K) returnType:kotlin.Array<.P> + $this: VALUE_PARAMETER name: type:.K + FUN FAKE_OVERRIDE name:equals visibility:public modality:OPEN <> ($this:kotlin.Any, other:kotlin.Any?) returnType:kotlin.Boolean [fake_override,operator] + overridden: + public open fun equals (other: kotlin.Any?): kotlin.Boolean [operator] declared in kotlin.Any + $this: VALUE_PARAMETER name: type:kotlin.Any + VALUE_PARAMETER name:other index:0 type:kotlin.Any? + FUN FAKE_OVERRIDE name:hashCode visibility:public modality:OPEN <> ($this:kotlin.Any) returnType:kotlin.Int [fake_override] + overridden: + public open fun hashCode (): kotlin.Int declared in kotlin.Any + $this: VALUE_PARAMETER name: type:kotlin.Any + FUN FAKE_OVERRIDE name:toString visibility:public modality:OPEN <> ($this:kotlin.Any) returnType:kotlin.String [fake_override] + overridden: + public open fun toString (): kotlin.String declared in kotlin.Any + $this: VALUE_PARAMETER name: type:kotlin.Any + CLASS CLASS name:P modality:FINAL visibility:public [data] superTypes:[kotlin.Any] + $this: VALUE_PARAMETER INSTANCE_RECEIVER name: type:.P + CONSTRUCTOR visibility:public <> (x:kotlin.Int, y:kotlin.Int) returnType:.P [primary] + VALUE_PARAMETER name:x index:0 type:kotlin.Int + VALUE_PARAMETER name:y index:1 type:kotlin.Int + BLOCK_BODY + DELEGATING_CONSTRUCTOR_CALL 'public constructor () [primary] declared in kotlin.Any' + INSTANCE_INITIALIZER_CALL classDescriptor='CLASS CLASS name:P modality:FINAL visibility:public [data] superTypes:[kotlin.Any]' + PROPERTY name:x visibility:public modality:FINAL [val] + FIELD PROPERTY_BACKING_FIELD name:x type:kotlin.Int visibility:private [final] + EXPRESSION_BODY + GET_VAR 'x: kotlin.Int declared in .P.' type=kotlin.Int origin=INITIALIZE_PROPERTY_FROM_PARAMETER + FUN DEFAULT_PROPERTY_ACCESSOR name: visibility:public modality:FINAL <> ($this:.P) returnType:kotlin.Int + correspondingProperty: PROPERTY name:x visibility:public modality:FINAL [val] + $this: VALUE_PARAMETER name: type:.P + BLOCK_BODY + RETURN type=kotlin.Nothing from='public final fun (): kotlin.Int declared in .P' + GET_FIELD 'FIELD PROPERTY_BACKING_FIELD name:x type:kotlin.Int visibility:private [final]' type=kotlin.Int origin=null + receiver: GET_VAR ': .P declared in .P.' type=.P origin=null + PROPERTY name:y visibility:public modality:FINAL [val] + FIELD PROPERTY_BACKING_FIELD name:y type:kotlin.Int visibility:private [final] + EXPRESSION_BODY + GET_VAR 'y: kotlin.Int declared in .P.' type=kotlin.Int origin=INITIALIZE_PROPERTY_FROM_PARAMETER + FUN DEFAULT_PROPERTY_ACCESSOR name: visibility:public modality:FINAL <> ($this:.P) returnType:kotlin.Int + correspondingProperty: PROPERTY name:y visibility:public modality:FINAL [val] + $this: VALUE_PARAMETER name: type:.P + BLOCK_BODY + RETURN type=kotlin.Nothing from='public final fun (): kotlin.Int declared in .P' + GET_FIELD 'FIELD PROPERTY_BACKING_FIELD name:y type:kotlin.Int visibility:private [final]' type=kotlin.Int origin=null + receiver: GET_VAR ': .P declared in .P.' type=.P origin=null + FUN name:component1 visibility:public modality:FINAL <> ($this:.P) returnType:kotlin.Int + $this: VALUE_PARAMETER name: type:.P + BLOCK_BODY + RETURN type=kotlin.Nothing from='public final fun component1 (): kotlin.Int declared in .P' + CALL 'public final fun (): kotlin.Int declared in .P' type=kotlin.Int origin=null + $this: GET_VAR ': .P declared in .P.component1' type=.P origin=null + FUN name:component2 visibility:public modality:FINAL <> ($this:.P) returnType:kotlin.Int + $this: VALUE_PARAMETER name: type:.P + BLOCK_BODY + RETURN type=kotlin.Nothing from='public final fun component2 (): kotlin.Int declared in .P' + CALL 'public final fun (): kotlin.Int declared in .P' type=kotlin.Int origin=null + $this: GET_VAR ': .P declared in .P.component2' type=.P origin=null + FUN name:copy visibility:public modality:FINAL <> ($this:.P, x:kotlin.Int, y:kotlin.Int) returnType:.P + $this: VALUE_PARAMETER name: type:.P + VALUE_PARAMETER name:x index:0 type:kotlin.Int + EXPRESSION_BODY + CALL 'public final fun (): kotlin.Int declared in .P' type=kotlin.Int origin=null + $this: GET_VAR ': .P declared in .P.copy' type=.P origin=null + VALUE_PARAMETER name:y index:1 type:kotlin.Int + EXPRESSION_BODY + CALL 'public final fun (): kotlin.Int declared in .P' type=kotlin.Int origin=null + $this: GET_VAR ': .P declared in .P.copy' type=.P origin=null + BLOCK_BODY + FUN FAKE_OVERRIDE name:equals visibility:public modality:OPEN <> ($this:kotlin.Any, other:kotlin.Any?) returnType:kotlin.Boolean [fake_override,operator] + overridden: + public open fun equals (other: kotlin.Any?): kotlin.Boolean [operator] declared in kotlin.Any + $this: VALUE_PARAMETER name: type:kotlin.Any + VALUE_PARAMETER name:other index:0 type:kotlin.Any? + FUN FAKE_OVERRIDE name:hashCode visibility:public modality:OPEN <> ($this:kotlin.Any) returnType:kotlin.Int [fake_override] + overridden: + public open fun hashCode (): kotlin.Int declared in kotlin.Any + $this: VALUE_PARAMETER name: type:kotlin.Any + FUN FAKE_OVERRIDE name:toString visibility:public modality:OPEN <> ($this:kotlin.Any) returnType:kotlin.String [fake_override] + overridden: + public open fun toString (): kotlin.String declared in kotlin.Any + $this: VALUE_PARAMETER name: type:kotlin.Any diff --git a/compiler/testData/ir/irText/types/nullChecks/enhancedNullabilityInForLoop.kt b/compiler/testData/ir/irText/types/nullChecks/enhancedNullabilityInForLoop.kt new file mode 100644 index 00000000000..1ddc0ee90c0 --- /dev/null +++ b/compiler/testData/ir/irText/types/nullChecks/enhancedNullabilityInForLoop.kt @@ -0,0 +1,63 @@ +// FILE: enhancedNullabilityInForLoop.kt +// WITH_JDK + +fun use(s: P) {} + +fun testForInListUnused() { + // See KT-36343 + for (x in J.listOfNotNull()) {} +} + +fun testForInListDestructured() { + // See KT-36343 and KT-36344 + for ((x, y) in J.listOfNotNull()) {} +} + +fun testDesugaredForInList() { + val iterator = J.listOfNotNull().iterator() + while (iterator.hasNext()) { + val x = iterator.next() + } +} + +fun testForInArrayUnused(j: J) { + // See KT-36343 + for (x in j.arrayOfNotNull()) {} +} + +fun testForInListUse() { + // See KT-36343 + for (x in J.listOfNotNull()) { + use(x) + J.use(x) + } +} + +fun testForInArrayUse(j: J) { + // See KT-36343 + for (x in j.arrayOfNotNull()) { + use(x) + J.use(x) + } +} + +interface K { + fun arrayOfNotNull(): Array

+} + +data class P(val x: Int, val y: Int) + +// FILE: J.java +import java.util.*; +import org.jetbrains.annotations.*; + +public class J implements K { + public static void use(@NotNull P s) {} + + public static @NotNull P notNull() { return null; } + + public static List<@NotNull P> listOfNotNull() { return null; } + + @Override + public P[] arrayOfNotNull() { return null; } +} diff --git a/compiler/testData/ir/irText/types/nullChecks/enhancedNullabilityInForLoop.txt b/compiler/testData/ir/irText/types/nullChecks/enhancedNullabilityInForLoop.txt new file mode 100644 index 00000000000..7cd206d3ed7 --- /dev/null +++ b/compiler/testData/ir/irText/types/nullChecks/enhancedNullabilityInForLoop.txt @@ -0,0 +1,270 @@ +FILE fqName: fileName:/enhancedNullabilityInForLoop.kt + FUN name:use visibility:public modality:FINAL <> (s:.P) returnType:kotlin.Unit + VALUE_PARAMETER name:s index:0 type:.P + BLOCK_BODY + FUN name:testForInListUnused visibility:public modality:FINAL <> () returnType:kotlin.Unit + BLOCK_BODY + BLOCK type=kotlin.Unit origin=FOR_LOOP + VAR FOR_LOOP_ITERATOR name:tmp_0 type:kotlin.collections.MutableIterator<@[NotNull(value = )] .P> [val] + CALL 'public abstract fun iterator (): kotlin.collections.MutableIterator [fake_override,operator] declared in kotlin.collections.MutableList' type=kotlin.collections.MutableIterator<@[NotNull(value = )] .P> origin=FOR_LOOP_ITERATOR + $this: TYPE_OP type=kotlin.collections.MutableList<*> origin=IMPLICIT_CAST typeOperand=kotlin.collections.MutableList<*> + TYPE_OP type=kotlin.collections.List<@[NotNull(value = )] .P> origin=IMPLICIT_NOTNULL typeOperand=kotlin.collections.List<@[NotNull(value = )] .P> + CALL 'public open fun listOfNotNull (): kotlin.collections.List<@[NotNull(value = )] .P>? declared in .J' type=kotlin.collections.List<@[NotNull(value = )] .P>? origin=null + WHILE label=null origin=FOR_LOOP_INNER_WHILE + condition: CALL 'public abstract fun hasNext (): kotlin.Boolean [fake_override,operator] declared in kotlin.collections.MutableIterator' type=kotlin.Boolean origin=FOR_LOOP_HAS_NEXT + $this: GET_VAR 'val tmp_0: kotlin.collections.MutableIterator<@[NotNull(value = )] .P> [val] declared in .testForInListUnused' type=kotlin.collections.MutableIterator<@[NotNull(value = )] .P> origin=null + body: BLOCK type=kotlin.Unit origin=FOR_LOOP_INNER_WHILE + VAR FOR_LOOP_VARIABLE name:x type:@[NotNull(value = )] .P [val] + CALL 'public abstract fun next (): T of kotlin.collections.MutableIterator [fake_override,operator] declared in kotlin.collections.MutableIterator' type=@[NotNull(value = )] .P origin=FOR_LOOP_NEXT + $this: GET_VAR 'val tmp_0: kotlin.collections.MutableIterator<@[NotNull(value = )] .P> [val] declared in .testForInListUnused' type=kotlin.collections.MutableIterator<@[NotNull(value = )] .P> origin=null + BLOCK type=kotlin.Unit origin=null + FUN name:testForInListDestructured visibility:public modality:FINAL <> () returnType:kotlin.Unit + BLOCK_BODY + BLOCK type=kotlin.Unit origin=FOR_LOOP + VAR FOR_LOOP_ITERATOR name:tmp_1 type:kotlin.collections.MutableIterator<@[NotNull(value = )] .P> [val] + CALL 'public abstract fun iterator (): kotlin.collections.MutableIterator [fake_override,operator] declared in kotlin.collections.MutableList' type=kotlin.collections.MutableIterator<@[NotNull(value = )] .P> origin=FOR_LOOP_ITERATOR + $this: TYPE_OP type=kotlin.collections.MutableList<*> origin=IMPLICIT_CAST typeOperand=kotlin.collections.MutableList<*> + TYPE_OP type=kotlin.collections.List<@[NotNull(value = )] .P> origin=IMPLICIT_NOTNULL typeOperand=kotlin.collections.List<@[NotNull(value = )] .P> + CALL 'public open fun listOfNotNull (): kotlin.collections.List<@[NotNull(value = )] .P>? declared in .J' type=kotlin.collections.List<@[NotNull(value = )] .P>? origin=null + WHILE label=null origin=FOR_LOOP_INNER_WHILE + condition: CALL 'public abstract fun hasNext (): kotlin.Boolean [fake_override,operator] declared in kotlin.collections.MutableIterator' type=kotlin.Boolean origin=FOR_LOOP_HAS_NEXT + $this: GET_VAR 'val tmp_1: kotlin.collections.MutableIterator<@[NotNull(value = )] .P> [val] declared in .testForInListDestructured' type=kotlin.collections.MutableIterator<@[NotNull(value = )] .P> origin=null + body: BLOCK type=kotlin.Unit origin=FOR_LOOP_INNER_WHILE + VAR IR_TEMPORARY_VARIABLE name:tmp_2 type:@[NotNull(value = )] .P [val] + CALL 'public abstract fun next (): T of kotlin.collections.MutableIterator [fake_override,operator] declared in kotlin.collections.MutableIterator' type=@[NotNull(value = )] .P origin=FOR_LOOP_NEXT + $this: GET_VAR 'val tmp_1: kotlin.collections.MutableIterator<@[NotNull(value = )] .P> [val] declared in .testForInListDestructured' type=kotlin.collections.MutableIterator<@[NotNull(value = )] .P> origin=null + VAR name:x type:kotlin.Int [val] + CALL 'public final fun component1 (): kotlin.Int [operator] declared in .P' type=kotlin.Int origin=COMPONENT_N(index=1) + $this: TYPE_OP type=@[NotNull(value = )] .P origin=IMPLICIT_NOTNULL typeOperand=@[NotNull(value = )] .P + GET_VAR 'val tmp_2: @[NotNull(value = )] .P [val] declared in .testForInListDestructured' type=@[NotNull(value = )] .P origin=null + VAR name:y type:kotlin.Int [val] + CALL 'public final fun component2 (): kotlin.Int [operator] declared in .P' type=kotlin.Int origin=COMPONENT_N(index=2) + $this: TYPE_OP type=@[NotNull(value = )] .P origin=IMPLICIT_NOTNULL typeOperand=@[NotNull(value = )] .P + GET_VAR 'val tmp_2: @[NotNull(value = )] .P [val] declared in .testForInListDestructured' type=@[NotNull(value = )] .P origin=null + BLOCK type=kotlin.Unit origin=null + FUN name:testDesugaredForInList visibility:public modality:FINAL <> () returnType:kotlin.Unit + BLOCK_BODY + VAR name:iterator type:kotlin.collections.MutableIterator<@[NotNull(value = )] .P> [val] + CALL 'public abstract fun iterator (): kotlin.collections.MutableIterator [fake_override,operator] declared in kotlin.collections.MutableList' type=kotlin.collections.MutableIterator<@[NotNull(value = )] .P> origin=null + $this: TYPE_OP type=kotlin.collections.MutableList<*> origin=IMPLICIT_CAST typeOperand=kotlin.collections.MutableList<*> + TYPE_OP type=kotlin.collections.List<@[NotNull(value = )] .P> origin=IMPLICIT_NOTNULL typeOperand=kotlin.collections.List<@[NotNull(value = )] .P> + CALL 'public open fun listOfNotNull (): kotlin.collections.List<@[NotNull(value = )] .P>? declared in .J' type=kotlin.collections.List<@[NotNull(value = )] .P>? origin=null + WHILE label=null origin=WHILE_LOOP + condition: CALL 'public abstract fun hasNext (): kotlin.Boolean [fake_override,operator] declared in kotlin.collections.MutableIterator' type=kotlin.Boolean origin=null + $this: GET_VAR 'val iterator: kotlin.collections.MutableIterator<@[NotNull(value = )] .P> [val] declared in .testDesugaredForInList' type=kotlin.collections.MutableIterator<@[NotNull(value = )] .P> origin=null + body: BLOCK type=kotlin.Unit origin=null + VAR name:x type:@[NotNull(value = )] .P [val] + TYPE_OP type=@[NotNull(value = )] .P origin=IMPLICIT_NOTNULL typeOperand=@[NotNull(value = )] .P + CALL 'public abstract fun next (): T of kotlin.collections.MutableIterator [fake_override,operator] declared in kotlin.collections.MutableIterator' type=@[NotNull(value = )] .P origin=null + $this: GET_VAR 'val iterator: kotlin.collections.MutableIterator<@[NotNull(value = )] .P> [val] declared in .testDesugaredForInList' type=kotlin.collections.MutableIterator<@[NotNull(value = )] .P> origin=null + FUN name:testForInArrayUnused visibility:public modality:FINAL <> (j:.J) returnType:kotlin.Unit + VALUE_PARAMETER name:j index:0 type:.J + BLOCK_BODY + BLOCK type=kotlin.Unit origin=FOR_LOOP + VAR FOR_LOOP_ITERATOR name:tmp_3 type:kotlin.collections.Iterator<.P> [val] + CALL 'public final fun iterator (): kotlin.collections.Iterator [operator] declared in kotlin.Array' type=kotlin.collections.Iterator<.P> origin=FOR_LOOP_ITERATOR + $this: TYPE_OP type=kotlin.Array<.P> origin=IMPLICIT_CAST typeOperand=kotlin.Array<.P> + TYPE_OP type=kotlin.Array.P> origin=IMPLICIT_NOTNULL typeOperand=kotlin.Array.P> + CALL 'public open fun arrayOfNotNull (): kotlin.Array.P> declared in .J' type=kotlin.Array.P> origin=null + $this: GET_VAR 'j: .J declared in .testForInArrayUnused' type=.J origin=null + WHILE label=null origin=FOR_LOOP_INNER_WHILE + condition: CALL 'public abstract fun hasNext (): kotlin.Boolean [operator] declared in kotlin.collections.Iterator' type=kotlin.Boolean origin=FOR_LOOP_HAS_NEXT + $this: GET_VAR 'val tmp_3: kotlin.collections.Iterator<.P> [val] declared in .testForInArrayUnused' type=kotlin.collections.Iterator<.P> origin=null + body: BLOCK type=kotlin.Unit origin=FOR_LOOP_INNER_WHILE + VAR FOR_LOOP_VARIABLE name:x type:.P [val] + CALL 'public abstract fun next (): T of kotlin.collections.Iterator [operator] declared in kotlin.collections.Iterator' type=.P origin=FOR_LOOP_NEXT + $this: GET_VAR 'val tmp_3: kotlin.collections.Iterator<.P> [val] declared in .testForInArrayUnused' type=kotlin.collections.Iterator<.P> origin=null + BLOCK type=kotlin.Unit origin=null + FUN name:testForInListUse visibility:public modality:FINAL <> () returnType:kotlin.Unit + BLOCK_BODY + BLOCK type=kotlin.Unit origin=FOR_LOOP + VAR FOR_LOOP_ITERATOR name:tmp_4 type:kotlin.collections.MutableIterator<@[NotNull(value = )] .P> [val] + CALL 'public abstract fun iterator (): kotlin.collections.MutableIterator [fake_override,operator] declared in kotlin.collections.MutableList' type=kotlin.collections.MutableIterator<@[NotNull(value = )] .P> origin=FOR_LOOP_ITERATOR + $this: TYPE_OP type=kotlin.collections.MutableList<*> origin=IMPLICIT_CAST typeOperand=kotlin.collections.MutableList<*> + TYPE_OP type=kotlin.collections.List<@[NotNull(value = )] .P> origin=IMPLICIT_NOTNULL typeOperand=kotlin.collections.List<@[NotNull(value = )] .P> + CALL 'public open fun listOfNotNull (): kotlin.collections.List<@[NotNull(value = )] .P>? declared in .J' type=kotlin.collections.List<@[NotNull(value = )] .P>? origin=null + WHILE label=null origin=FOR_LOOP_INNER_WHILE + condition: CALL 'public abstract fun hasNext (): kotlin.Boolean [fake_override,operator] declared in kotlin.collections.MutableIterator' type=kotlin.Boolean origin=FOR_LOOP_HAS_NEXT + $this: GET_VAR 'val tmp_4: kotlin.collections.MutableIterator<@[NotNull(value = )] .P> [val] declared in .testForInListUse' type=kotlin.collections.MutableIterator<@[NotNull(value = )] .P> origin=null + body: BLOCK type=kotlin.Unit origin=FOR_LOOP_INNER_WHILE + VAR FOR_LOOP_VARIABLE name:x type:@[NotNull(value = )] .P [val] + CALL 'public abstract fun next (): T of kotlin.collections.MutableIterator [fake_override,operator] declared in kotlin.collections.MutableIterator' type=@[NotNull(value = )] .P origin=FOR_LOOP_NEXT + $this: GET_VAR 'val tmp_4: kotlin.collections.MutableIterator<@[NotNull(value = )] .P> [val] declared in .testForInListUse' type=kotlin.collections.MutableIterator<@[NotNull(value = )] .P> origin=null + BLOCK type=kotlin.Unit origin=null + CALL 'public final fun use (s: .P): kotlin.Unit declared in ' type=kotlin.Unit origin=null + s: TYPE_OP type=@[NotNull(value = )] .P origin=IMPLICIT_NOTNULL typeOperand=@[NotNull(value = )] .P + GET_VAR 'val x: @[NotNull(value = )] .P [val] declared in .testForInListUse' type=@[NotNull(value = )] .P origin=null + CALL 'public open fun use (s: .P): kotlin.Unit declared in .J' type=kotlin.Unit origin=null + s: GET_VAR 'val x: @[NotNull(value = )] .P [val] declared in .testForInListUse' type=@[NotNull(value = )] .P origin=null + FUN name:testForInArrayUse visibility:public modality:FINAL <> (j:.J) returnType:kotlin.Unit + VALUE_PARAMETER name:j index:0 type:.J + BLOCK_BODY + BLOCK type=kotlin.Unit origin=FOR_LOOP + VAR FOR_LOOP_ITERATOR name:tmp_5 type:kotlin.collections.Iterator<.P> [val] + CALL 'public final fun iterator (): kotlin.collections.Iterator [operator] declared in kotlin.Array' type=kotlin.collections.Iterator<.P> origin=FOR_LOOP_ITERATOR + $this: TYPE_OP type=kotlin.Array<.P> origin=IMPLICIT_CAST typeOperand=kotlin.Array<.P> + TYPE_OP type=kotlin.Array.P> origin=IMPLICIT_NOTNULL typeOperand=kotlin.Array.P> + CALL 'public open fun arrayOfNotNull (): kotlin.Array.P> declared in .J' type=kotlin.Array.P> origin=null + $this: GET_VAR 'j: .J declared in .testForInArrayUse' type=.J origin=null + WHILE label=null origin=FOR_LOOP_INNER_WHILE + condition: CALL 'public abstract fun hasNext (): kotlin.Boolean [operator] declared in kotlin.collections.Iterator' type=kotlin.Boolean origin=FOR_LOOP_HAS_NEXT + $this: GET_VAR 'val tmp_5: kotlin.collections.Iterator<.P> [val] declared in .testForInArrayUse' type=kotlin.collections.Iterator<.P> origin=null + body: BLOCK type=kotlin.Unit origin=FOR_LOOP_INNER_WHILE + VAR FOR_LOOP_VARIABLE name:x type:.P [val] + CALL 'public abstract fun next (): T of kotlin.collections.Iterator [operator] declared in kotlin.collections.Iterator' type=.P origin=FOR_LOOP_NEXT + $this: GET_VAR 'val tmp_5: kotlin.collections.Iterator<.P> [val] declared in .testForInArrayUse' type=kotlin.collections.Iterator<.P> origin=null + BLOCK type=kotlin.Unit origin=null + CALL 'public final fun use (s: .P): kotlin.Unit declared in ' type=kotlin.Unit origin=null + s: TYPE_OP type=.P origin=IMPLICIT_NOTNULL typeOperand=.P + GET_VAR 'val x: .P [val] declared in .testForInArrayUse' type=.P origin=null + CALL 'public open fun use (s: .P): kotlin.Unit declared in .J' type=kotlin.Unit origin=null + s: GET_VAR 'val x: .P [val] declared in .testForInArrayUse' type=.P origin=null + CLASS INTERFACE name:K modality:ABSTRACT visibility:public superTypes:[kotlin.Any] + $this: VALUE_PARAMETER INSTANCE_RECEIVER name: type:.K + FUN name:arrayOfNotNull visibility:public modality:ABSTRACT <> ($this:.K) returnType:kotlin.Array<.P> + $this: VALUE_PARAMETER name: type:.K + FUN FAKE_OVERRIDE name:equals visibility:public modality:OPEN <> ($this:kotlin.Any, other:kotlin.Any?) returnType:kotlin.Boolean [fake_override,operator] + overridden: + public open fun equals (other: kotlin.Any?): kotlin.Boolean [operator] declared in kotlin.Any + $this: VALUE_PARAMETER name: type:kotlin.Any + VALUE_PARAMETER name:other index:0 type:kotlin.Any? + FUN FAKE_OVERRIDE name:hashCode visibility:public modality:OPEN <> ($this:kotlin.Any) returnType:kotlin.Int [fake_override] + overridden: + public open fun hashCode (): kotlin.Int declared in kotlin.Any + $this: VALUE_PARAMETER name: type:kotlin.Any + FUN FAKE_OVERRIDE name:toString visibility:public modality:OPEN <> ($this:kotlin.Any) returnType:kotlin.String [fake_override] + overridden: + public open fun toString (): kotlin.String declared in kotlin.Any + $this: VALUE_PARAMETER name: type:kotlin.Any + CLASS CLASS name:P modality:FINAL visibility:public [data] superTypes:[kotlin.Any] + $this: VALUE_PARAMETER INSTANCE_RECEIVER name: type:.P + CONSTRUCTOR visibility:public <> (x:kotlin.Int, y:kotlin.Int) returnType:.P [primary] + VALUE_PARAMETER name:x index:0 type:kotlin.Int + VALUE_PARAMETER name:y index:1 type:kotlin.Int + BLOCK_BODY + DELEGATING_CONSTRUCTOR_CALL 'public constructor () [primary] declared in kotlin.Any' + INSTANCE_INITIALIZER_CALL classDescriptor='CLASS CLASS name:P modality:FINAL visibility:public [data] superTypes:[kotlin.Any]' + PROPERTY name:x visibility:public modality:FINAL [val] + FIELD PROPERTY_BACKING_FIELD name:x type:kotlin.Int visibility:private [final] + EXPRESSION_BODY + GET_VAR 'x: kotlin.Int declared in .P.' type=kotlin.Int origin=INITIALIZE_PROPERTY_FROM_PARAMETER + FUN DEFAULT_PROPERTY_ACCESSOR name: visibility:public modality:FINAL <> ($this:.P) returnType:kotlin.Int + correspondingProperty: PROPERTY name:x visibility:public modality:FINAL [val] + $this: VALUE_PARAMETER name: type:.P + BLOCK_BODY + RETURN type=kotlin.Nothing from='public final fun (): kotlin.Int declared in .P' + GET_FIELD 'FIELD PROPERTY_BACKING_FIELD name:x type:kotlin.Int visibility:private [final]' type=kotlin.Int origin=null + receiver: GET_VAR ': .P declared in .P.' type=.P origin=null + PROPERTY name:y visibility:public modality:FINAL [val] + FIELD PROPERTY_BACKING_FIELD name:y type:kotlin.Int visibility:private [final] + EXPRESSION_BODY + GET_VAR 'y: kotlin.Int declared in .P.' type=kotlin.Int origin=INITIALIZE_PROPERTY_FROM_PARAMETER + FUN DEFAULT_PROPERTY_ACCESSOR name: visibility:public modality:FINAL <> ($this:.P) returnType:kotlin.Int + correspondingProperty: PROPERTY name:y visibility:public modality:FINAL [val] + $this: VALUE_PARAMETER name: type:.P + BLOCK_BODY + RETURN type=kotlin.Nothing from='public final fun (): kotlin.Int declared in .P' + GET_FIELD 'FIELD PROPERTY_BACKING_FIELD name:y type:kotlin.Int visibility:private [final]' type=kotlin.Int origin=null + receiver: GET_VAR ': .P declared in .P.' type=.P origin=null + FUN GENERATED_DATA_CLASS_MEMBER name:component1 visibility:public modality:FINAL <> ($this:.P) returnType:kotlin.Int [operator] + $this: VALUE_PARAMETER name: type:.P + BLOCK_BODY + RETURN type=kotlin.Nothing from='public final fun component1 (): kotlin.Int [operator] declared in .P' + GET_FIELD 'FIELD PROPERTY_BACKING_FIELD name:x type:kotlin.Int visibility:private [final]' type=kotlin.Int origin=null + receiver: GET_VAR ': .P declared in .P.component1' type=.P origin=null + FUN GENERATED_DATA_CLASS_MEMBER name:component2 visibility:public modality:FINAL <> ($this:.P) returnType:kotlin.Int [operator] + $this: VALUE_PARAMETER name: type:.P + BLOCK_BODY + RETURN type=kotlin.Nothing from='public final fun component2 (): kotlin.Int [operator] declared in .P' + GET_FIELD 'FIELD PROPERTY_BACKING_FIELD name:y type:kotlin.Int visibility:private [final]' type=kotlin.Int origin=null + receiver: GET_VAR ': .P declared in .P.component2' type=.P origin=null + FUN GENERATED_DATA_CLASS_MEMBER name:copy visibility:public modality:FINAL <> ($this:.P, x:kotlin.Int, y:kotlin.Int) returnType:.P + $this: VALUE_PARAMETER name: type:.P + VALUE_PARAMETER name:x index:0 type:kotlin.Int + EXPRESSION_BODY + GET_FIELD 'FIELD PROPERTY_BACKING_FIELD name:x type:kotlin.Int visibility:private [final]' type=kotlin.Int origin=null + receiver: GET_VAR ': .P declared in .P.copy' type=.P origin=null + VALUE_PARAMETER name:y index:1 type:kotlin.Int + EXPRESSION_BODY + GET_FIELD 'FIELD PROPERTY_BACKING_FIELD name:y type:kotlin.Int visibility:private [final]' type=kotlin.Int origin=null + receiver: GET_VAR ': .P declared in .P.copy' type=.P origin=null + BLOCK_BODY + RETURN type=kotlin.Nothing from='public final fun copy (x: kotlin.Int, y: kotlin.Int): .P declared in .P' + CONSTRUCTOR_CALL 'public constructor (x: kotlin.Int, y: kotlin.Int) [primary] declared in .P' type=.P origin=null + x: GET_VAR 'x: kotlin.Int declared in .P.copy' type=kotlin.Int origin=null + y: GET_VAR 'y: kotlin.Int declared in .P.copy' type=kotlin.Int origin=null + FUN GENERATED_DATA_CLASS_MEMBER name:toString visibility:public modality:OPEN <> ($this:.P) returnType:kotlin.String + overridden: + public open fun toString (): kotlin.String declared in kotlin.Any + $this: VALUE_PARAMETER name: type:.P + BLOCK_BODY + RETURN type=kotlin.Nothing from='public open fun toString (): kotlin.String declared in .P' + STRING_CONCATENATION type=kotlin.String + CONST String type=kotlin.String value="P(" + CONST String type=kotlin.String value="x=" + GET_FIELD 'FIELD PROPERTY_BACKING_FIELD name:x type:kotlin.Int visibility:private [final]' type=kotlin.Int origin=null + receiver: GET_VAR ': .P declared in .P.toString' type=.P origin=null + CONST String type=kotlin.String value=", " + CONST String type=kotlin.String value="y=" + GET_FIELD 'FIELD PROPERTY_BACKING_FIELD name:y type:kotlin.Int visibility:private [final]' type=kotlin.Int origin=null + receiver: GET_VAR ': .P declared in .P.toString' type=.P origin=null + CONST String type=kotlin.String value=")" + FUN GENERATED_DATA_CLASS_MEMBER name:hashCode visibility:public modality:OPEN <> ($this:.P) returnType:kotlin.Int + overridden: + public open fun hashCode (): kotlin.Int declared in kotlin.Any + $this: VALUE_PARAMETER name: type:.P + BLOCK_BODY + RETURN type=kotlin.Nothing from='public open fun hashCode (): kotlin.Int declared in .P' + CALL 'public final fun plus (other: kotlin.Int): kotlin.Int [operator] declared in kotlin.Int' type=kotlin.Int origin=null + $this: CALL 'public final fun times (other: kotlin.Int): kotlin.Int [operator] declared in kotlin.Int' type=kotlin.Int origin=null + $this: CALL 'public open fun hashCode (): kotlin.Int [fake_override] declared in kotlin.Int' type=kotlin.Int origin=null + $this: GET_FIELD 'FIELD PROPERTY_BACKING_FIELD name:x type:kotlin.Int visibility:private [final]' type=kotlin.Int origin=null + receiver: GET_VAR ': .P declared in .P.hashCode' type=.P origin=null + other: CONST Int type=kotlin.Int value=31 + other: CALL 'public open fun hashCode (): kotlin.Int [fake_override] declared in kotlin.Int' type=kotlin.Int origin=null + $this: GET_FIELD 'FIELD PROPERTY_BACKING_FIELD name:y type:kotlin.Int visibility:private [final]' type=kotlin.Int origin=null + receiver: GET_VAR ': .P declared in .P.hashCode' type=.P origin=null + FUN GENERATED_DATA_CLASS_MEMBER name:equals visibility:public modality:OPEN <> ($this:.P, other:kotlin.Any?) returnType:kotlin.Boolean [operator] + overridden: + public open fun equals (other: kotlin.Any?): kotlin.Boolean [operator] declared in kotlin.Any + $this: VALUE_PARAMETER name: type:.P + VALUE_PARAMETER name:other index:0 type:kotlin.Any? + BLOCK_BODY + WHEN type=kotlin.Unit origin=null + BRANCH + if: CALL 'public final fun EQEQEQ (arg0: kotlin.Any?, arg1: kotlin.Any?): kotlin.Boolean declared in kotlin.internal.ir' type=kotlin.Boolean origin=EQEQEQ + arg0: GET_VAR ': .P declared in .P.equals' type=.P origin=null + arg1: GET_VAR 'other: kotlin.Any? declared in .P.equals' type=kotlin.Any? origin=null + then: RETURN type=kotlin.Nothing from='public open fun equals (other: kotlin.Any?): kotlin.Boolean [operator] declared in .P' + CONST Boolean type=kotlin.Boolean value=true + WHEN type=kotlin.Unit origin=null + BRANCH + if: TYPE_OP type=kotlin.Boolean origin=NOT_INSTANCEOF typeOperand=.P + GET_VAR 'other: kotlin.Any? declared in .P.equals' type=kotlin.Any? origin=null + then: RETURN type=kotlin.Nothing from='public open fun equals (other: kotlin.Any?): kotlin.Boolean [operator] declared in .P' + CONST Boolean type=kotlin.Boolean value=false + VAR IR_TEMPORARY_VARIABLE name:tmp_6 type:.P [val] + TYPE_OP type=.P origin=CAST typeOperand=.P + GET_VAR 'other: kotlin.Any? declared in .P.equals' type=kotlin.Any? origin=null + WHEN type=kotlin.Unit origin=null + BRANCH + if: CALL 'public final fun not (): kotlin.Boolean [operator] declared in kotlin.Boolean' type=kotlin.Boolean origin=EXCLEQ + $this: CALL 'public final fun EQEQ (arg0: kotlin.Any?, arg1: kotlin.Any?): kotlin.Boolean declared in kotlin.internal.ir' type=kotlin.Boolean origin=EXCLEQ + arg0: GET_FIELD 'FIELD PROPERTY_BACKING_FIELD name:x type:kotlin.Int visibility:private [final]' type=kotlin.Int origin=null + receiver: GET_VAR ': .P declared in .P.equals' type=.P origin=null + arg1: GET_FIELD 'FIELD PROPERTY_BACKING_FIELD name:x type:kotlin.Int visibility:private [final]' type=kotlin.Int origin=null + receiver: GET_VAR 'val tmp_6: .P [val] declared in .P.equals' type=.P origin=null + then: RETURN type=kotlin.Nothing from='public open fun equals (other: kotlin.Any?): kotlin.Boolean [operator] declared in .P' + CONST Boolean type=kotlin.Boolean value=false + WHEN type=kotlin.Unit origin=null + BRANCH + if: CALL 'public final fun not (): kotlin.Boolean [operator] declared in kotlin.Boolean' type=kotlin.Boolean origin=EXCLEQ + $this: CALL 'public final fun EQEQ (arg0: kotlin.Any?, arg1: kotlin.Any?): kotlin.Boolean declared in kotlin.internal.ir' type=kotlin.Boolean origin=EXCLEQ + arg0: GET_FIELD 'FIELD PROPERTY_BACKING_FIELD name:y type:kotlin.Int visibility:private [final]' type=kotlin.Int origin=null + receiver: GET_VAR ': .P declared in .P.equals' type=.P origin=null + arg1: GET_FIELD 'FIELD PROPERTY_BACKING_FIELD name:y type:kotlin.Int visibility:private [final]' type=kotlin.Int origin=null + receiver: GET_VAR 'val tmp_6: .P [val] declared in .P.equals' type=.P origin=null + then: RETURN type=kotlin.Nothing from='public open fun equals (other: kotlin.Any?): kotlin.Boolean [operator] declared in .P' + CONST Boolean type=kotlin.Boolean value=false + RETURN type=kotlin.Nothing from='public open fun equals (other: kotlin.Any?): kotlin.Boolean [operator] declared in .P' + CONST Boolean type=kotlin.Boolean value=true diff --git a/compiler/testData/ir/irText/types/explicitEqualsAndCompareToCallsOnPlatformTypeReceiver.fir.txt b/compiler/testData/ir/irText/types/nullChecks/explicitEqualsAndCompareToCallsOnPlatformTypeReceiver.fir.txt similarity index 100% rename from compiler/testData/ir/irText/types/explicitEqualsAndCompareToCallsOnPlatformTypeReceiver.fir.txt rename to compiler/testData/ir/irText/types/nullChecks/explicitEqualsAndCompareToCallsOnPlatformTypeReceiver.fir.txt diff --git a/compiler/testData/ir/irText/types/explicitEqualsAndCompareToCallsOnPlatformTypeReceiver.kt b/compiler/testData/ir/irText/types/nullChecks/explicitEqualsAndCompareToCallsOnPlatformTypeReceiver.kt similarity index 100% rename from compiler/testData/ir/irText/types/explicitEqualsAndCompareToCallsOnPlatformTypeReceiver.kt rename to compiler/testData/ir/irText/types/nullChecks/explicitEqualsAndCompareToCallsOnPlatformTypeReceiver.kt diff --git a/compiler/testData/ir/irText/types/explicitEqualsAndCompareToCallsOnPlatformTypeReceiver.txt b/compiler/testData/ir/irText/types/nullChecks/explicitEqualsAndCompareToCallsOnPlatformTypeReceiver.txt similarity index 100% rename from compiler/testData/ir/irText/types/explicitEqualsAndCompareToCallsOnPlatformTypeReceiver.txt rename to compiler/testData/ir/irText/types/nullChecks/explicitEqualsAndCompareToCallsOnPlatformTypeReceiver.txt diff --git a/compiler/testData/ir/irText/types/implicitNotNullOnPlatformType.fir.txt b/compiler/testData/ir/irText/types/nullChecks/implicitNotNullOnPlatformType.fir.txt similarity index 100% rename from compiler/testData/ir/irText/types/implicitNotNullOnPlatformType.fir.txt rename to compiler/testData/ir/irText/types/nullChecks/implicitNotNullOnPlatformType.fir.txt diff --git a/compiler/testData/ir/irText/types/implicitNotNullOnPlatformType.kt b/compiler/testData/ir/irText/types/nullChecks/implicitNotNullOnPlatformType.kt similarity index 100% rename from compiler/testData/ir/irText/types/implicitNotNullOnPlatformType.kt rename to compiler/testData/ir/irText/types/nullChecks/implicitNotNullOnPlatformType.kt diff --git a/compiler/testData/ir/irText/types/implicitNotNullOnPlatformType.txt b/compiler/testData/ir/irText/types/nullChecks/implicitNotNullOnPlatformType.txt similarity index 100% rename from compiler/testData/ir/irText/types/implicitNotNullOnPlatformType.txt rename to compiler/testData/ir/irText/types/nullChecks/implicitNotNullOnPlatformType.txt diff --git a/compiler/testData/ir/irText/types/nullabilityAssertionOnExtensionReceiver.fir.txt b/compiler/testData/ir/irText/types/nullChecks/nullabilityAssertionOnExtensionReceiver.fir.txt similarity index 100% rename from compiler/testData/ir/irText/types/nullabilityAssertionOnExtensionReceiver.fir.txt rename to compiler/testData/ir/irText/types/nullChecks/nullabilityAssertionOnExtensionReceiver.fir.txt diff --git a/compiler/testData/ir/irText/types/nullabilityAssertionOnExtensionReceiver.kt b/compiler/testData/ir/irText/types/nullChecks/nullabilityAssertionOnExtensionReceiver.kt similarity index 100% rename from compiler/testData/ir/irText/types/nullabilityAssertionOnExtensionReceiver.kt rename to compiler/testData/ir/irText/types/nullChecks/nullabilityAssertionOnExtensionReceiver.kt diff --git a/compiler/testData/ir/irText/types/nullabilityAssertionOnExtensionReceiver.txt b/compiler/testData/ir/irText/types/nullChecks/nullabilityAssertionOnExtensionReceiver.txt similarity index 100% rename from compiler/testData/ir/irText/types/nullabilityAssertionOnExtensionReceiver.txt rename to compiler/testData/ir/irText/types/nullChecks/nullabilityAssertionOnExtensionReceiver.txt diff --git a/compiler/testData/ir/irText/types/platformTypeReceiver.fir.txt b/compiler/testData/ir/irText/types/nullChecks/platformTypeReceiver.fir.txt similarity index 100% rename from compiler/testData/ir/irText/types/platformTypeReceiver.fir.txt rename to compiler/testData/ir/irText/types/nullChecks/platformTypeReceiver.fir.txt diff --git a/compiler/testData/ir/irText/types/platformTypeReceiver.kt b/compiler/testData/ir/irText/types/nullChecks/platformTypeReceiver.kt similarity index 100% rename from compiler/testData/ir/irText/types/platformTypeReceiver.kt rename to compiler/testData/ir/irText/types/nullChecks/platformTypeReceiver.kt diff --git a/compiler/testData/ir/irText/types/platformTypeReceiver.txt b/compiler/testData/ir/irText/types/nullChecks/platformTypeReceiver.txt similarity index 100% rename from compiler/testData/ir/irText/types/platformTypeReceiver.txt rename to compiler/testData/ir/irText/types/nullChecks/platformTypeReceiver.txt diff --git a/compiler/tests/org/jetbrains/kotlin/ir/IrTextTestCaseGenerated.java b/compiler/tests/org/jetbrains/kotlin/ir/IrTextTestCaseGenerated.java index ba0d1f869fb..c358bbd9af3 100644 --- a/compiler/tests/org/jetbrains/kotlin/ir/IrTextTestCaseGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/ir/IrTextTestCaseGenerated.java @@ -1806,26 +1806,11 @@ public class IrTextTestCaseGenerated extends AbstractIrTextTestCase { runTest("compiler/testData/ir/irText/types/asOnPlatformType.kt"); } - @TestMetadata("enhancedNullability.kt") - public void testEnhancedNullability() throws Exception { - runTest("compiler/testData/ir/irText/types/enhancedNullability.kt"); - } - - @TestMetadata("explicitEqualsAndCompareToCallsOnPlatformTypeReceiver.kt") - public void testExplicitEqualsAndCompareToCallsOnPlatformTypeReceiver() throws Exception { - runTest("compiler/testData/ir/irText/types/explicitEqualsAndCompareToCallsOnPlatformTypeReceiver.kt"); - } - @TestMetadata("genericPropertyReferenceType.kt") public void testGenericPropertyReferenceType() throws Exception { runTest("compiler/testData/ir/irText/types/genericPropertyReferenceType.kt"); } - @TestMetadata("implicitNotNullOnPlatformType.kt") - public void testImplicitNotNullOnPlatformType() throws Exception { - runTest("compiler/testData/ir/irText/types/implicitNotNullOnPlatformType.kt"); - } - @TestMetadata("intersectionType1_NI.kt") public void testIntersectionType1_NI() throws Exception { runTest("compiler/testData/ir/irText/types/intersectionType1_NI.kt"); @@ -1861,16 +1846,6 @@ public class IrTextTestCaseGenerated extends AbstractIrTextTestCase { runTest("compiler/testData/ir/irText/types/localVariableOfIntersectionType_NI.kt"); } - @TestMetadata("nullabilityAssertionOnExtensionReceiver.kt") - public void testNullabilityAssertionOnExtensionReceiver() throws Exception { - runTest("compiler/testData/ir/irText/types/nullabilityAssertionOnExtensionReceiver.kt"); - } - - @TestMetadata("platformTypeReceiver.kt") - public void testPlatformTypeReceiver() throws Exception { - runTest("compiler/testData/ir/irText/types/platformTypeReceiver.kt"); - } - @TestMetadata("smartCastOnFakeOverrideReceiver.kt") public void testSmartCastOnFakeOverrideReceiver() throws Exception { runTest("compiler/testData/ir/irText/types/smartCastOnFakeOverrideReceiver.kt"); @@ -1885,5 +1860,53 @@ public class IrTextTestCaseGenerated extends AbstractIrTextTestCase { public void testSmartCastOnReceiverOfGenericType() throws Exception { runTest("compiler/testData/ir/irText/types/smartCastOnReceiverOfGenericType.kt"); } + + @TestMetadata("compiler/testData/ir/irText/types/nullChecks") + @TestDataPath("$PROJECT_ROOT") + @RunWith(JUnit3RunnerWithInners.class) + public static class NullChecks extends AbstractIrTextTestCase { + private void runTest(String testDataFilePath) throws Exception { + KotlinTestUtils.runTest(this::doTest, this, testDataFilePath); + } + + public void testAllFilesPresentInNullChecks() throws Exception { + KotlinTestUtils.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/ir/irText/types/nullChecks"), Pattern.compile("^(.+)\\.kt$"), null, true); + } + + @TestMetadata("enhancedNullability.kt") + public void testEnhancedNullability() throws Exception { + runTest("compiler/testData/ir/irText/types/nullChecks/enhancedNullability.kt"); + } + + @TestMetadata("enhancedNullabilityInDestructuringAssignment.kt") + public void testEnhancedNullabilityInDestructuringAssignment() throws Exception { + runTest("compiler/testData/ir/irText/types/nullChecks/enhancedNullabilityInDestructuringAssignment.kt"); + } + + @TestMetadata("enhancedNullabilityInForLoop.kt") + public void testEnhancedNullabilityInForLoop() throws Exception { + runTest("compiler/testData/ir/irText/types/nullChecks/enhancedNullabilityInForLoop.kt"); + } + + @TestMetadata("explicitEqualsAndCompareToCallsOnPlatformTypeReceiver.kt") + public void testExplicitEqualsAndCompareToCallsOnPlatformTypeReceiver() throws Exception { + runTest("compiler/testData/ir/irText/types/nullChecks/explicitEqualsAndCompareToCallsOnPlatformTypeReceiver.kt"); + } + + @TestMetadata("implicitNotNullOnPlatformType.kt") + public void testImplicitNotNullOnPlatformType() throws Exception { + runTest("compiler/testData/ir/irText/types/nullChecks/implicitNotNullOnPlatformType.kt"); + } + + @TestMetadata("nullabilityAssertionOnExtensionReceiver.kt") + public void testNullabilityAssertionOnExtensionReceiver() throws Exception { + runTest("compiler/testData/ir/irText/types/nullChecks/nullabilityAssertionOnExtensionReceiver.kt"); + } + + @TestMetadata("platformTypeReceiver.kt") + public void testPlatformTypeReceiver() throws Exception { + runTest("compiler/testData/ir/irText/types/nullChecks/platformTypeReceiver.kt"); + } + } } }