K2: Fix inference from assignment in PCLA

Before this, the order of the constraints being added was incorrect

^KT-64222 Fixed
This commit is contained in:
Denis.Zharkov
2024-01-11 11:28:52 +01:00
committed by Space Team
parent 97d17012e5
commit 8f9c09482b
6 changed files with 21 additions and 35 deletions
@@ -1035,7 +1035,8 @@ open class FirExpressionsResolveTransformer(transformer: FirAbstractBodyResolveT
// for cases like // for cases like
// buildSomething { tVar = "" // Should infer TV from String assignment } // buildSomething { tVar = "" // Should infer TV from String assignment }
context.inferenceSession.addSubtypeConstraintIfCompatible( context.inferenceSession.addSubtypeConstraintIfCompatible(
variableAssignment.lValue.resolvedType, variableAssignment.rValue.resolvedType, lowerType = variableAssignment.rValue.resolvedType,
upperType = variableAssignment.lValue.resolvedType,
variableAssignment, variableAssignment,
) )
@@ -27,14 +27,14 @@ fun test() {
var variable = getTypeVariable() var variable = getTypeVariable()
variable = TargetType() variable = TargetType()
variable.<!UNRESOLVED_REFERENCE!>targetTypeMemberFunction<!>() variable.<!UNRESOLVED_REFERENCE!>targetTypeMemberFunction<!>()
variable = <!ASSIGNMENT_TYPE_MISMATCH!>DifferentType()<!> variable = DifferentType()
variable.<!UNRESOLVED_REFERENCE!>targetTypeMemberFunction<!>() variable.<!UNRESOLVED_REFERENCE!>targetTypeMemberFunction<!>()
variable = TargetType() variable = TargetType()
variable.<!UNRESOLVED_REFERENCE!>targetTypeMemberFunction<!>() variable.<!UNRESOLVED_REFERENCE!>targetTypeMemberFunction<!>()
} }
// exact type equality check — turns unexpected compile-time behavior into red code // exact type equality check — turns unexpected compile-time behavior into red code
// considered to be non-user-reproducible code for the purposes of these tests // considered to be non-user-reproducible code for the purposes of these tests
checkExactType<Buildee<Any>>(<!ARGUMENT_TYPE_MISMATCH!>anyBuildee<!>) checkExactType<Buildee<Any>>(anyBuildee)
} }
@@ -1,16 +0,0 @@
// ISSUE: KT-64222
interface A {
fun bar(): B<Int>
}
interface B<T>
fun <E> foo(block: B<E>.() -> Unit): B<E> = TODO()
class C : A {
private var value: B<Int>? = null
override fun <!RETURN_TYPE_MISMATCH_ON_OVERRIDE!>bar<!>() = <!NEW_INFERENCE_NO_INFORMATION_FOR_PARAMETER!>foo<!> {
value = this
}
}
@@ -1,3 +1,4 @@
// FIR_IDENTICAL
// ISSUE: KT-64222 // ISSUE: KT-64222
interface A { interface A {
@@ -46,23 +46,23 @@ fun main(arg: Any, condition: Boolean) {
val value2 = myBuilder { val value2 = myBuilder {
accept("") accept("")
a = <!ASSIGNMENT_TYPE_MISMATCH!>45<!> a = 45
when (condition) { when (condition) {
true -> a = <!ASSIGNMENT_TYPE_MISMATCH!>87<!> true -> a = 87
false -> a = <!ASSIGNMENT_TYPE_MISMATCH!>65<!> false -> a = 65
} }
change { change {
a = <!ASSIGNMENT_TYPE_MISMATCH!>99<!> a = 99
} }
if (a is Int) { if (a is Int) {
a = <!ASSIGNMENT_TYPE_MISMATCH!>67<!> a = 67
} }
} }
// See KT-54664 // See KT-54664
val value3 = myBuilder { val value3 = myBuilder {
accept("") accept("")
a = <!ASSIGNMENT_TYPE_MISMATCH!>45<!> a = 45
bar(::<!INAPPLICABLE_CANDIDATE!>a<!>) bar(::<!INAPPLICABLE_CANDIDATE!>a<!>)
} }
@@ -67,33 +67,33 @@ FILE: unsafeAssignmentExtra.fir.kt
) )
} }
) )
lval value2: R|Foo<kotlin/String>| = R|/myBuilder|<R|kotlin/String|>(<L> = myBuilder@fun R|Foo<kotlin/String>|.<anonymous>(): R|kotlin/Unit| <inline=NoInline> { lval value2: 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.accept: R|kotlin/Unit|>|(String())
this@R|special/anonymous|.R|SubstitutionOverride</Foo.a: R|kotlin/String|>| = Int(45) this@R|special/anonymous|.R|SubstitutionOverride</Foo.a: R|it(kotlin/Comparable<*> & java/io/Serializable)|>| = Int(45)
when (R|<local>/condition|) { when (R|<local>/condition|) {
==($subj$, Boolean(true)) -> { ==($subj$, Boolean(true)) -> {
this@R|special/anonymous|.R|SubstitutionOverride</Foo.a: R|kotlin/String|>| = Int(87) this@R|special/anonymous|.R|SubstitutionOverride</Foo.a: R|it(kotlin/Comparable<*> & java/io/Serializable)|>| = Int(87)
} }
==($subj$, Boolean(false)) -> { ==($subj$, Boolean(false)) -> {
this@R|special/anonymous|.R|SubstitutionOverride</Foo.a: R|kotlin/String|>| = Int(65) this@R|special/anonymous|.R|SubstitutionOverride</Foo.a: R|it(kotlin/Comparable<*> & java/io/Serializable)|>| = 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|/change|<R|it(kotlin/Comparable<*> & java/io/Serializable)|>(<L> = change@fun R|Foo<it(kotlin/Comparable<*> & java/io/Serializable)>|.<anonymous>(): R|kotlin/Unit| <inline=NoInline> {
this@R|special/anonymous|.R|SubstitutionOverride</Foo.a: R|kotlin/String|>| = Int(99) this@R|special/anonymous|.R|SubstitutionOverride</Foo.a: R|it(kotlin/Comparable<*> & java/io/Serializable)|>| = Int(99)
} }
) )
when () { when () {
(this@R|special/anonymous|.R|SubstitutionOverride</Foo.a: R|kotlin/String|>| is R|kotlin/Int|) -> { (this@R|special/anonymous|.R|SubstitutionOverride</Foo.a: R|it(kotlin/Comparable<*> & java/io/Serializable)|>| is R|kotlin/Int|) -> {
this@R|special/anonymous|.R|SubstitutionOverride</Foo.a: R|kotlin/String|>| = Int(67) this@R|special/anonymous|.R|SubstitutionOverride</Foo.a: R|it(kotlin/Comparable<*> & java/io/Serializable)|>| = Int(67)
} }
} }
} }
) )
lval value3: R|Foo<kotlin/String>| = R|/myBuilder|<R|kotlin/String|>(<L> = myBuilder@fun R|Foo<kotlin/String>|.<anonymous>(): R|kotlin/Unit| <inline=NoInline> { lval value3: 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.accept: R|kotlin/Unit|>|(String())
this@R|special/anonymous|.R|SubstitutionOverride</Foo.a: R|kotlin/String|>| = Int(45) this@R|special/anonymous|.R|SubstitutionOverride</Foo.a: R|it(kotlin/Comparable<*> & java/io/Serializable)|>| = Int(45)
R|/bar<Inapplicable(INAPPLICABLE): /bar>#|(::<Inapplicable(INAPPLICABLE): /Foo.a>#) R|/bar<Inapplicable(INAPPLICABLE): /bar>#|(::<Inapplicable(INAPPLICABLE): /Foo.a>#)
} }
) )