[FIR] Add regression tests for number of issues fixed in K2

List of issues:
KT-4113,  KT-6822,  KT-7389,  KT-17817, KT-20223
KT-21463, KT-24503, KT-24737, KT-24779, KT-24901
KT-27261, KT-28668, KT-30497, KT-30756, KT-36958
KT-37365, KT-37490, KT-38288, KT-41038, KT-41721
KT-42136, KT-42169, KT-42449, KT-42715, KT-43553
KT-43603, KT-43846, KT-43936, KT-46288, KT-46301
KT-47373, KT-47484, KT-47490, KT-47495, KT-47750
KT-47815, KT-47870, KT-48975, KT-49024, KT-49045
KT-50134, KT-50160, KT-50550, KT-51045, KT-51143
KT-51796, KT-52262, KT-52424, KT-52860, KT-52934
KT-53086, KT-53494, KT-53671, KT-53752, KT-53819
KT-54478, KT-54518, KT-54931, KT-54990, KT-55138
KT-55379, KT-55555, KT-56243
This commit is contained in:
Dmitriy Novozhilov
2023-02-10 11:31:10 +02:00
committed by Space Team
parent 8ae5213155
commit aef9b129d2
129 changed files with 4253 additions and 0 deletions
@@ -0,0 +1,40 @@
FILE: complexConflictingProjections.kt
public final class Foo : R|kotlin/Any| {
public constructor(): R|Foo| {
super<R|kotlin/Any|>()
}
}
public final class Bar<T1 : R|Foo|, out T2> : R|kotlin/Any| {
public constructor<T1 : R|Foo|, out T2>(): R|Bar<T1, T2>| {
super<R|kotlin/Any|>()
}
}
public final class Baz<T1, T2 : R|Bar<Foo, out T2>|> : R|kotlin/Any| {
public constructor<T1, T2 : R|Bar<Foo, out T2>|>(): R|Baz<T1, T2>| {
super<R|kotlin/Any|>()
}
}
public final class Qux<T1, T2 : R|Baz<T2, Bar<Foo, T2>>|> : R|kotlin/Any| {
public constructor<T1, T2 : R|Baz<T2, Bar<Foo, T2>>|>(f: R|T2|): R|Qux<T1, T2>| {
super<R|kotlin/Any|>()
}
public final var f: R|T2| = R|<local>/f|
public get(): R|T2|
public set(value: R|T2|): R|kotlin/Unit|
}
public final class Quux<T> : R|kotlin/Any| {
public constructor<T>(): R|Quux<T>| {
super<R|kotlin/Any|>()
}
public final fun test(): R|kotlin/Unit| {
lval x: R|Qux<in T, Baz<T, Bar<Foo, in T>>>| = Null(null)!!
R|<local>/x|.R|SubstitutionOverride</Qux.f: R|CapturedType(out Baz<T, out ERROR CLASS: Inconsistent type: Bar<Foo, in T> (1 parameter has declared variance: out, but argument variance is in)>)|>| = Null(null)!!
}
}
@@ -0,0 +1,13 @@
// ISSUE: KT-49024
class Foo
class Bar<T1: <!FINAL_UPPER_BOUND!>Foo<!>, out T2>
class Baz<T1, T2: Bar<Foo, out T2>>
class Qux<T1, T2: Baz<T2, <!UPPER_BOUND_VIOLATED!>Bar<Foo, T2><!>>>(var f: T2)
class Quux<T> {
fun test(): Unit {
val x: Qux<in T, <!UPPER_BOUND_VIOLATED!>Baz<T, <!UPPER_BOUND_VIOLATED!>Bar<Foo, <!CONFLICTING_PROJECTION!>in<!> T><!>><!>> = null!!
x.f = null!!
}
}
@@ -0,0 +1,9 @@
FILE: a.kt
@R|kotlin/RequiresOptIn|() public final annotation class MyOptIn : R|kotlin/Annotation| {
public constructor(): R|MyOptIn| {
super<R|kotlin/Any|>()
}
}
FILE: b.kt
package vvv
@@ -0,0 +1,10 @@
// ISSUE: KT-53671
// FILE: a.kt
@RequiresOptIn
annotation class MyOptIn
// FILE: b.kt
package vvv
import MyOptIn // OPT_IN_MARKER_CAN_ONLY_BE_USED_AS_ANNOTATION_OR_ARGUMENT_IN_OPT_IN
@@ -0,0 +1,17 @@
FILE: internalImplicitInvokeFromInlineFun.kt
public final class Test : R|kotlin/Any| {
public constructor(): R|Test| {
super<R|kotlin/Any|>()
}
internal final operator fun invoke(): R|Test| {
^invoke this@R|/Test|
}
}
public final inline fun testFunction(): R|Test| {
^testFunction R|/Test.Test|().R|/Test.invoke|()
}
public final inline fun testOperator(): R|Test| {
^testOperator R|/Test.Test|().R|/Test.invoke|()
}
@@ -0,0 +1,8 @@
// ISSUE: KT-20223
class Test {
internal operator fun invoke() = this
}
<!NOTHING_TO_INLINE!>inline<!> fun testFunction() = Test().<!NON_PUBLIC_CALL_FROM_PUBLIC_INLINE!>invoke<!>()
<!NOTHING_TO_INLINE!>inline<!> fun testOperator() = <!NON_PUBLIC_CALL_FROM_PUBLIC_INLINE!>Test()<!>()
@@ -0,0 +1,26 @@
FILE: internalSuperCallFromInlineFun.kt
public abstract class C : R|kotlin/Any| {
public constructor(): R|C| {
super<R|kotlin/Any|>()
}
internal final fun foo(x: R|kotlin/String|): R|kotlin/String| {
^foo R|<local>/x|
}
public abstract fun bar(): R|kotlin/String|
}
public final inline fun baz(crossinline block: R|() -> kotlin/String|): R|C| {
^baz object : R|C| {
private constructor(): R|<anonymous>| {
super<R|C|>()
}
public open override fun bar(): R|kotlin/String| {
^bar this@R|/<anonymous>|.R|/C.foo|(R|<local>/block|.R|SubstitutionOverride<kotlin/Function0.invoke: R|kotlin/String|>|())
}
}
}
@@ -0,0 +1,11 @@
// ISSUE: KT-54518
abstract class C {
internal fun foo(x: String) = x
abstract fun bar(): String
}
inline fun baz(crossinline block: () -> String) = object : C() {
override fun bar() = <!NON_PUBLIC_CALL_FROM_PUBLIC_INLINE!>foo<!>(block())
}
@@ -0,0 +1,4 @@
FILE: invalidLhsOfClassLiteral.kt
public final fun main(args: R|kotlin/Array<kotlin/String>|): R|kotlin/Unit| {
<getClass>(<Unresolved name: foo>#().<Unresolved name: Wrapper>#<*>)
}
@@ -0,0 +1,5 @@
// ISSUE: KT-17817
fun main(args: Array<String>) {
<!UNRESOLVED_REFERENCE!>foo<!>().Wrapper<<!PROJECTION_ON_NON_CLASS_TYPE_ARGUMENT!>*<!>>::class // no errors
}
@@ -0,0 +1,33 @@
FILE: notUselessCast_1.kt
public open class Base : R|kotlin/Any| {
public constructor(): R|Base| {
super<R|kotlin/Any|>()
}
}
public final class Derived : R|Base| {
public constructor(): R|Derived| {
super<R|Base|>()
}
}
public final fun test_0(d: R|Derived|): R|kotlin/Unit| {
local final fun take(d: R|Derived|): R|kotlin/Unit| {
}
R|<local>/take|((R|<local>/d| as R|Derived|))
}
public final fun test_1(): R|kotlin/Unit| {
lval list: R|kotlin/collections/MutableList<Base>| = R|kotlin/collections/listOf|<R|kotlin/Any|>().R|kotlin/collections/map|<R|kotlin/Any|, R|Base|>(<L> = map@fun <anonymous>(it: R|kotlin/Any|): R|Base| <inline=Inline, kind=UNKNOWN> {
^ (R|/Derived.Derived|() as R|Base|)
}
).R|kotlin/collections/toMutableList|<R|Base|>()
R|<local>/list|.R|SubstitutionOverride<kotlin/collections/MutableList.add: R|kotlin/Boolean|>|(R|/Base.Base|())
}
public final fun test_2(): R|kotlin/Unit| {
lval list: R|kotlin/collections/MutableList<Derived>| = R|kotlin/collections/listOf|<R|kotlin/Any|>().R|kotlin/collections/map|<R|kotlin/Any|, R|Derived|>(<L> = map@fun <anonymous>(it: R|kotlin/Any|): R|Derived| <inline=Inline, kind=UNKNOWN> {
^ R|/Derived.Derived|()
}
).R|kotlin/collections/toMutableList|<R|Derived|>()
R|<local>/list|.R|SubstitutionOverride<kotlin/collections/MutableList.add: R|kotlin/Boolean|><Inapplicable(INAPPLICABLE): kotlin/collections/MutableList.add>#|(R|/Base.Base|())
}
@@ -0,0 +1,20 @@
// ISSUE: KT-42136
// WITH_STDLIB
open class Base
class Derived : Base()
fun test_0(d: Derived) {
fun take(d: Derived) {}
take(d <!USELESS_CAST!>as Derived<!>) // should be USELESS_CAST
}
fun test_1() {
val list = listOf<Any>().map { Derived() as Base }.toMutableList() // should be no USELESS_CAST
list.add(Base())
}
fun test_2() {
val list = listOf<Any>().map { Derived() }.toMutableList()
list.add(<!ARGUMENT_TYPE_MISMATCH!>Base()<!>) // should be an error
}
@@ -0,0 +1,61 @@
FILE: notUselessCast_2.kt
public final data class Foo : R|kotlin/Any| {
public constructor(foo: R|kotlin/String|): R|Foo| {
super<R|kotlin/Any|>()
}
public final val foo: R|kotlin/String| = R|<local>/foo|
public get(): R|kotlin/String|
public final operator fun component1(): R|kotlin/String|
public final fun copy(foo: R|kotlin/String| = this@R|/Foo|.R|/Foo.foo|): R|Foo|
}
public final class Bar : R|kotlin/Any| {
public constructor(bar: R|kotlin/String|): R|Bar| {
super<R|kotlin/Any|>()
}
public final val bar: R|kotlin/String| = R|<local>/bar|
public get(): R|kotlin/String|
}
public final fun R|Bar|.toFoo(): R|Foo| {
^toFoo R|/Foo.Foo|(this@R|/toFoo|.R|/Bar.bar|)
}
public final class Wrapper<T> : R|kotlin/Any| {
public constructor<T>(wrapped: R|T|): R|Wrapper<T>| {
super<R|kotlin/Any|>()
}
public final val wrapped: R|T| = R|<local>/wrapped|
public get(): R|T|
public final fun <A> map(f: R|(T) -> A|): R|Wrapper<A>| {
^map R|/Wrapper.Wrapper|<R|A|>(R|<local>/f|.R|SubstitutionOverride<kotlin/Function1.invoke: R|A|>|(this@R|/Wrapper|.R|/Wrapper.wrapped|))
}
public final fun swapWrappedValue(f: R|(T) -> Wrapper<T>|): R|Wrapper<T>| {
^swapWrappedValue R|<local>/f|.R|SubstitutionOverride<kotlin/Function1.invoke: R|Wrapper<T>|>|(this@R|/Wrapper|.R|/Wrapper.wrapped|)
}
}
public final fun test_1(): R|Wrapper<Foo?>| {
^test_1 R|/Wrapper.Wrapper|<R|Bar|>(R|/Bar.Bar|(String(bar))).R|SubstitutionOverride</Wrapper.map: R|Wrapper<A>|>|<R|Foo?|>(<L> = map@fun <anonymous>(it: R|Bar|): R|Foo?| <inline=NoInline> {
^ (R|<local>/it|.R|/toFoo|() as R|Foo?|)
}
).R|SubstitutionOverride</Wrapper.swapWrappedValue: R|Wrapper<Foo?>|>|(<L> = swapWrappedValue@fun <anonymous>(it: R|Foo?|): R|Wrapper<Foo?>| <inline=NoInline> {
^ R|/Wrapper.Wrapper|<R|Foo?|>(Null(null))
}
)
}
public final fun test_2(): R|Wrapper<Foo?>| {
^test_2 R|/Wrapper.Wrapper|<R|Bar|>(R|/Bar.Bar|(String(bar))).R|SubstitutionOverride</Wrapper.map: R|Wrapper<A>|>|<R|Foo|>(<L> = map@fun <anonymous>(it: R|Bar|): R|Foo| <inline=NoInline> {
^ R|<local>/it|.R|/toFoo|()
}
).R|SubstitutionOverride</Wrapper.swapWrappedValue: R|Wrapper<Foo>|><CS errors: /Wrapper.swapWrappedValue>#|(<L> = swapWrappedValue@fun <anonymous>(it: R|Foo|): R|Wrapper<Foo>| <inline=NoInline> {
^ R|/Wrapper.Wrapper<CS errors: /Wrapper.Wrapper>#|<R|Foo|>(Null(null))
}
)
}
@@ -0,0 +1,23 @@
// ISSUE: KT-49045
data class Foo(val foo: String)
class Bar(val bar: String)
fun Bar.toFoo() = Foo(bar)
class Wrapper<T>(val wrapped: T) {
fun <A> map(f: (T) -> A): Wrapper<A> = Wrapper(f(wrapped))
fun swapWrappedValue(f: (T) -> Wrapper<T>): Wrapper<T> = f(wrapped)
}
fun test_1(): Wrapper<Foo?> {
return Wrapper(Bar("bar"))
.map { it.toFoo() as Foo? }
.swapWrappedValue { Wrapper(null) }
}
fun test_2(): Wrapper<Foo?> {
return <!RETURN_TYPE_MISMATCH!>Wrapper(Bar("bar"))
.map { it.toFoo() }
.swapWrappedValue { <!TYPE_MISMATCH, TYPE_MISMATCH!>Wrapper(null)<!> }<!>
}
@@ -0,0 +1,43 @@
FILE: notUselessCast_3.kt
public sealed interface Square : R|kotlin/Any| {
}
public final object MARKED : R|Square| {
private constructor(): R|MARKED| {
super<R|kotlin/Any|>()
}
}
public final object UNMARKED : R|Square| {
private constructor(): R|UNMARKED| {
super<R|kotlin/Any|>()
}
}
public final fun test_1(): R|kotlin/Unit| {
lval lines: R|kotlin/collections/List<kotlin/String>| = R|kotlin/collections/listOf|<R|kotlin/String|>()
lval cards: R|kotlin/collections/List<kotlin/collections/List<kotlin/collections/MutableList<Square>>>| = R|<local>/lines|.R|kotlin/collections/windowed|<R|kotlin/String|>(Int(6)).R|kotlin/collections/map|<R|kotlin/collections/List<kotlin/String>|, R|kotlin/collections/List<kotlin/collections/MutableList<Square>>|>(<L> = map@fun <anonymous>(card: R|kotlin/collections/List<kotlin/String>|): R|kotlin/collections/List<kotlin/collections/MutableList<Square>>| <inline=Inline, kind=UNKNOWN> {
^ R|<local>/card|.R|kotlin/collections/map|<R|kotlin/String|, R|kotlin/collections/MutableList<Square>|>(<L> = map@fun <anonymous>(line: R|kotlin/String|): R|kotlin/collections/MutableList<Square>| <inline=Inline, kind=UNKNOWN> {
^ R|<local>/line|.R|kotlin/text/map|<R|Square|>(<L> = map@fun <anonymous>(it: R|kotlin/Char|): R|Square| <inline=Inline, kind=UNKNOWN> {
^ (Q|UNMARKED| as R|Square|)
}
).R|kotlin/collections/toMutableList|<R|Square|>()
}
)
}
)
R|<local>/cards|.R|SubstitutionOverride<kotlin/collections/List.get: R|kotlin/collections/List<kotlin/collections/MutableList<Square>>|>|(Int(0)).R|SubstitutionOverride<kotlin/collections/List.get: R|kotlin/collections/MutableList<Square>|>|(Int(0)).R|SubstitutionOverride<kotlin/collections/MutableList.set: R|Square|>|(Int(0), Q|MARKED|)
}
public final fun test_2(): R|kotlin/Unit| {
lval lines: R|kotlin/collections/List<kotlin/String>| = R|kotlin/collections/listOf|<R|kotlin/String|>()
lval cards: R|kotlin/collections/List<kotlin/collections/List<kotlin/collections/MutableList<UNMARKED>>>| = R|<local>/lines|.R|kotlin/collections/windowed|<R|kotlin/String|>(Int(6)).R|kotlin/collections/map|<R|kotlin/collections/List<kotlin/String>|, R|kotlin/collections/List<kotlin/collections/MutableList<UNMARKED>>|>(<L> = map@fun <anonymous>(card: R|kotlin/collections/List<kotlin/String>|): R|kotlin/collections/List<kotlin/collections/MutableList<UNMARKED>>| <inline=Inline, kind=UNKNOWN> {
^ R|<local>/card|.R|kotlin/collections/map|<R|kotlin/String|, R|kotlin/collections/MutableList<UNMARKED>|>(<L> = map@fun <anonymous>(line: R|kotlin/String|): R|kotlin/collections/MutableList<UNMARKED>| <inline=Inline, kind=UNKNOWN> {
^ R|<local>/line|.R|kotlin/text/map|<R|UNMARKED|>(<L> = map@fun <anonymous>(it: R|kotlin/Char|): R|UNMARKED| <inline=Inline, kind=UNKNOWN> {
^ Q|UNMARKED|
}
).R|kotlin/collections/toMutableList|<R|UNMARKED|>()
}
)
}
)
R|<local>/cards|.R|SubstitutionOverride<kotlin/collections/List.get: R|kotlin/collections/List<kotlin/collections/MutableList<UNMARKED>>|>|(Int(0)).R|SubstitutionOverride<kotlin/collections/List.get: R|kotlin/collections/MutableList<UNMARKED>|>|(Int(0)).R|SubstitutionOverride<kotlin/collections/MutableList.set: R|UNMARKED|><Inapplicable(INAPPLICABLE): kotlin/collections/MutableList.set>#|(Int(0), Q|MARKED|)
}
@@ -0,0 +1,30 @@
// ISSUE: KT-50160
// WITH_STDLIB
sealed interface Square
object MARKED : Square
object UNMARKED : Square
fun test_1() {
val lines: List<String> = listOf()
val cards = lines.windowed(6)
.map { card ->
card.map { line: String ->
line.map { UNMARKED as Square }
.toMutableList()
}
}
cards[0][0][0] = MARKED
}
fun test_2() {
val lines: List<String> = listOf()
val cards = lines.windowed(6)
.map { card ->
card.map { line: String ->
line.map { UNMARKED }
.toMutableList()
}
}
cards[0][0][0] = <!ARGUMENT_TYPE_MISMATCH!>MARKED<!>
}
@@ -0,0 +1,19 @@
FILE: recursiveDependencyBetweenReturnTypeAndSupertype.kt
public abstract interface A : R|Test| {
}
public open class Test : R|kotlin/Any| {
public constructor(): R|Test| {
super<R|kotlin/Any|>()
}
public final fun <T> result(): R|A| {
^result object : R|A| {
private constructor(): R|<anonymous><T>| {
super<R|kotlin/Any|>()
}
}
}
}
@@ -0,0 +1,7 @@
// ISSUE: KT-47815
interface A : <!INTERFACE_WITH_SUPERCLASS!>Test<!>
open class Test {
fun <T> result() = object : A { }
}
@@ -0,0 +1,22 @@
FILE: unsuccessfullCastToStartProjectedType.kt
public open class Foo<T> : R|kotlin/Any| {
public constructor<T>(): R|Foo<T>| {
super<R|kotlin/Any|>()
}
}
public final class Foo1<A> : R|Foo<kotlin/Int>| {
public constructor<A>(): R|Foo1<A>| {
super<R|Foo<kotlin/Int>|>()
}
}
public final class Foo2 : R|Foo<kotlin/Int>| {
public constructor(): R|Foo2| {
super<R|Foo<kotlin/Int>|>()
}
}
public final fun process(foo: R|Foo<kotlin/Long>|): R|kotlin/Unit| {
(R|<local>/foo| as R|Foo1<*>|)
}
@@ -0,0 +1,9 @@
// ISSUE: KT-42169
open class Foo<T>
class Foo1<A> : Foo<Int>()
class Foo2 : Foo<Int>()
fun process(foo: Foo<Long>) {
foo <!CAST_NEVER_SUCCEEDS!>as<!> Foo1<*>
}
@@ -0,0 +1,53 @@
FILE: uselessCastLeadsToRecursiveProblem.kt
public abstract interface A : R|kotlin/Any| {
}
public final class B : R|A| {
public constructor(): R|B| {
super<R|kotlin/Any|>()
}
}
public open class C : R|A| {
public constructor(): R|C| {
super<R|kotlin/Any|>()
}
}
public final val <T : R|C|> R|kotlin/reflect/KClass<T>|.extProp1: R|kotlin/String|
public get(): R|kotlin/String| {
^ String(I'm C)
}
public final val R|A|.extProp1: R|kotlin/String|
public get(): R|kotlin/String| {
^ when (this@R|/extProp1|) {
($subj$ is R|B|) -> {
String(I'm B)
}
($subj$ is R|C|) -> {
<getClass>((this@R|/extProp1| as R|C|)).R|/extProp1|<R|CapturedType(out C)|>
}
else -> {
String(I don't know who I am..)
}
}
}
public final val <T : R|C|> R|kotlin/reflect/KClass<T>|.extProp2: R|kotlin/String|
public get(): R|kotlin/String| {
^ String(I'm C)
}
public final val R|A|.extProp2: R|kotlin/String|
public get(): R|kotlin/String| {
^ when (this@R|/extProp2|) {
($subj$ is R|B|) -> {
String(I'm B)
}
($subj$ is R|C|) -> {
<getClass>(this@R|/extProp2|).R|/extProp2|<R|CapturedType(out C)|>
}
else -> {
String(I don't know who I am..)
}
}
}
@@ -0,0 +1,27 @@
// ISSUE: KT-43603
import kotlin.reflect.KClass
interface A
class B : A
open class C : A
val <T : C> KClass<T>.extProp1
get() = "I'm C"
val A.extProp1
get() = when (this) {
is B -> "I'm B"
is C -> (this <!USELESS_CAST!>as C<!>)::class.extProp1
else -> "I don't know who I am.."
}
val <T : C> KClass<T>.extProp2
get() = "I'm C"
val A.extProp2
get() = when (this) {
is B -> "I'm B"
is C -> this::class.extProp2
else -> "I don't know who I am.."
}