[NI] Discriminate Nothing? result type from nullability constraints

Nullability constraints should not be chosen when proper
argument constraints for variables in contravariant position present.

^KT-32106 Fixed
^KT-33166 Fixed
This commit is contained in:
Pavel Kirpichenkov
2019-12-24 14:51:39 +03:00
parent a1ad680edb
commit 7ee71450bc
23 changed files with 154 additions and 35 deletions
@@ -0,0 +1,15 @@
// !LANGUAGE: +NewInference
// !DIAGNOSTICS: -UNUSED_PARAMETER
open class Cls
abstract class In<in I>
class SubIn : In<Cls?>()
inline fun <reified T : Cls> materialize(): T? = TODO()
fun <D> transform(transformer: In<D>, data: D): Unit = TODO()
fun test(subIn: SubIn) {
transform(subIn, materialize()) // D should be inferred to Cls?, not Nothing?
}
@@ -0,0 +1,15 @@
// !LANGUAGE: +NewInference
// !DIAGNOSTICS: -UNUSED_PARAMETER
open class Cls
abstract class In<in I>
class SubIn : In<Cls?>()
inline fun <reified T : Cls> materialize(): T? = TODO()
fun <D> transform(transformer: In<D>, data: D): Unit = TODO()
fun test(subIn: SubIn) {
transform(subIn, materialize()) // D should be inferred to Cls?, not Nothing?
}
@@ -0,0 +1,26 @@
package
public inline fun </*0*/ reified T : Cls> materialize(): T?
public fun test(/*0*/ subIn: SubIn): kotlin.Unit
public fun </*0*/ D> transform(/*0*/ transformer: In<D>, /*1*/ data: D): kotlin.Unit
public open class Cls {
public constructor Cls()
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
}
public abstract class In</*0*/ in I> {
public constructor In</*0*/ in I>()
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
}
public final class SubIn : In<Cls?> {
public constructor SubIn()
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
}
@@ -0,0 +1,3 @@
fun <K> id(arg: K): K = arg
val v = id(null)
@@ -0,0 +1,3 @@
fun <K> id(arg: K): K = arg
val v = <!DEBUG_INFO_EXPRESSION_TYPE("kotlin.Nothing?")!>id(null)<!>
@@ -0,0 +1,4 @@
package
public val v: kotlin.Nothing?
public fun </*0*/ K> id(/*0*/ arg: K): K
@@ -0,0 +1,12 @@
// !DIAGNOSTICS: -UNUSED_PARAMETER -UNUSED_EXPRESSION -ASSIGNED_BUT_NEVER_ACCESSED_VARIABLE -UNUSED_VALUE
class Out<out T : Any>(result: T?)
fun main() {
val a = Out(null)
a
var b: Out<Int>? = null
b = a
}
@@ -1,5 +1,3 @@
// !LANGUAGE: +NewInference
class Query<out T : Any> private constructor(
private val result: T?,
private val error: Throwable?,
@@ -1,5 +1,3 @@
// !LANGUAGE: +NewInference
class Query<out T : Any> private constructor(
private val result: T?,
private val error: Throwable?,
@@ -36,7 +36,6 @@ fun testOK(first: First, bound: Bound, second: Second) {
strictSelect(OutB(first), OutB(bound))
strictSelect(In(first), In(bound))
strictSelect(InB(first), InB(bound))
strictSelect(InB(first), InB(second)) // different behaviour in contravariant position
val out: Out<Bound> = strictSelect(Out(first), Out(second))
val outb: OutB<Bound> = strictSelect(OutB(first), OutB(second))
@@ -49,6 +48,7 @@ fun testFail(first: First, bound: Bound, second: Second) {
strictSelect(Inv(first), Inv(bound))
strictSelect(Out(first), Out(second))
strictSelect(In(first), In(second))
strictSelect(InB(first), InB(second))
strictSelect(Out(Inv(first)), Out(Inv(second)))
strictSelect(In(Inv(first)), In(Inv(second)))
}
@@ -36,7 +36,6 @@ fun testOK(first: First, bound: Bound, second: Second) {
strictSelect(OutB(first), OutB(bound))
strictSelect(In(first), In(bound))
strictSelect(InB(first), InB(bound))
<!OI;TYPE_INFERENCE_ONLY_INPUT_TYPES!>strictSelect<!>(InB(first), InB(second)) // different behaviour in contravariant position
val out: Out<Bound> = strictSelect(Out(first), Out(second))
val outb: OutB<Bound> = strictSelect(OutB(first), OutB(second))
@@ -49,6 +48,7 @@ fun testFail(first: First, bound: Bound, second: Second) {
<!TYPE_INFERENCE_ONLY_INPUT_TYPES!>strictSelect<!>(Inv(first), Inv(bound))
<!TYPE_INFERENCE_ONLY_INPUT_TYPES!>strictSelect<!>(Out(first), Out(second))
<!TYPE_INFERENCE_ONLY_INPUT_TYPES!>strictSelect<!>(In(first), In(second))
<!TYPE_INFERENCE_ONLY_INPUT_TYPES!>strictSelect<!>(InB(first), InB(second))
<!TYPE_INFERENCE_ONLY_INPUT_TYPES!>strictSelect<!>(Out(Inv(first)), Out(Inv(second)))
<!TYPE_INFERENCE_ONLY_INPUT_TYPES!>strictSelect<!>(In(Inv(first)), In(Inv(second)))
}
@@ -27,7 +27,7 @@ fun test1(): Map<Int, Int> = run {
}
fun test2(): Map<Int, Int> = run {
<!NI;TYPE_MISMATCH, NI;TYPE_MISMATCH, NI;TYPE_MISMATCH, NI;TYPE_MISMATCH, NI;TYPE_MISMATCH, NI;TYPE_MISMATCH, NI;TYPE_MISMATCH, NI;TYPE_MISMATCH!>try {
<!NI;TYPE_MISMATCH, NI;TYPE_MISMATCH, NI;TYPE_MISMATCH, NI;TYPE_MISMATCH, NI;TYPE_MISMATCH, NI;TYPE_MISMATCH!>try {
emptyMap()
} catch (e: ExcA) {
<!NI;TYPE_MISMATCH, NI;TYPE_MISMATCH, OI;TYPE_INFERENCE_EXPECTED_TYPE_MISMATCH!>mapOf(<!NI;TYPE_MISMATCH, NI;TYPE_MISMATCH!>"" to ""<!>)<!>