diff --git a/compiler/fir/fir2ir/tests-gen/org/jetbrains/kotlin/test/runners/codegen/FirBytecodeTextTestGenerated.java b/compiler/fir/fir2ir/tests-gen/org/jetbrains/kotlin/test/runners/codegen/FirBytecodeTextTestGenerated.java index a2964cee377..a618a0e228b 100644 --- a/compiler/fir/fir2ir/tests-gen/org/jetbrains/kotlin/test/runners/codegen/FirBytecodeTextTestGenerated.java +++ b/compiler/fir/fir2ir/tests-gen/org/jetbrains/kotlin/test/runners/codegen/FirBytecodeTextTestGenerated.java @@ -2274,6 +2274,12 @@ public class FirBytecodeTextTestGenerated extends AbstractFirBytecodeTextTest { KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/bytecodeText/exclExcl"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JVM_IR, true); } + @Test + @TestMetadata("exclExclOnPlatformType.kt") + public void testExclExclOnPlatformType() throws Exception { + runTest("compiler/testData/codegen/bytecodeText/exclExcl/exclExclOnPlatformType.kt"); + } + @Test @TestMetadata("primitive.kt") public void testPrimitive() throws Exception { diff --git a/compiler/fir/fir2ir/tests-gen/org/jetbrains/kotlin/test/runners/ir/Fir2IrTextTestGenerated.java b/compiler/fir/fir2ir/tests-gen/org/jetbrains/kotlin/test/runners/ir/Fir2IrTextTestGenerated.java index ddfc49782f8..9fd2dc2fde4 100644 --- a/compiler/fir/fir2ir/tests-gen/org/jetbrains/kotlin/test/runners/ir/Fir2IrTextTestGenerated.java +++ b/compiler/fir/fir2ir/tests-gen/org/jetbrains/kotlin/test/runners/ir/Fir2IrTextTestGenerated.java @@ -1340,6 +1340,12 @@ public class Fir2IrTextTestGenerated extends AbstractFir2IrTextTest { runTest("compiler/testData/ir/irText/expressions/equals.kt"); } + @Test + @TestMetadata("exclExclOnPlatformType.kt") + public void testExclExclOnPlatformType() throws Exception { + runTest("compiler/testData/ir/irText/expressions/exclExclOnPlatformType.kt"); + } + @Test @TestMetadata("exhaustiveWhenElseBranch.kt") public void testExhaustiveWhenElseBranch() throws Exception { diff --git a/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/generators/OperatorExpressionGenerator.kt b/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/generators/OperatorExpressionGenerator.kt index 86e124bfa1b..e8405730a57 100644 --- a/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/generators/OperatorExpressionGenerator.kt +++ b/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/generators/OperatorExpressionGenerator.kt @@ -25,11 +25,8 @@ import org.jetbrains.kotlin.ir.descriptors.IrBuiltInsOverDescriptors import org.jetbrains.kotlin.ir.expressions.* import org.jetbrains.kotlin.ir.expressions.impl.* import org.jetbrains.kotlin.ir.symbols.IrSimpleFunctionSymbol -import org.jetbrains.kotlin.ir.types.IrType -import org.jetbrains.kotlin.ir.types.classifierOrFail -import org.jetbrains.kotlin.ir.types.classifierOrNull +import org.jetbrains.kotlin.ir.types.* import org.jetbrains.kotlin.ir.types.impl.originalKotlinType -import org.jetbrains.kotlin.ir.types.makeNotNull import org.jetbrains.kotlin.lexer.KtTokens import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.psi.* @@ -504,7 +501,8 @@ class OperatorExpressionGenerator(statementGenerator: StatementGenerator) : Stat val argumentType = context.bindingContext.getType(ktArgument) ?: throw AssertionError("No type for !! argument") - val expressionType = argumentType.makeNotNullable() + + val expressionType = context.extensions.enhancedNullability.stripEnhancedNullability(argumentType.makeNotNullable()) val checkNotNull = context.irBuiltIns.checkNotNullSymbol.descriptor val checkNotNullSubstituted = @@ -514,15 +512,17 @@ class OperatorExpressionGenerator(statementGenerator: StatementGenerator) : Stat ) ) ?: throw AssertionError("Substitution failed for $checkNotNull: T=$argumentType") + val expressionIrType = expressionType.toIrType() + val checkNotNullSymbol = context.irBuiltIns.checkNotNullSymbol return IrCallImpl.fromSymbolDescriptor( ktOperator.startOffsetSkippingComments, ktOperator.endOffset, - expressionType.toIrType(), + expressionIrType, checkNotNullSymbol, origin = origin ).apply { context.callToSubstitutedDescriptorMap[this] = checkNotNullSubstituted - putTypeArgument(0, argumentType.toIrType().makeNotNull()) + putTypeArgument(0, expressionIrType) putValueArgument(0, irArgument) } } diff --git a/compiler/testData/codegen/bytecodeText/exclExcl/exclExclOnPlatformType.kt b/compiler/testData/codegen/bytecodeText/exclExcl/exclExclOnPlatformType.kt new file mode 100644 index 00000000000..842e4a1bcb1 --- /dev/null +++ b/compiler/testData/codegen/bytecodeText/exclExcl/exclExclOnPlatformType.kt @@ -0,0 +1,17 @@ +// FULL_JDK +import java.lang.ref.WeakReference + +fun func1(x: Any) {} + +fun func2() { + func1(WeakReference(Any()).get()!!) +} + +// 0 ASTORE +// ^ no temporary variables created in 'func2' +// 1 ALOAD +// ^ single ALOAD in 'func1' (parameter null check) + +// JVM_IR_TEMPLATES +// 0 checkNotNullExpressionValue +// ^ no null check on result of 'get()!!' diff --git a/compiler/testData/ir/irText/expressions/exclExclOnPlatformType.fir.ir.txt b/compiler/testData/ir/irText/expressions/exclExclOnPlatformType.fir.ir.txt new file mode 100644 index 00000000000..d533dcbd36f --- /dev/null +++ b/compiler/testData/ir/irText/expressions/exclExclOnPlatformType.fir.ir.txt @@ -0,0 +1,18 @@ +FILE fqName: fileName:/exclExclOnPlatformType.kt + FUN name:use visibility:public modality:FINAL <> (a:kotlin.Any) returnType:kotlin.Unit + VALUE_PARAMETER name:a index:0 type:kotlin.Any + BLOCK_BODY + FUN name:test visibility:public modality:FINAL <> () returnType:kotlin.Unit + BLOCK_BODY + CALL 'public final fun use (a: kotlin.Any): kotlin.Unit declared in ' type=kotlin.Unit origin=null + a: CALL 'public final fun CHECK_NOT_NULL (arg0: T0 of kotlin.internal.ir.CHECK_NOT_NULL?): T0 of kotlin.internal.ir.CHECK_NOT_NULL declared in kotlin.internal.ir' type=kotlin.String origin=EXCLEXCL + : kotlin.String + arg0: CALL 'public open fun get (): T of java.lang.ref.WeakReference? [fake_override,operator] declared in java.lang.ref.WeakReference' type=kotlin.String? origin=null + $this: CONSTRUCTOR_CALL 'public constructor (p0: @[FlexibleNullability] T of java.lang.ref.WeakReference?) declared in java.lang.ref.WeakReference' type=java.lang.ref.WeakReference<@[FlexibleNullability] kotlin.String?> origin=null + : @[FlexibleNullability] kotlin.String? + p0: CONST String type=kotlin.String value="" + CALL 'public final fun use (a: kotlin.Any): kotlin.Unit declared in ' type=kotlin.Unit origin=null + a: CALL 'public final fun CHECK_NOT_NULL (arg0: T0 of kotlin.internal.ir.CHECK_NOT_NULL?): T0 of kotlin.internal.ir.CHECK_NOT_NULL declared in kotlin.internal.ir' type=kotlin.String origin=EXCLEXCL + : @[FlexibleNullability] kotlin.String + arg0: CALL 'public open fun getProperty (p0: @[FlexibleNullability] kotlin.String?): @[FlexibleNullability] kotlin.String? declared in java.lang.System' type=@[FlexibleNullability] kotlin.String? origin=null + p0: CONST String type=kotlin.String value="abc" diff --git a/compiler/testData/ir/irText/expressions/exclExclOnPlatformType.fir.kt.txt b/compiler/testData/ir/irText/expressions/exclExclOnPlatformType.fir.kt.txt new file mode 100644 index 00000000000..953814ac05f --- /dev/null +++ b/compiler/testData/ir/irText/expressions/exclExclOnPlatformType.fir.kt.txt @@ -0,0 +1,8 @@ +fun use(a: Any) { +} + +fun test() { + use(a = CHECK_NOT_NULL(arg0 = WeakReference<@FlexibleNullability String?>(p0 = "").get())) + use(a = CHECK_NOT_NULL<@FlexibleNullability String>(arg0 = getProperty(p0 = "abc"))) +} + diff --git a/compiler/testData/ir/irText/expressions/exclExclOnPlatformType.ir.txt b/compiler/testData/ir/irText/expressions/exclExclOnPlatformType.ir.txt new file mode 100644 index 00000000000..f11e263aae9 --- /dev/null +++ b/compiler/testData/ir/irText/expressions/exclExclOnPlatformType.ir.txt @@ -0,0 +1,18 @@ +FILE fqName: fileName:/exclExclOnPlatformType.kt + FUN name:use visibility:public modality:FINAL <> (a:kotlin.Any) returnType:kotlin.Unit + VALUE_PARAMETER name:a index:0 type:kotlin.Any + BLOCK_BODY + FUN name:test visibility:public modality:FINAL <> () returnType:kotlin.Unit + BLOCK_BODY + CALL 'public final fun use (a: kotlin.Any): kotlin.Unit declared in ' type=kotlin.Unit origin=null + a: CALL 'public final fun CHECK_NOT_NULL (arg0: T0 of kotlin.internal.ir.CHECK_NOT_NULL?): T0 of kotlin.internal.ir.CHECK_NOT_NULL declared in kotlin.internal.ir' type=kotlin.String origin=EXCLEXCL + : kotlin.String + arg0: CALL 'public open fun get (): @[EnhancedNullability] T of java.lang.ref.WeakReference? [fake_override] declared in java.lang.ref.WeakReference' type=@[EnhancedNullability] kotlin.String? origin=null + $this: CONSTRUCTOR_CALL 'public constructor (p0: @[FlexibleNullability] T of java.lang.ref.WeakReference?) declared in java.lang.ref.WeakReference' type=java.lang.ref.WeakReference<@[FlexibleNullability] kotlin.String?> origin=null + : @[FlexibleNullability] kotlin.String? + p0: CONST String type=kotlin.String value="" + CALL 'public final fun use (a: kotlin.Any): kotlin.Unit declared in ' type=kotlin.Unit origin=null + a: CALL 'public final fun CHECK_NOT_NULL (arg0: T0 of kotlin.internal.ir.CHECK_NOT_NULL?): T0 of kotlin.internal.ir.CHECK_NOT_NULL declared in kotlin.internal.ir' type=kotlin.String origin=EXCLEXCL + : kotlin.String + arg0: CALL 'public open fun getProperty (p0: @[FlexibleNullability] kotlin.String?): @[FlexibleNullability] kotlin.String? declared in java.lang.System' type=@[FlexibleNullability] kotlin.String? origin=null + p0: CONST String type=kotlin.String value="abc" diff --git a/compiler/testData/ir/irText/expressions/exclExclOnPlatformType.kt b/compiler/testData/ir/irText/expressions/exclExclOnPlatformType.kt new file mode 100644 index 00000000000..5a7bd9d1514 --- /dev/null +++ b/compiler/testData/ir/irText/expressions/exclExclOnPlatformType.kt @@ -0,0 +1,11 @@ +// TARGET_BACKEND: JVM +// FULL_JDK + +import java.lang.ref.WeakReference + +fun use(a: Any) {} + +fun test() { + use(WeakReference("").get()!!) + use(System.getProperty("abc")!!) +} diff --git a/compiler/testData/ir/irText/expressions/exclExclOnPlatformType.kt.txt b/compiler/testData/ir/irText/expressions/exclExclOnPlatformType.kt.txt new file mode 100644 index 00000000000..88071518ea0 --- /dev/null +++ b/compiler/testData/ir/irText/expressions/exclExclOnPlatformType.kt.txt @@ -0,0 +1,8 @@ +fun use(a: Any) { +} + +fun test() { + use(a = CHECK_NOT_NULL(arg0 = WeakReference<@FlexibleNullability String?>(p0 = "").get())) + use(a = CHECK_NOT_NULL(arg0 = getProperty(p0 = "abc"))) +} + diff --git a/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/BytecodeTextTestGenerated.java b/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/BytecodeTextTestGenerated.java index 653316e9538..561f7bfbf64 100644 --- a/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/BytecodeTextTestGenerated.java +++ b/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/BytecodeTextTestGenerated.java @@ -2250,6 +2250,12 @@ public class BytecodeTextTestGenerated extends AbstractBytecodeTextTest { KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/bytecodeText/exclExcl"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JVM, true); } + @Test + @TestMetadata("exclExclOnPlatformType.kt") + public void testExclExclOnPlatformType() throws Exception { + runTest("compiler/testData/codegen/bytecodeText/exclExcl/exclExclOnPlatformType.kt"); + } + @Test @TestMetadata("primitive.kt") public void testPrimitive() throws Exception { diff --git a/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/IrBytecodeTextTestGenerated.java b/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/IrBytecodeTextTestGenerated.java index 97c64841993..2d2ce479015 100644 --- a/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/IrBytecodeTextTestGenerated.java +++ b/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/IrBytecodeTextTestGenerated.java @@ -2274,6 +2274,12 @@ public class IrBytecodeTextTestGenerated extends AbstractIrBytecodeTextTest { KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/bytecodeText/exclExcl"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JVM_IR, true); } + @Test + @TestMetadata("exclExclOnPlatformType.kt") + public void testExclExclOnPlatformType() throws Exception { + runTest("compiler/testData/codegen/bytecodeText/exclExcl/exclExclOnPlatformType.kt"); + } + @Test @TestMetadata("primitive.kt") public void testPrimitive() throws Exception { diff --git a/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/ir/IrTextTestGenerated.java b/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/ir/IrTextTestGenerated.java index a608c19ebda..ff4daa078b6 100644 --- a/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/ir/IrTextTestGenerated.java +++ b/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/ir/IrTextTestGenerated.java @@ -1340,6 +1340,12 @@ public class IrTextTestGenerated extends AbstractIrTextTest { runTest("compiler/testData/ir/irText/expressions/equals.kt"); } + @Test + @TestMetadata("exclExclOnPlatformType.kt") + public void testExclExclOnPlatformType() throws Exception { + runTest("compiler/testData/ir/irText/expressions/exclExclOnPlatformType.kt"); + } + @Test @TestMetadata("exhaustiveWhenElseBranch.kt") public void testExhaustiveWhenElseBranch() throws Exception {