diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/ExpressionCodegen.java b/compiler/backend/src/org/jetbrains/kotlin/codegen/ExpressionCodegen.java index d12dbeab9ac..e8262db801e 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/ExpressionCodegen.java +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/ExpressionCodegen.java @@ -2646,7 +2646,13 @@ public class ExpressionCodegen extends KtVisitor impleme KotlinType returnType = resolvedCall.getResultingDescriptor().getReturnType(); if (returnType != null && KotlinBuiltIns.isNothing(returnType)) { - v.aconst(null); + if (state.getLanguageVersionSettings().getApiVersion().compareTo(ApiVersion.KOTLIN_1_4) >= 0) { + v.anew(Type.getObjectType("kotlin/KotlinNothingValueException")); + v.dup(); + v.invokespecial("kotlin/KotlinNothingValueException", "", "()V", false); + } else { + v.aconst(null); + } v.athrow(); } } diff --git a/compiler/fir/fir2ir/tests/org/jetbrains/kotlin/codegen/ir/FirBlackBoxCodegenTestGenerated.java b/compiler/fir/fir2ir/tests/org/jetbrains/kotlin/codegen/ir/FirBlackBoxCodegenTestGenerated.java index a480b7a2710..fd82b92332b 100644 --- a/compiler/fir/fir2ir/tests/org/jetbrains/kotlin/codegen/ir/FirBlackBoxCodegenTestGenerated.java +++ b/compiler/fir/fir2ir/tests/org/jetbrains/kotlin/codegen/ir/FirBlackBoxCodegenTestGenerated.java @@ -17262,6 +17262,24 @@ public class FirBlackBoxCodegenTestGenerated extends AbstractFirBlackBoxCodegenT } } + @TestMetadata("compiler/testData/codegen/box/nothingValue") + @TestDataPath("$PROJECT_ROOT") + @RunWith(JUnit3RunnerWithInners.class) + public static class NothingValue extends AbstractFirBlackBoxCodegenTest { + private void runTest(String testDataFilePath) throws Exception { + KotlinTestUtils.runTestWithCustomIgnoreDirective(this::doTest, TargetBackend.JVM_IR, testDataFilePath, "// IGNORE_BACKEND_FIR: "); + } + + public void testAllFilesPresentInNothingValue() throws Exception { + KotlinTestUtils.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/box/nothingValue"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JVM_IR, true); + } + + @TestMetadata("nothingValueException.kt") + public void testNothingValueException() throws Exception { + runTest("compiler/testData/codegen/box/nothingValue/nothingValueException.kt"); + } + } + @TestMetadata("compiler/testData/codegen/box/nullCheckOptimization") @TestDataPath("$PROJECT_ROOT") @RunWith(JUnit3RunnerWithInners.class) diff --git a/compiler/testData/codegen/box/nothingValue/nothingValueException.kt b/compiler/testData/codegen/box/nothingValue/nothingValueException.kt new file mode 100644 index 00000000000..1fd3671ed40 --- /dev/null +++ b/compiler/testData/codegen/box/nothingValue/nothingValueException.kt @@ -0,0 +1,29 @@ +// IGNORE_BACKEND_FIR: JVM_IR +// IGNORE_BACKEND: JS, JS_IR, JVM_IR, NATIVE + +fun something(): T = Any() as T + +class Context + +fun Any.decodeIn(typeFrom: Context): T = something() + +fun Any?.decodeOut(typeFrom: Context): T { + return this?.decodeIn(typeFrom) // decodeIn result is of type Nothing + ?: throw AssertionError("") +} + +fun box(): String { + try { + "str".decodeOut(Context()) + } catch (e: Exception) { + // TODO check FQN + val exceptionClassName = e::class.simpleName + if (exceptionClassName != "KotlinNothingValueException") { + throw AssertionError("Unexpected exception: $e") + } else { + return "OK" + } + } + + throw AssertionError("Should fail with exception") +} \ No newline at end of file diff --git a/compiler/tests/org/jetbrains/kotlin/codegen/BlackBoxCodegenTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/codegen/BlackBoxCodegenTestGenerated.java index 0b4c96b2d0d..93b2c91c4c6 100644 --- a/compiler/tests/org/jetbrains/kotlin/codegen/BlackBoxCodegenTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/codegen/BlackBoxCodegenTestGenerated.java @@ -18477,6 +18477,24 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest { } } + @TestMetadata("compiler/testData/codegen/box/nothingValue") + @TestDataPath("$PROJECT_ROOT") + @RunWith(JUnit3RunnerWithInners.class) + public static class NothingValue extends AbstractBlackBoxCodegenTest { + private void runTest(String testDataFilePath) throws Exception { + KotlinTestUtils.runTest(this::doTest, TargetBackend.JVM, testDataFilePath); + } + + public void testAllFilesPresentInNothingValue() throws Exception { + KotlinTestUtils.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/box/nothingValue"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JVM, true); + } + + @TestMetadata("nothingValueException.kt") + public void testNothingValueException() throws Exception { + runTest("compiler/testData/codegen/box/nothingValue/nothingValueException.kt"); + } + } + @TestMetadata("compiler/testData/codegen/box/nullCheckOptimization") @TestDataPath("$PROJECT_ROOT") @RunWith(JUnit3RunnerWithInners.class) diff --git a/compiler/tests/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java index 49886e7ffd9..fef5472297a 100644 --- a/compiler/tests/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java @@ -18477,6 +18477,24 @@ public class LightAnalysisModeTestGenerated extends AbstractLightAnalysisModeTes } } + @TestMetadata("compiler/testData/codegen/box/nothingValue") + @TestDataPath("$PROJECT_ROOT") + @RunWith(JUnit3RunnerWithInners.class) + public static class NothingValue extends AbstractLightAnalysisModeTest { + private void runTest(String testDataFilePath) throws Exception { + KotlinTestUtils.runTest(this::doTest, TargetBackend.JVM, testDataFilePath); + } + + public void testAllFilesPresentInNothingValue() throws Exception { + KotlinTestUtils.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/box/nothingValue"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JVM, true); + } + + @TestMetadata("nothingValueException.kt") + public void testNothingValueException() throws Exception { + runTest("compiler/testData/codegen/box/nothingValue/nothingValueException.kt"); + } + } + @TestMetadata("compiler/testData/codegen/box/nullCheckOptimization") @TestDataPath("$PROJECT_ROOT") @RunWith(JUnit3RunnerWithInners.class) diff --git a/compiler/tests/org/jetbrains/kotlin/codegen/ir/IrBlackBoxCodegenTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/codegen/ir/IrBlackBoxCodegenTestGenerated.java index cae7e1c4e07..05d1f2f0b6f 100644 --- a/compiler/tests/org/jetbrains/kotlin/codegen/ir/IrBlackBoxCodegenTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/codegen/ir/IrBlackBoxCodegenTestGenerated.java @@ -17262,6 +17262,24 @@ public class IrBlackBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTes } } + @TestMetadata("compiler/testData/codegen/box/nothingValue") + @TestDataPath("$PROJECT_ROOT") + @RunWith(JUnit3RunnerWithInners.class) + public static class NothingValue extends AbstractIrBlackBoxCodegenTest { + private void runTest(String testDataFilePath) throws Exception { + KotlinTestUtils.runTest(this::doTest, TargetBackend.JVM_IR, testDataFilePath); + } + + public void testAllFilesPresentInNothingValue() throws Exception { + KotlinTestUtils.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/box/nothingValue"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JVM_IR, true); + } + + @TestMetadata("nothingValueException.kt") + public void testNothingValueException() throws Exception { + runTest("compiler/testData/codegen/box/nothingValue/nothingValueException.kt"); + } + } + @TestMetadata("compiler/testData/codegen/box/nullCheckOptimization") @TestDataPath("$PROJECT_ROOT") @RunWith(JUnit3RunnerWithInners.class) diff --git a/js/js.tests/test/org/jetbrains/kotlin/js/test/ir/semantics/IrJsCodegenBoxTestGenerated.java b/js/js.tests/test/org/jetbrains/kotlin/js/test/ir/semantics/IrJsCodegenBoxTestGenerated.java index ba1b1ea5d9a..880ad667c5b 100644 --- a/js/js.tests/test/org/jetbrains/kotlin/js/test/ir/semantics/IrJsCodegenBoxTestGenerated.java +++ b/js/js.tests/test/org/jetbrains/kotlin/js/test/ir/semantics/IrJsCodegenBoxTestGenerated.java @@ -13902,6 +13902,24 @@ public class IrJsCodegenBoxTestGenerated extends AbstractIrJsCodegenBoxTest { } } + @TestMetadata("compiler/testData/codegen/box/nothingValue") + @TestDataPath("$PROJECT_ROOT") + @RunWith(JUnit3RunnerWithInners.class) + public static class NothingValue extends AbstractIrJsCodegenBoxTest { + private void runTest(String testDataFilePath) throws Exception { + KotlinTestUtils.runTest0(this::doTest, TargetBackend.JS_IR, testDataFilePath); + } + + public void testAllFilesPresentInNothingValue() throws Exception { + KotlinTestUtils.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/box/nothingValue"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JS_IR, true); + } + + @TestMetadata("nothingValueException.kt") + public void testNothingValueException() throws Exception { + runTest("compiler/testData/codegen/box/nothingValue/nothingValueException.kt"); + } + } + @TestMetadata("compiler/testData/codegen/box/nullCheckOptimization") @TestDataPath("$PROJECT_ROOT") @RunWith(JUnit3RunnerWithInners.class) diff --git a/js/js.tests/test/org/jetbrains/kotlin/js/test/semantics/JsCodegenBoxTestGenerated.java b/js/js.tests/test/org/jetbrains/kotlin/js/test/semantics/JsCodegenBoxTestGenerated.java index 746ef5fc504..2955d2c05eb 100644 --- a/js/js.tests/test/org/jetbrains/kotlin/js/test/semantics/JsCodegenBoxTestGenerated.java +++ b/js/js.tests/test/org/jetbrains/kotlin/js/test/semantics/JsCodegenBoxTestGenerated.java @@ -13967,6 +13967,24 @@ public class JsCodegenBoxTestGenerated extends AbstractJsCodegenBoxTest { } } + @TestMetadata("compiler/testData/codegen/box/nothingValue") + @TestDataPath("$PROJECT_ROOT") + @RunWith(JUnit3RunnerWithInners.class) + public static class NothingValue extends AbstractJsCodegenBoxTest { + private void runTest(String testDataFilePath) throws Exception { + KotlinTestUtils.runTest0(this::doTest, TargetBackend.JS, testDataFilePath); + } + + public void testAllFilesPresentInNothingValue() throws Exception { + KotlinTestUtils.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/box/nothingValue"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JS, true); + } + + @TestMetadata("nothingValueException.kt") + public void testNothingValueException() throws Exception { + runTest("compiler/testData/codegen/box/nothingValue/nothingValueException.kt"); + } + } + @TestMetadata("compiler/testData/codegen/box/nullCheckOptimization") @TestDataPath("$PROJECT_ROOT") @RunWith(JUnit3RunnerWithInners.class)