K2: support ForbidInferringTypeVariablesIntoEmptyIntersection on/off

This commit is contained in:
Mikhail Glukhikh
2023-02-28 09:40:19 +01:00
committed by Space Team
parent f7544aff62
commit b64cb67370
43 changed files with 86 additions and 248 deletions
@@ -27,7 +27,7 @@ fun test3() = run {
incompatibleI() // ? either uninferred T or error (Unit </: I)
}
fun test4() = <!INFERRED_TYPE_VARIABLE_INTO_EMPTY_INTERSECTION!>run<!> {
fun test4() = <!INFERRED_TYPE_VARIABLE_INTO_EMPTY_INTERSECTION_WARNING!>run<!> {
if (p) return@run
incompatibleC() // ? either uninferred T or error (Unit </: C)
}
@@ -47,7 +47,7 @@ fun test(i: Inv<Nothing>, iUnit: Inv<Unit>) {
if (iUnit is String) {
launch {
run(A.<!INFERRED_TYPE_VARIABLE_INTO_EMPTY_INTERSECTION!>flexible<!>(iUnit)) { 42 }
run(A.<!INFERRED_TYPE_VARIABLE_INTO_EMPTY_INTERSECTION_WARNING!>flexible<!>(iUnit)) { 42 }
}
}
}
@@ -1,37 +0,0 @@
// !DIAGNOSTICS: -UNUSED_PARAMETER -UNUSED_EXPRESSION
abstract class Foo<T>
abstract class Bar<T> : Foo<T>(), Comparable<Bar<T>>
object Scope {
fun <T : Comparable<T>, S : T> greater(x: Bar<in S>, other: Foo<T>) {}
object Nested {
fun <T : Comparable<T>, S : T> greater(x: Bar<in S>, t: T) {}
fun test(b: Bar<Long>) {
<!DEBUG_INFO_CALL("fqName: Scope.greater; typeCall: function")!>greater(b, b)<!>
}
}
}
object OnlyOne {
fun <T : Comparable<T>, S : T> greater(x: Bar<in S>, t: T) {}
fun test(b: Bar<Long>) {
<!DEBUG_INFO_CALL("fqName: OnlyOne.greater; typeCall: function")!><!INFERRED_TYPE_VARIABLE_INTO_EMPTY_INTERSECTION!>greater<!>(b, b)<!>
}
}
object GoodOldCandidate {
fun <T : Comparable<T>, S : T> greater(x: Bar<in S>, t: T) {}
object Nested {
fun <T : Comparable<T>, S : T> greater(x: Bar<in S>, other: Foo<T>) {}
fun test(b: Bar<Long>) {
<!DEBUG_INFO_CALL("fqName: GoodOldCandidate.Nested.greater; typeCall: function")!>greater(b, b)<!>
}
}
}
@@ -1,3 +1,4 @@
// FIR_IDENTICAL
// !DIAGNOSTICS: -UNUSED_PARAMETER -UNUSED_EXPRESSION
abstract class Foo<T>
@@ -1,11 +0,0 @@
// RENDER_DIAGNOSTICS_FULL_TEXT
class Foo<T>
class Bar<T> {
fun <S : T> takeFoo(foo: Foo<in S>) {}
}
fun main() {
val foo = Foo<Int>()
Bar<String>().<!INFERRED_TYPE_VARIABLE_INTO_EMPTY_INTERSECTION!>takeFoo<!>(foo) // error in 1.3.72, no error in 1.4.31
}
@@ -1,3 +1,4 @@
// FIR_IDENTICAL
// RENDER_DIAGNOSTICS_FULL_TEXT
class Foo<T>
@@ -1,13 +0,0 @@
// RENDER_DIAGNOSTICS_FULL_TEXT
class Foo<T>
class Bar<T> {
fun <S : T> takeFoo(foo: Foo<in S>) {}
}
interface A
fun <K : L, L : N, N> main() where N: A, N: Number {
val foo = Foo<K>()
Bar<String>().<!INFERRED_TYPE_VARIABLE_INTO_EMPTY_INTERSECTION!>takeFoo<!>(foo) // error in 1.3.72, no error in 1.4.31
}
@@ -1,3 +1,4 @@
// FIR_IDENTICAL
// RENDER_DIAGNOSTICS_FULL_TEXT
class Foo<T>
@@ -1,11 +0,0 @@
// RENDER_DIAGNOSTICS_FULL_TEXT
class Foo<T>
class Bar<T> {
fun <S : T> takeFoo(foo: Foo<in S>) {}
}
fun <K : <!FINAL_UPPER_BOUND!>Int<!>> main() {
val foo = Foo<K>()
Bar<String>().<!INFERRED_TYPE_VARIABLE_INTO_EMPTY_INTERSECTION!>takeFoo<!>(foo) // error in 1.3.72, no error in 1.4.31
}
@@ -1,3 +1,4 @@
// FIR_IDENTICAL
// RENDER_DIAGNOSTICS_FULL_TEXT
class Foo<T>
@@ -8,5 +8,5 @@ class Bar<T> {
fun <K : L, L : N, N: <!FINAL_UPPER_BOUND!>Int<!>> main() {
val foo = Foo<K>()
val x: Float = Bar<String>().<!INFERRED_TYPE_VARIABLE_INTO_EMPTY_INTERSECTION("S; kotlin/String, K; multiple incompatible classes; : kotlin/String, kotlin/Int")!>takeFoo<!>(foo) // error in 1.3.72, no error in 1.4.31
val x: Float = Bar<String>().<!INFERRED_TYPE_VARIABLE_INTO_EMPTY_INTERSECTION_ERROR("S; kotlin/String, K; multiple incompatible classes; : kotlin/String, kotlin/Int")!>takeFoo<!>(foo) // error in 1.3.72, no error in 1.4.31
}
@@ -1,11 +0,0 @@
// RENDER_DIAGNOSTICS_FULL_TEXT
class Foo<T>
class Bar<T> {
fun <S : T> takeFoo(foo: Foo<in S>) {}
}
fun <K : L, L : N, N: Number> main() {
val foo = Foo<K>()
Bar<String>().<!INFERRED_TYPE_VARIABLE_INTO_EMPTY_INTERSECTION!>takeFoo<!>(foo) // error in 1.3.72, no error in 1.4.31
}
@@ -1,3 +1,4 @@
// FIR_IDENTICAL
// RENDER_DIAGNOSTICS_FULL_TEXT
class Foo<T>
@@ -1,17 +0,0 @@
// RENDER_DIAGNOSTICS_FULL_TEXT
open class A<T1, T2> {}
class B {
fun <T1: Number, T2: A<Float, T1>> foo(x1: T2, x2: T1) {}
}
class C<T: D, T2>(val x: T, val y: T2) {
fun test() {
B().<!INFERRED_TYPE_VARIABLE_INTO_EMPTY_INTERSECTION!>foo<!>(x, foo())
}
}
open class D: A<Float, Number>()
fun <T: <!FINAL_UPPER_BOUND!>String<!>> foo(): T {
return "" <!UNCHECKED_CAST!>as T<!> // this cast is safe because String is final.
}
fun main() {
C(D(), 10.5).test()
}
@@ -1,3 +1,4 @@
// FIR_IDENTICAL
// RENDER_DIAGNOSTICS_FULL_TEXT
open class A<T1, T2> {}
class B {
@@ -1,11 +0,0 @@
open class Base
open class DoesNotImplementBase
fun <T, V> exampleGenericFunction(func: V) where T: Base, V: (T) -> Unit {
}
fun main() {
val func: (DoesNotImplementBase) -> Unit = { }
<!INFERRED_TYPE_VARIABLE_INTO_EMPTY_INTERSECTION!>exampleGenericFunction<!>(func) // expected this to be a compilation error as the T: Base constraint should not be satisfied
}
@@ -1,3 +1,4 @@
// FIR_IDENTICAL
open class Base
open class DoesNotImplementBase
@@ -1,11 +0,0 @@
open class Base
class DoesNotImplementBase
fun <T, V> exampleGenericFunction(func: V) where T: Base, V: (T) -> Unit {
}
fun main() {
val func: (DoesNotImplementBase) -> Unit = { }
<!INFERRED_TYPE_VARIABLE_INTO_EMPTY_INTERSECTION!>exampleGenericFunction<!>(func) // expected this to be a compilation error as the T: Base constraint should not be satisfied
}
@@ -1,3 +1,4 @@
// FIR_IDENTICAL
open class Base
class DoesNotImplementBase
@@ -5,7 +5,7 @@ fun box(): String {
return try {
val range1 = 0..1
range1 <!CAST_NEVER_SUCCEEDS!>as<!> List<Double>
range1.<!INFERRED_TYPE_VARIABLE_INTO_EMPTY_INTERSECTION!>joinToString<!> { "" }
range1.<!INFERRED_TYPE_VARIABLE_INTO_EMPTY_INTERSECTION_WARNING!>joinToString<!> { "" }
} catch (e: java.lang.ClassCastException) {
"OK"
}
@@ -1,11 +0,0 @@
// RENDER_DIAGNOSTICS_FULL_TEXT
open class Foo
inline fun <reified T : Foo> g(): T? = null
inline fun <R> f(block: ()->R?): R? {
return block()
}
fun main() {
<!INFERRED_TYPE_VARIABLE_INTO_EMPTY_INTERSECTION!>f<!><Int> { g() }
}
@@ -1,3 +1,4 @@
// FIR_IDENTICAL
// RENDER_DIAGNOSTICS_FULL_TEXT
open class Foo
inline fun <reified T : Foo> g(): T? = null
@@ -1,7 +0,0 @@
fun <T : <!FINAL_UPPER_BOUND!>String<!>> g(): T? = null
fun <R> f(block: () -> R?): R? = block()
fun main() {
<!INFERRED_TYPE_VARIABLE_INTO_EMPTY_INTERSECTION!>f<!><Int> { g() /* OK, g() is inferred into {Int & String}? */ }
}
@@ -1,3 +1,4 @@
// FIR_IDENTICAL
fun <T : <!FINAL_UPPER_BOUND!>String<!>> g(): T? = null
fun <R> f(block: () -> R?): R? = block()
@@ -1,20 +0,0 @@
// RENDER_DIAGNOSTICS_FULL_TEXT
// !DIAGNOSTICS: -UNUSED_PARAMETER
class In<in T>
class Out<out T>
class A
class B
fun <K> select(x: K, y: K): K = x
fun <V> genericIn(x: In<V>) {}
fun <V> genericOut(x: Out<V>) {}
fun test1(a: In<A>, b: In<B>) {
<!INFERRED_TYPE_VARIABLE_INTO_EMPTY_INTERSECTION!>genericIn<!>(select(a, b))
}
fun test2(a: Out<A>, b: Out<B>) {
genericOut(select(a, b))
}
@@ -1,3 +1,4 @@
// FIR_IDENTICAL
// RENDER_DIAGNOSTICS_FULL_TEXT
// !DIAGNOSTICS: -UNUSED_PARAMETER