FIR: improve inference of implicit type arguments in casts
Type parameters do not necessarily match one-to-one, or preserve order.
This commit is contained in:
@@ -4,7 +4,7 @@ interface Tr
|
||||
interface G<T>
|
||||
|
||||
fun test(tr: Tr) {
|
||||
val v = tr as G?
|
||||
val v = tr as <!WRONG_NUMBER_OF_TYPE_ARGUMENTS!>G?<!>
|
||||
// If v is not nullable, there will be a warning on this line:
|
||||
checkSubtype<G<*>>(v!!)
|
||||
<!INAPPLICABLE_CANDIDATE!>checkSubtype<!><G<*>>(v!!)
|
||||
}
|
||||
@@ -1,18 +0,0 @@
|
||||
// !CHECK_TYPE
|
||||
|
||||
interface Either<out A, out B>
|
||||
interface Left<out A>: Either<A, Nothing>
|
||||
interface Right<out B>: Either<Nothing, B>
|
||||
|
||||
class C1(val v1: Int)
|
||||
class C2(val v2: Int)
|
||||
|
||||
fun _as_left(e: Either<C1, C2>): Any {
|
||||
val v = e as Left
|
||||
return checkSubtype<Left<C1>>(v)
|
||||
}
|
||||
|
||||
fun _as_right(e: Either<C1, C2>): Any {
|
||||
val v = e as Right
|
||||
return <!INAPPLICABLE_CANDIDATE!>checkSubtype<!><Right<C2>>(v)
|
||||
}
|
||||
@@ -1,3 +1,4 @@
|
||||
// FIR_IDENTICAL
|
||||
// !CHECK_TYPE
|
||||
|
||||
interface Either<out A, out B>
|
||||
|
||||
@@ -1,25 +0,0 @@
|
||||
// !DIAGNOSTICS: -DEBUG_INFO_SMARTCAST
|
||||
interface Either<out A, out B>
|
||||
interface Left<out A>: Either<A, Nothing> {
|
||||
val value: A
|
||||
}
|
||||
interface Right<out B>: Either<Nothing, B> {
|
||||
val value: B
|
||||
}
|
||||
|
||||
class C1(val v1: Int)
|
||||
class C2(val v2: Int)
|
||||
|
||||
fun _is_l(e: Either<C1, C2>): Any {
|
||||
if (e is Left) {
|
||||
return e.value.v1
|
||||
}
|
||||
return e
|
||||
}
|
||||
|
||||
fun _is_r(e: Either<C1, C2>): Any {
|
||||
if (e is Right) {
|
||||
return e.value.<!UNRESOLVED_REFERENCE!>v2<!>
|
||||
}
|
||||
return e
|
||||
}
|
||||
@@ -1,3 +1,4 @@
|
||||
// FIR_IDENTICAL
|
||||
// !DIAGNOSTICS: -DEBUG_INFO_SMARTCAST
|
||||
interface Either<out A, out B>
|
||||
interface Left<out A>: Either<A, Nothing> {
|
||||
|
||||
@@ -1,25 +0,0 @@
|
||||
// !DIAGNOSTICS: -DEBUG_INFO_SMARTCAST
|
||||
interface Either<out A, out B>
|
||||
interface Left<out A>: Either<A, Nothing> {
|
||||
val value: A
|
||||
}
|
||||
interface Right<out B>: Either<Nothing, B> {
|
||||
val value: B
|
||||
}
|
||||
|
||||
class C1(val v1: Int)
|
||||
class C2(val v2: Int)
|
||||
|
||||
fun _is_l(e: Either<C1, C2>): Any {
|
||||
if (e !is Left) {
|
||||
return e
|
||||
}
|
||||
return e.value.v1
|
||||
}
|
||||
|
||||
fun _is_r(e: Either<C1, C2>): Any {
|
||||
if (e !is Right) {
|
||||
return e
|
||||
}
|
||||
return e.value.<!UNRESOLVED_REFERENCE!>v2<!>
|
||||
}
|
||||
@@ -1,3 +1,4 @@
|
||||
// FIR_IDENTICAL
|
||||
// !DIAGNOSTICS: -DEBUG_INFO_SMARTCAST
|
||||
interface Either<out A, out B>
|
||||
interface Left<out A>: Either<A, Nothing> {
|
||||
|
||||
@@ -1,18 +0,0 @@
|
||||
// !CHECK_TYPE
|
||||
|
||||
interface Either<out A, out B>
|
||||
interface Left<out A>: Either<A, Nothing>
|
||||
interface Right<out B>: Either<Nothing, B>
|
||||
|
||||
class C1(val v1: Int)
|
||||
class C2(val v2: Int)
|
||||
|
||||
fun _as_left(e: Either<C1, C2>): Any? {
|
||||
val v = e as? Left
|
||||
return checkSubtype<Left<C1>?>(v)
|
||||
}
|
||||
|
||||
fun _as_right(e: Either<C1, C2>): Any? {
|
||||
val v = e as? Right
|
||||
return <!INAPPLICABLE_CANDIDATE!>checkSubtype<!><Right<C2>?>(v)
|
||||
}
|
||||
@@ -1,3 +1,4 @@
|
||||
// FIR_IDENTICAL
|
||||
// !CHECK_TYPE
|
||||
|
||||
interface Either<out A, out B>
|
||||
|
||||
@@ -1,19 +0,0 @@
|
||||
// !DIAGNOSTICS: -DEBUG_INFO_SMARTCAST
|
||||
interface Either<out A, out B>
|
||||
interface Left<out A>: Either<A, Nothing> {
|
||||
val value: A
|
||||
}
|
||||
interface Right<out B>: Either<Nothing, B> {
|
||||
val value: B
|
||||
}
|
||||
|
||||
class C1(val v1: Int)
|
||||
class C2(val v2: Int)
|
||||
|
||||
fun _when(e: Either<C1, C2>): Any {
|
||||
return when (e) {
|
||||
is Left -> e.value.v1
|
||||
is Right -> e.value.<!UNRESOLVED_REFERENCE!>v2<!>
|
||||
else -> e
|
||||
}
|
||||
}
|
||||
@@ -1,3 +1,4 @@
|
||||
// FIR_IDENTICAL
|
||||
// !DIAGNOSTICS: -DEBUG_INFO_SMARTCAST
|
||||
interface Either<out A, out B>
|
||||
interface Left<out A>: Either<A, Nothing> {
|
||||
|
||||
@@ -4,6 +4,6 @@ interface Tr
|
||||
interface G<T>
|
||||
|
||||
fun test(tr: Tr?) {
|
||||
val v = tr as G
|
||||
checkSubtype<G<*>>(v)
|
||||
val v = tr as <!WRONG_NUMBER_OF_TYPE_ARGUMENTS!>G<!>
|
||||
<!INAPPLICABLE_CANDIDATE!>checkSubtype<!><G<*>>(v)
|
||||
}
|
||||
+2
-2
@@ -4,6 +4,6 @@ interface Tr
|
||||
interface G<T>
|
||||
|
||||
fun test(tr: Tr?) {
|
||||
val v = tr as G?
|
||||
checkSubtype<G<*>>(v!!)
|
||||
val v = tr as <!WRONG_NUMBER_OF_TYPE_ARGUMENTS!>G?<!>
|
||||
<!INAPPLICABLE_CANDIDATE!>checkSubtype<!><G<*>>(v!!)
|
||||
}
|
||||
@@ -4,6 +4,6 @@ interface Tr
|
||||
interface G<T>
|
||||
|
||||
fun test(tr: Tr) {
|
||||
val v = tr as G
|
||||
checkSubtype<G<*>>(v)
|
||||
val v = tr as <!WRONG_NUMBER_OF_TYPE_ARGUMENTS!>G<!>
|
||||
<!INAPPLICABLE_CANDIDATE!>checkSubtype<!><G<*>>(v)
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
interface Tr
|
||||
interface G<T>
|
||||
|
||||
fun test(tr: Tr) = tr is G
|
||||
fun test(tr: Tr) = tr is <!WRONG_NUMBER_OF_TYPE_ARGUMENTS!>G<!>
|
||||
@@ -2,13 +2,13 @@ package p
|
||||
|
||||
public fun foo(a: Any) {
|
||||
a is Map<Int>
|
||||
a is Map
|
||||
a is <!WRONG_NUMBER_OF_TYPE_ARGUMENTS!>Map<!>
|
||||
a is Map<out Any?, Any?>
|
||||
a is Map<*, *>
|
||||
a is Map<<!SYNTAX!><!>>
|
||||
a is List<Map>
|
||||
a is List
|
||||
a is <!WRONG_NUMBER_OF_TYPE_ARGUMENTS!>List<!>
|
||||
a is Int
|
||||
|
||||
(a as Map) is Int
|
||||
(a as <!WRONG_NUMBER_OF_TYPE_ARGUMENTS!>Map<!>) is Int
|
||||
}
|
||||
@@ -1,12 +1,12 @@
|
||||
public fun foo(a: Any, b: Map) {
|
||||
when (a) {
|
||||
is Map<Int> -> {}
|
||||
is Map -> {}
|
||||
is <!WRONG_NUMBER_OF_TYPE_ARGUMENTS!>Map<!> -> {}
|
||||
is Map<out Any?, Any?> -> {}
|
||||
is Map<*, *> -> {}
|
||||
is Map<<!SYNTAX!><!>> -> {}
|
||||
is List<Map> -> {}
|
||||
is List -> {}
|
||||
is <!WRONG_NUMBER_OF_TYPE_ARGUMENTS!>List<!> -> {}
|
||||
is Int -> {}
|
||||
else -> {}
|
||||
}
|
||||
|
||||
+1
-1
@@ -8,7 +8,7 @@ class DerivedOuter<G> : SuperOuter<G>() {
|
||||
|
||||
fun bare(x: SuperOuter<*>.SuperInner<*>, y: Any?) {
|
||||
if (x is SuperOuter.SuperInner) return
|
||||
if (y is SuperOuter.SuperInner) {
|
||||
if (y is <!WRONG_NUMBER_OF_TYPE_ARGUMENTS!>SuperOuter.SuperInner<!>) {
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
+2
-2
@@ -12,7 +12,7 @@ class Outer<E> {
|
||||
x.prop.checkType { _<E>() }
|
||||
}
|
||||
|
||||
if (y is Inner) return
|
||||
if (y is <!WRONG_NUMBER_OF_TYPE_ARGUMENTS!>Inner<!>) return
|
||||
|
||||
if (z is Inner) {
|
||||
z.prop.checkType { _<Any?>() }
|
||||
@@ -26,7 +26,7 @@ class Outer<E> {
|
||||
|
||||
fun bar(x: InnerBase<String>, y: Any?, z: Outer<*>.InnerBase<String>) {
|
||||
x as Inner
|
||||
y as Inner
|
||||
y as <!WRONG_NUMBER_OF_TYPE_ARGUMENTS!>Inner<!>
|
||||
z as Inner
|
||||
}
|
||||
}
|
||||
|
||||
@@ -14,8 +14,8 @@ fun testNL1(x: Collection<Int>?): Boolean = x is NL
|
||||
fun testNL2(x: Collection<Int>?): List<Int>? = x as NL
|
||||
fun testNL3(x: Collection<Int>?): List<Int>? = x as NL?
|
||||
|
||||
fun testLStar(x: Collection<Int>): List<Int> = x as LStar
|
||||
fun testMyList(x: Collection<Int>): List<Int> = x as MyList
|
||||
fun testLStar(x: Collection<Int>): List<Int> = x as <!WRONG_NUMBER_OF_TYPE_ARGUMENTS!>LStar<!>
|
||||
fun testMyList(x: Collection<Int>): List<Int> = x as <!WRONG_NUMBER_OF_TYPE_ARGUMENTS!>MyList<!>
|
||||
|
||||
typealias MMTT<T> = MutableMap<T, T>
|
||||
typealias Dictionary<T> = MutableMap<String, T>
|
||||
@@ -24,8 +24,8 @@ typealias ReadableList<T> = MutableList<out T>
|
||||
|
||||
fun testWrong1(x: Map<Any, Any>) = x is MMTT
|
||||
fun testWrong2(x: Map<Any, Any>) = x is Dictionary
|
||||
fun testWrong3(x: Map<Any, Any>) = x is WriteableMap
|
||||
fun testWrong4(x: List<Any>) = x is ReadableList
|
||||
fun testWrong3(x: Map<Any, Any>) = x is <!WRONG_NUMBER_OF_TYPE_ARGUMENTS!>WriteableMap<!>
|
||||
fun testWrong4(x: List<Any>) = x is <!WRONG_NUMBER_OF_TYPE_ARGUMENTS!>ReadableList<!>
|
||||
|
||||
fun <T> testLocal(x: Any) {
|
||||
class C
|
||||
|
||||
Reference in New Issue
Block a user