K1: add more tests for BI assignment checker, fix corner cases

Related to KT-54004
This commit is contained in:
Mikhail Glukhikh
2022-10-25 13:24:19 +02:00
committed by Space Team
parent 87af855087
commit 50cd560d09
6 changed files with 151 additions and 8 deletions
@@ -9,8 +9,13 @@ fun main(arg: Any) {
val x = 57
val value = myBuilder {
doSmthng("one ")
a = <!ASSIGNMENT_TYPE_MISMATCH!>57<!>
run { a; this }.a = <!ASSIGNMENT_TYPE_MISMATCH!>10<!>
a += 1
this.a = <!ASSIGNMENT_TYPE_MISMATCH!>57<!>
this.(a) = 57
a = <!ASSIGNMENT_TYPE_MISMATCH!>x<!>
(a) = <!ASSIGNMENT_TYPE_MISMATCH!>x<!>
a.<!FUNCTION_CALL_EXPECTED!>hashCode<!> = 99
if (arg is String) {
a = arg
}
@@ -9,8 +9,13 @@ fun main(arg: Any) {
val x = 57
val value = myBuilder {
doSmthng("one ")
a = <!TYPE_MISMATCH!>57<!>
run { a; this }.a = <!TYPE_MISMATCH, TYPE_MISMATCH!>10<!>
<!BUILDER_INFERENCE_STUB_RECEIVER, STUB_TYPE_IN_RECEIVER_CAUSES_AMBIGUITY, TYPE_MISMATCH, TYPE_MISMATCH!>a<!> <!OVERLOAD_RESOLUTION_AMBIGUITY_BECAUSE_OF_STUB_TYPES!>+=<!> 1
this.a = <!TYPE_MISMATCH!>57<!>
this.<!ILLEGAL_SELECTOR, VARIABLE_EXPECTED!>(a)<!> = <!TYPE_MISMATCH!>57<!>
a = <!TYPE_MISMATCH!>x<!>
(a) = <!TYPE_MISMATCH!>x<!>
<!TYPE_MISMATCH!>a<!>.<!FUNCTION_CALL_EXPECTED, VARIABLE_EXPECTED!>hashCode<!> = <!TYPE_MISMATCH, TYPE_MISMATCH!>99<!>
if (arg is String) {
a = arg
}
@@ -1,4 +1,5 @@
// WITH_REFLECT
// FIR_DUMP
import kotlin.reflect.*
interface Foo<T : Any> {
@@ -57,4 +58,20 @@ fun main(arg: Any, condition: Boolean) {
a = <!ASSIGNMENT_TYPE_MISMATCH!>67<!>
}
}
// See KT-54664
val value3 = myBuilder {
accept("")
a = 45
bar(::a)
}
fun baz(t: Int) {}
val value4 = myBuilder {
accept("")
a = 45
b[0] = 123
baz(a)
}
}
@@ -0,0 +1,103 @@
FILE: unsafeAssignmentExtra.fir.kt
public abstract interface Foo<T : R|kotlin/Any|> : R|kotlin/Any| {
public abstract var a: R|T|
public get(): R|T|
public set(value: R|T|): R|kotlin/Unit|
public abstract val b: R|kotlin/Array<T>|
public get(): R|kotlin/Array<T>|
public abstract fun accept(arg: R|T|): R|kotlin/Unit|
}
public final class FooImpl<T : R|kotlin/Any|> : R|Foo<T>| {
public constructor<T : R|kotlin/Any|>(): R|FooImpl<T>| {
super<R|kotlin/Any|>()
}
}
public final fun bar(p: R|kotlin/reflect/KMutableProperty0<kotlin/Int>|): R|kotlin/Unit| {
R|<local>/p|.R|SubstitutionOverride<kotlin/reflect/KMutableProperty0.set: R|kotlin/Unit|>|(Int(100))
}
public final fun <T : R|kotlin/Any|> myBuilder(block: R|Foo<T>.() -> kotlin/Unit|): R|Foo<T>| {
^myBuilder R|/FooImpl.FooImpl|<R|T|>().R|kotlin/apply|<R|FooImpl<T>|>(R|<local>/block|)
}
public final fun <T : R|kotlin/Any|> R|Foo<T>|.change(block: R|Foo<T>.() -> kotlin/Unit|): R|Foo<T>| {
R|<local>/block|.R|SubstitutionOverride<kotlin/Function1.invoke: R|kotlin/Unit|>|(this@R|/change|)
^change this@R|/change|
}
public final fun main(arg: R|kotlin/Any|, condition: R|kotlin/Boolean|): R|kotlin/Unit| {
lval value: R|Foo<kotlin/Int>| = R|/myBuilder|<R|kotlin/Int|>(<L> = myBuilder@fun R|Foo<kotlin/Int>|.<anonymous>(): R|kotlin/Unit| <inline=NoInline> {
this@R|special/anonymous|.R|SubstitutionOverride</Foo.b: R|kotlin/Array<Stub (chain inference): TypeVariable(T)>|>|.R|SubstitutionOverride<kotlin/Array.set: R|kotlin/Unit|>|(Int(0), Int(123))
this@R|special/anonymous|.R|SubstitutionOverride</Foo.a: R|Stub (chain inference): TypeVariable(T)|>| = Int(45)
lval <unary>: R|kotlin/Int| = this@R|special/anonymous|.R|SubstitutionOverride</Foo.a: R|Stub (chain inference): TypeVariable(T)|>|
this@R|special/anonymous|.R|SubstitutionOverride</Foo.a: R|Stub (chain inference): TypeVariable(T)|>| = R|<local>/<unary>|.<Ambiguity: inc, [kotlin/inc, kotlin/inc]>#()
R|<local>/<unary>|
R|/bar|(::R|SubstitutionOverride</Foo.a: R|Stub (chain inference): TypeVariable(T)|>|)
when () {
(this@R|special/anonymous|.R|SubstitutionOverride</Foo.a: R|Stub (chain inference): TypeVariable(T)|>| is R|kotlin/Int|) -> {
this@R|special/anonymous|.R|SubstitutionOverride</Foo.a: R|Stub (chain inference): TypeVariable(T)|>| = Int(67)
lval <unary>: R|kotlin/Int| = this@R|special/anonymous|.R|SubstitutionOverride</Foo.a: R|Stub (chain inference): TypeVariable(T)|>|
this@R|special/anonymous|.R|SubstitutionOverride</Foo.a: R|Stub (chain inference): TypeVariable(T)|>| = R|<local>/<unary>|.<Ambiguity: dec, [kotlin/dec, kotlin/dec]>#()
R|<local>/<unary>|
R|/bar|(::R|SubstitutionOverride</Foo.a: R|Stub (chain inference): TypeVariable(T)|>|)
}
}
when (R|<local>/condition|) {
==($subj$, Boolean(true)) -> {
this@R|special/anonymous|.R|SubstitutionOverride</Foo.a: R|Stub (chain inference): TypeVariable(T)|>| = Int(87)
}
==($subj$, Boolean(false)) -> {
this@R|special/anonymous|.R|SubstitutionOverride</Foo.a: R|Stub (chain inference): TypeVariable(T)|>| = Int(65)
}
}
lval x: <ERROR TYPE REF: Ambiguity: getValue, [kotlin/getValue, kotlin/getValue, kotlin/getValue, kotlin/collections/getValue, kotlin/collections/getValue]>by this@R|special/anonymous|.R|SubstitutionOverride</Foo.a: R|Stub (chain inference): TypeVariable(T)|>|
this@R|special/anonymous|.R|/change|<R|kotlin/Int|>(<L> = change@fun R|Foo<kotlin/Int>|.<anonymous>(): R|kotlin/Unit| <inline=NoInline> {
this@R|special/anonymous|.R|SubstitutionOverride</Foo.a: R|Stub (chain inference): TypeVariable(T)|>| = Int(99)
}
)
}
)
lval value2: R|Foo<kotlin/String>| = R|/myBuilder|<R|kotlin/String|>(<L> = myBuilder@fun R|Foo<kotlin/String>|.<anonymous>(): R|kotlin/Unit| <inline=NoInline> {
this@R|special/anonymous|.R|SubstitutionOverride</Foo.accept: R|kotlin/Unit|>|(String())
this@R|special/anonymous|.R|SubstitutionOverride</Foo.a: R|Stub (chain inference): TypeVariable(T)|>| = Int(45)
when (R|<local>/condition|) {
==($subj$, Boolean(true)) -> {
this@R|special/anonymous|.R|SubstitutionOverride</Foo.a: R|Stub (chain inference): TypeVariable(T)|>| = Int(87)
}
==($subj$, Boolean(false)) -> {
this@R|special/anonymous|.R|SubstitutionOverride</Foo.a: R|Stub (chain inference): TypeVariable(T)|>| = Int(65)
}
}
this@R|special/anonymous|.R|/change|<R|kotlin/String|>(<L> = change@fun R|Foo<kotlin/String>|.<anonymous>(): R|kotlin/Unit| <inline=NoInline> {
this@R|special/anonymous|.R|SubstitutionOverride</Foo.a: R|Stub (chain inference): TypeVariable(T)|>| = Int(99)
}
)
when () {
(this@R|special/anonymous|.R|SubstitutionOverride</Foo.a: R|Stub (chain inference): TypeVariable(T)|>| is R|kotlin/Int|) -> {
this@R|special/anonymous|.R|SubstitutionOverride</Foo.a: R|Stub (chain inference): TypeVariable(T)|>| = Int(67)
}
}
}
)
lval value3: R|Foo<kotlin/Int>| = R|/myBuilder|<R|kotlin/Int|>(<L> = myBuilder@fun R|Foo<kotlin/Int>|.<anonymous>(): R|kotlin/Unit| <inline=NoInline> {
this@R|special/anonymous|.R|SubstitutionOverride</Foo.accept: R|kotlin/Unit|>|(String())
this@R|special/anonymous|.R|SubstitutionOverride</Foo.a: R|Stub (chain inference): TypeVariable(T)|>| = Int(45)
R|/bar|(::R|SubstitutionOverride</Foo.a: R|Stub (chain inference): TypeVariable(T)|>|)
}
)
local final fun baz(t: R|kotlin/Int|): R|kotlin/Unit| {
}
lval value4: R|Foo<it(kotlin/Comparable<*> & java/io/Serializable)>| = R|/myBuilder|<R|it(kotlin/Comparable<*> & java/io/Serializable)|>(<L> = myBuilder@fun R|Foo<it(kotlin/Comparable<*> & java/io/Serializable)>|.<anonymous>(): R|kotlin/Unit| <inline=NoInline> {
this@R|special/anonymous|.R|SubstitutionOverride</Foo.accept: R|kotlin/Unit|>|(String())
this@R|special/anonymous|.R|SubstitutionOverride</Foo.a: R|Stub (chain inference): TypeVariable(T)|>| = Int(45)
this@R|special/anonymous|.R|SubstitutionOverride</Foo.b: R|kotlin/Array<Stub (chain inference): TypeVariable(T)>|>|.R|SubstitutionOverride<kotlin/Array.set: R|kotlin/Unit|>|(Int(0), Int(123))
R|<local>/baz|(this@R|special/anonymous|.R|SubstitutionOverride</Foo.a: R|Stub (chain inference): TypeVariable(T)|>|)
}
)
}
@@ -1,4 +1,5 @@
// WITH_REFLECT
// FIR_DUMP
import kotlin.reflect.*
interface Foo<T : Any> {
@@ -57,4 +58,20 @@ fun main(arg: Any, condition: Boolean) {
a = <!TYPE_MISMATCH!>67<!>
}
}
// See KT-54664
val value3 = myBuilder {
accept(<!TYPE_MISMATCH!>""<!>)
a = 45
bar(<!TYPE_MISMATCH!>::a<!>)
}
fun baz(t: Int) {}
val value4 = myBuilder {
accept("")
a = 45
b[0] = 123
baz(<!TYPE_MISMATCH, TYPE_MISMATCH!>a<!>)
}
}