From 4ab6b6954d41668c6e52d92052a07857a03809f8 Mon Sep 17 00:00:00 2001 From: Denis Zharkov Date: Wed, 18 Jan 2017 18:20:19 +0300 Subject: [PATCH] Fix false positive "Null can not be a value of a non-null type" Inferred type of receiver of orElse is Optional Generic descriptor is orElse(E!): E! Substituted descriptor is orElse(T): T , and that is the problem. Seems that E! => (T & Any)! gets expanded to just T or T & Any , however it should be expanded to (T & Any) .. (T & Any)? => T & Any .. T & Any T & Any is NotNullTypeParameter(T) The problem is that (T & Any)? is expanded to T & Any, that is seems to be wrong. #KT-15236 Fixed --- .../diagnostics/testsWithJava8/nullForOptionalOrElse.kt | 7 +++++++ .../diagnostics/testsWithJava8/nullForOptionalOrElse.txt | 3 +++ .../kotlin/checkers/DiagnosticsWithJava8TestGenerated.java | 6 ++++++ .../kotlin/load/java/typeEnhancement/typeEnhancement.kt | 3 ++- 4 files changed, 18 insertions(+), 1 deletion(-) create mode 100644 compiler/testData/diagnostics/testsWithJava8/nullForOptionalOrElse.kt create mode 100644 compiler/testData/diagnostics/testsWithJava8/nullForOptionalOrElse.txt diff --git a/compiler/testData/diagnostics/testsWithJava8/nullForOptionalOrElse.kt b/compiler/testData/diagnostics/testsWithJava8/nullForOptionalOrElse.kt new file mode 100644 index 00000000000..e27ded0f05b --- /dev/null +++ b/compiler/testData/diagnostics/testsWithJava8/nullForOptionalOrElse.kt @@ -0,0 +1,7 @@ +import java.util.* +import java.util.stream.Stream + +fun Stream?.getIfSingle() = + this?.map { Optional.ofNullable(it) } + ?.reduce(Optional.empty()) { _, _ -> Optional.empty() } + ?.orElse(null) // <<---- should not be an error diff --git a/compiler/testData/diagnostics/testsWithJava8/nullForOptionalOrElse.txt b/compiler/testData/diagnostics/testsWithJava8/nullForOptionalOrElse.txt new file mode 100644 index 00000000000..fecbc90fedf --- /dev/null +++ b/compiler/testData/diagnostics/testsWithJava8/nullForOptionalOrElse.txt @@ -0,0 +1,3 @@ +package + +public fun java.util.stream.Stream?.getIfSingle(): T? diff --git a/compiler/tests-java8/tests/org/jetbrains/kotlin/checkers/DiagnosticsWithJava8TestGenerated.java b/compiler/tests-java8/tests/org/jetbrains/kotlin/checkers/DiagnosticsWithJava8TestGenerated.java index a73b51f2b73..a2e0435d6f7 100644 --- a/compiler/tests-java8/tests/org/jetbrains/kotlin/checkers/DiagnosticsWithJava8TestGenerated.java +++ b/compiler/tests-java8/tests/org/jetbrains/kotlin/checkers/DiagnosticsWithJava8TestGenerated.java @@ -48,6 +48,12 @@ public class DiagnosticsWithJava8TestGenerated extends AbstractDiagnosticsWithFu doTest(fileName); } + @TestMetadata("nullForOptionalOrElse.kt") + public void testNullForOptionalOrElse() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/testsWithJava8/nullForOptionalOrElse.kt"); + doTest(fileName); + } + @TestMetadata("samWithConsumer.kt") public void testSamWithConsumer() throws Exception { String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/testsWithJava8/samWithConsumer.kt"); diff --git a/core/descriptor.loader.java/src/org/jetbrains/kotlin/load/java/typeEnhancement/typeEnhancement.kt b/core/descriptor.loader.java/src/org/jetbrains/kotlin/load/java/typeEnhancement/typeEnhancement.kt index a63fa53e5a2..ae8d9af53d7 100644 --- a/core/descriptor.loader.java/src/org/jetbrains/kotlin/load/java/typeEnhancement/typeEnhancement.kt +++ b/core/descriptor.loader.java/src/org/jetbrains/kotlin/load/java/typeEnhancement/typeEnhancement.kt @@ -243,7 +243,8 @@ internal class NotNullTypeParameter(override val delegate: SimpleType) : CustomT } override fun replaceAnnotations(newAnnotations: Annotations) = NotNullTypeParameter(delegate.replaceAnnotations(newAnnotations)) - override fun makeNullableAsSpecified(newNullability: Boolean) = this + override fun makeNullableAsSpecified(newNullability: Boolean) = + if (newNullability) delegate.makeNullableAsSpecified(true) else this override val isError: Boolean get() = false