[FIR] Report errors for upper bounded type variables by an empty intersection type
^KT-51221 Fixed
This commit is contained in:
committed by
teamcity
parent
65213e9a42
commit
c16ae81a48
Vendored
+1
-1
@@ -47,7 +47,7 @@ fun test(i: Inv<Nothing>, iUnit: Inv<Unit>) {
|
||||
|
||||
if (iUnit is String) {
|
||||
launch {
|
||||
run(A.flexible(iUnit)) { 42 }
|
||||
run(A.<!INFERRED_TYPE_VARIABLE_INTO_EMPTY_INTERSECTION!>flexible<!>(iUnit)) { 42 }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+21
@@ -0,0 +1,21 @@
|
||||
// RENDER_DIAGNOSTICS_FULL_TEXT
|
||||
// !LANGUAGE: +NewInference
|
||||
// !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))
|
||||
}
|
||||
+2
-2
@@ -11,7 +11,7 @@ object Scope {
|
||||
fun <T : Comparable<T>, S : T> greater(x: Bar<in S>, t: T) {}
|
||||
|
||||
fun test(b: Bar<Long>) {
|
||||
<!DEBUG_INFO_CALL("fqName: Scope.Nested.greater; typeCall: function")!>greater(b, b)<!>
|
||||
<!DEBUG_INFO_CALL("fqName: Scope.greater; typeCall: function")!>greater(b, b)<!>
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -20,7 +20,7 @@ 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")!>greater(b, b)<!>
|
||||
<!DEBUG_INFO_CALL("fqName: fqName is unknown; typeCall: unresolved")!><!INFERRED_TYPE_VARIABLE_INTO_EMPTY_INTERSECTION!>greater<!>(b, b)<!>
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Vendored
+4
-4
@@ -164,10 +164,10 @@ fun main() {
|
||||
select({ x, y -> x.inv() + y.toByte() }, id { x: Int, y -> y.toByte() }, id { x, y: Number -> x.inv() })
|
||||
|
||||
// Inferring lambda parameter types by other specified lambda parameters; expected type is a functional type with type variables in parameter types
|
||||
takeLambdas({ <!DEBUG_INFO_EXPRESSION_TYPE("kotlin.Nothing")!>it<!> }, { x: Int -> }, { x: Nothing -> x })
|
||||
takeLambdas({ <!DEBUG_INFO_EXPRESSION_TYPE("kotlin.Nothing")!>it<!> }, { } as (Int) -> Unit, { x: Nothing -> x })
|
||||
takeLambdas({ <!DEBUG_INFO_EXPRESSION_TYPE("kotlin.Nothing")!>it<!> }, { } as (Nothing) -> Unit, { x: Int -> x })
|
||||
takeLambdas({ <!DEBUG_INFO_EXPRESSION_TYPE("kotlin.Nothing")!>it<!> }, { } as (Int) -> Unit, { } as (Nothing) -> Unit)
|
||||
<!INFERRED_TYPE_VARIABLE_INTO_EMPTY_INTERSECTION!>takeLambdas<!>({ <!DEBUG_INFO_EXPRESSION_TYPE("kotlin.Nothing")!>it<!> }, { x: Int -> }, { x: Nothing -> x })
|
||||
<!INFERRED_TYPE_VARIABLE_INTO_EMPTY_INTERSECTION!>takeLambdas<!>({ <!DEBUG_INFO_EXPRESSION_TYPE("kotlin.Nothing")!>it<!> }, { } as (Int) -> Unit, { x: Nothing -> x })
|
||||
<!INFERRED_TYPE_VARIABLE_INTO_EMPTY_INTERSECTION!>takeLambdas<!>({ <!DEBUG_INFO_EXPRESSION_TYPE("kotlin.Nothing")!>it<!> }, { } as (Nothing) -> Unit, { x: Int -> x })
|
||||
<!INFERRED_TYPE_VARIABLE_INTO_EMPTY_INTERSECTION!>takeLambdas<!>({ <!DEBUG_INFO_EXPRESSION_TYPE("kotlin.Nothing")!>it<!> }, { } as (Int) -> Unit, { } as (Nothing) -> Unit)
|
||||
|
||||
// Inferring lambda parameter types by other specified lambda parameters; expected type is a functional type with type variables in parameter types; dependent type parameters
|
||||
takeLambdasWithDirectlyDependentTypeParameters({ <!DEBUG_INFO_EXPRESSION_TYPE("kotlin.Int")!>it<!> }, { <!DEBUG_INFO_EXPRESSION_TYPE("kotlin.Int")!>it<!> }, { x: Int -> x })
|
||||
|
||||
Vendored
-13
@@ -1,13 +0,0 @@
|
||||
// !DIAGNOSTICS: -UNUSED_PARAMETER -UNUSED_EXPRESSION
|
||||
|
||||
abstract class Foo<T>
|
||||
|
||||
abstract class Bar<T> : Foo<T>(), Comparable<Bar<T>>
|
||||
|
||||
fun <T : Comparable<T>, S : T> greater(x: Bar<in S>, t: T): Int = 0
|
||||
fun <T : Comparable<T>, S : T> greater(x: Bar<in S>, other: Foo<T>): String = ""
|
||||
|
||||
fun test(b: Bar<Long>) {
|
||||
val result = <!OVERLOAD_RESOLUTION_AMBIGUITY!>greater<!>(b, b)
|
||||
<!DEBUG_INFO_EXPRESSION_TYPE("ERROR CLASS: Ambiguity: greater, [/greater, /greater]")!>result<!>
|
||||
}
|
||||
+1
@@ -1,3 +1,4 @@
|
||||
// FIR_IDENTICAL
|
||||
// !DIAGNOSTICS: -UNUSED_PARAMETER -UNUSED_EXPRESSION
|
||||
|
||||
abstract class Foo<T>
|
||||
|
||||
@@ -0,0 +1,11 @@
|
||||
// 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
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
// 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()
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
// RENDER_DIAGNOSTICS_FULL_TEXT
|
||||
interface 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
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
// 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
-1
@@ -13,7 +13,7 @@ fun testElvis(a: Int?, b: Int?) {
|
||||
if (a != null) {
|
||||
doInt(b ?: a)
|
||||
}
|
||||
doList(getList() ?: emptyListOfA()) //should be an error
|
||||
<!INFERRED_TYPE_VARIABLE_INTO_EMPTY_INTERSECTION!>doList<!>(getList() ?: emptyListOfA()) //should be an error
|
||||
doList(getList() ?: strangeList { doInt(it) }) //lambda was not analyzed
|
||||
}
|
||||
|
||||
|
||||
+1
-1
@@ -12,7 +12,7 @@ fun <T: A> emptyNullableListOfA(): List<T>? = null
|
||||
//-------------------------------
|
||||
|
||||
fun testExclExcl() {
|
||||
doList(emptyNullableListOfA()!!) //should be an error here
|
||||
<!INFERRED_TYPE_VARIABLE_INTO_EMPTY_INTERSECTION!>doList<!>(emptyNullableListOfA()!!) //should be an error here
|
||||
val l: List<Int> = <!INITIALIZER_TYPE_MISMATCH, NEW_INFERENCE_ERROR!>id(emptyNullableListOfA()!!)<!>
|
||||
|
||||
doList(strangeNullableList { doInt(it) }!!) //lambda should be analyzed (at completion phase)
|
||||
|
||||
Reference in New Issue
Block a user