Fix false positive "Null can not be a value of a non-null type"

Inferred type of receiver of orElse  is Optional<T & Any>
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
This commit is contained in:
Denis Zharkov
2017-01-18 18:20:19 +03:00
parent 5d4f51d9b6
commit 4ab6b6954d
4 changed files with 18 additions and 1 deletions
@@ -0,0 +1,7 @@
import java.util.*
import java.util.stream.Stream
fun <T> Stream<T>?.getIfSingle() =
this?.map { Optional.ofNullable(it) }
?.reduce(Optional.empty()) { _, _ -> Optional.empty() }
?.orElse(null) // <<---- should not be an error
@@ -0,0 +1,3 @@
package
public fun </*0*/ T> java.util.stream.Stream<T>?.getIfSingle(): T?
@@ -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");
@@ -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