[FIR] Don't approximate captured types

This fixes some type argument mismatch errors caused by a captured type
being approximated and then captured again.
Some places need to be adapted to work with captured types that
previously only worked with approximated types.

#KT-62959 Fixed
This commit is contained in:
Kirill Rakhman
2023-12-20 11:10:25 +01:00
committed by Space Team
parent b6d7f35ebf
commit 251827c9aa
58 changed files with 506 additions and 86 deletions
@@ -0,0 +1,18 @@
interface Inv<T : CharSequence>
fun <E : CharSequence> id(i: Inv<E>): Inv<E> = i
fun foo1(x: Inv<in String>) {
val y = <!DEBUG_INFO_EXPRESSION_TYPE("Inv<CapturedType(in kotlin.String)>")!>id(x)<!> // Should return Inv<in String>
bar1(y)
}
fun bar1(i: Inv<in String>) {}
fun foo2(x: Inv<in Nothing>) {
// Inv<out kotlin.CharSequence> is OK here, because it's still a subtype of Inv<in Nothing>
val y = <!DEBUG_INFO_EXPRESSION_TYPE("Inv<CapturedType(in kotlin.Nothing)>")!>id(x)<!>
bar2(y)
}
fun bar2(i: Inv<in Nothing>) {}
@@ -1,4 +1,3 @@
// FIR_IDENTICAL
interface Inv<T : CharSequence>
fun <E : CharSequence> id(i: Inv<E>): Inv<E> = i
@@ -0,0 +1,13 @@
// ISSUE: KT-57958
fun ListVM<*>.foo() {
val currentItem1: MutableProperty<out Any?> = <!DEBUG_INFO_EXPRESSION_TYPE("MutableProperty<CapturedType(*)?>")!>currentItem<!>
}
interface MutableProperty<T> {
var value: T
}
interface ListVM<TItemVM> {
val currentItem: MutableProperty<TItemVM?>
}
@@ -1,4 +1,3 @@
// FIR_IDENTICAL
// ISSUE: KT-57958
fun ListVM<*>.foo() {
@@ -20,11 +20,11 @@ fun getTag7(): Tag7<*> = Tag7<Int> { }
fun getTag8(): Tag8<*> = Tag8<Int> { 1 }
fun main() {
<!DEBUG_INFO_EXPRESSION_TYPE("kotlin.Function1<kotlin.Nothing, kotlin.Unit>")!>getTag().action<!>
<!DEBUG_INFO_EXPRESSION_TYPE("kotlin.Function1<kotlin.Nothing, kotlin.Unit>")!>getTag2().action<!>
<!DEBUG_INFO_EXPRESSION_TYPE("kotlin.Function1<kotlin.Nothing, kotlin.Unit>")!>getTag3().action<!>
<!DEBUG_INFO_EXPRESSION_TYPE("kotlin.Function1<kotlin.Nothing, kotlin.Unit>")!>getTag4().action<!>
<!DEBUG_INFO_EXPRESSION_TYPE("kotlin.Function1<kotlin.Nothing, kotlin.Any?>")!>getTag5().action<!>
<!DEBUG_INFO_EXPRESSION_TYPE("Action<CapturedType(*)>")!>getTag().action<!>
<!DEBUG_INFO_EXPRESSION_TYPE("Action<in CapturedType(*)>")!>getTag2().action<!>
<!DEBUG_INFO_EXPRESSION_TYPE("Action<CapturedType(*)>")!>getTag3().action<!>
<!DEBUG_INFO_EXPRESSION_TYPE("Action<in CapturedType(*)>")!>getTag4().action<!>
<!DEBUG_INFO_EXPRESSION_TYPE("Action2<CapturedType(*)>")!>getTag5().action<!>
<!DEBUG_INFO_EXPRESSION_TYPE("Action<in kotlin.Any?>")!>getTag6().action<!>
<!DEBUG_INFO_EXPRESSION_TYPE("Action<kotlin.Any?>")!>getTag7().action<!>
<!DEBUG_INFO_EXPRESSION_TYPE("Action2<kotlin.Any?>")!>getTag8().action<!>
@@ -0,0 +1,16 @@
// FIR_IDENTICAL
// FILE: Inlay.java
public interface Inlay<T extends EditorCustomElementRenderer> {
@org.jetbrains.annotations.NotNull T getRenderer();
}
// FILE: test.kt
interface EditorCustomElementRenderer
interface PresentationContainerRenderer<Constraints : Any> : EditorCustomElementRenderer
fun test(inlay: Inlay<out PresentationContainerRenderer<*>>) {
inlay.renderer.addOrUpdate()
}
fun <T : Any> PresentationContainerRenderer<T>.addOrUpdate() {}
@@ -44,7 +44,7 @@ public class Bar<T> {
fun takeStarBar(x: Bar<*>) {
x.value = <!ASSIGNMENT_TYPE_MISMATCH!>"test"<!>
x.value <!UNRESOLVED_REFERENCE!>+=<!> "test"
x.value <!NONE_APPLICABLE!>+=<!> "test"
}
fun main2() {
@@ -58,7 +58,7 @@ fun main2() {
fun takeStarFoo2(x: Foo2<*>) {
x.value = <!ASSIGNMENT_TYPE_MISMATCH!>"test"<!>
x.value <!UNRESOLVED_REFERENCE!>+=<!> "test"
x.value <!NONE_APPLICABLE!>+=<!> "test"
}
fun main3() {
@@ -75,7 +75,7 @@ public class Bar2<T> {
fun takeStarBar2(x: Bar2<*>) {
x.value = <!ASSIGNMENT_TYPE_MISMATCH!>"test"<!>
x.value <!UNRESOLVED_REFERENCE!>+=<!> "test"
x.value <!NONE_APPLICABLE!>+=<!> "test"
}
fun main4() {
@@ -89,7 +89,7 @@ fun main4() {
fun takeStarFoo3(x: Foo3<*>) {
x.value = <!ASSIGNMENT_TYPE_MISMATCH!>"test"<!>
x.value <!UNRESOLVED_REFERENCE!>+=<!> "test"
x.value <!NONE_APPLICABLE!>+=<!> "test"
}
fun main5() {
@@ -107,7 +107,7 @@ class Bar3<T> {
fun takeStarBar3(x: Bar3<*>) {
x.value = <!ASSIGNMENT_TYPE_MISMATCH!>"test"<!>
x.value <!UNRESOLVED_REFERENCE!>+=<!> "test"
x.value <!NONE_APPLICABLE!>+=<!> "test"
}
fun main6() {
@@ -44,7 +44,7 @@ public class Bar<T> {
fun takeStarBar(x: Bar<*>) {
x.value = <!ASSIGNMENT_TYPE_MISMATCH!>"test"<!>
x.value <!UNRESOLVED_REFERENCE!>+=<!> "test"
x.value <!NONE_APPLICABLE!>+=<!> "test"
}
fun main2() {
@@ -58,7 +58,7 @@ fun main2() {
fun takeStarFoo2(x: Foo2<*>) {
x.value = <!ASSIGNMENT_TYPE_MISMATCH!>"test"<!>
x.value <!UNRESOLVED_REFERENCE!>+=<!> "test"
x.value <!NONE_APPLICABLE!>+=<!> "test"
}
fun main3() {
@@ -75,7 +75,7 @@ public class Bar2<T> {
fun takeStarBar2(x: Bar2<*>) {
x.value = <!ASSIGNMENT_TYPE_MISMATCH!>"test"<!>
x.value <!UNRESOLVED_REFERENCE!>+=<!> "test"
x.value <!NONE_APPLICABLE!>+=<!> "test"
}
fun main4() {
@@ -89,7 +89,7 @@ fun main4() {
fun takeStarFoo3(x: Foo3<*>) {
x.value = <!ASSIGNMENT_TYPE_MISMATCH!>"test"<!>
x.value <!UNRESOLVED_REFERENCE!>+=<!> "test"
x.value <!NONE_APPLICABLE!>+=<!> "test"
}
fun main5() {
@@ -107,7 +107,7 @@ class Bar3<T> {
fun takeStarBar3(x: Bar3<*>) {
x.value = <!ASSIGNMENT_TYPE_MISMATCH!>"test"<!>
x.value <!UNRESOLVED_REFERENCE!>+=<!> "test"
x.value <!NONE_APPLICABLE!>+=<!> "test"
}
fun main6() {
@@ -0,0 +1,13 @@
// !CHECK_TYPE
class A<T> {
fun foo(): T = null!!
}
fun <E> A<E>.bar(): A<in E> = this
fun baz(x: A<out CharSequence>) {
x.bar() checkType { _<A<*>>() }
<!DEBUG_INFO_EXPRESSION_TYPE("CapturedType(in CapturedType(out kotlin.CharSequence))")!>x.bar().foo()<!> checkType { <!UNRESOLVED_REFERENCE_WRONG_RECEIVER!>_<!><Any?>() } // See KT-10448
<!DEBUG_INFO_EXPRESSION_TYPE("CapturedType(in CapturedType(out kotlin.CharSequence))")!>x.bar().foo()<!> checkType { _<CharSequence>() } // Inference change in K2
}
@@ -1,4 +1,3 @@
// FIR_IDENTICAL
// !CHECK_TYPE
class A<T> {
@@ -9,5 +8,6 @@ fun <E> A<E>.bar(): A<in E> = this
fun baz(x: A<out CharSequence>) {
x.bar() checkType { _<A<*>>() }
x.bar().foo() checkType { _<Any?>() } // See KT-10448
<!DEBUG_INFO_EXPRESSION_TYPE("kotlin.Any?")!>x.bar().foo()<!> checkType { _<Any?>() } // See KT-10448
<!DEBUG_INFO_EXPRESSION_TYPE("kotlin.Any?")!>x.bar().foo()<!> checkType { <!UNRESOLVED_REFERENCE_WRONG_RECEIVER!>_<!><CharSequence>() } // Inference change in K2
}
@@ -19,17 +19,17 @@ public class JavaWriterAppender {
// FILE: main.kt
fun test() {
<!DEBUG_INFO_EXPRESSION_TYPE("WriterAppender.Builder1<*>")!>WriterAppender.newBuilder()<!>
<!DEBUG_INFO_EXPRESSION_TYPE("WriterAppender.Builder1<out WriterAppender.Builder1<*>>")!>WriterAppender.Builder1()<!>
<!DEBUG_INFO_EXPRESSION_TYPE("CapturedType(*)")!>WriterAppender.newBuilder()<!>
<!DEBUG_INFO_EXPRESSION_TYPE("WriterAppender.Builder1<CapturedType(*)>")!>WriterAppender.Builder1()<!>
<!DEBUG_INFO_EXPRESSION_TYPE("WriterAppender.Builder1<*> & WriterAppender.Builder2<*>")!>WriterAppender.intersectTwoSelfTypes()<!>
<!DEBUG_INFO_EXPRESSION_TYPE("CapturedType(*)")!>WriterAppender.intersectTwoSelfTypes()<!>
}
fun testJava(appender: JavaWriterAppender) {
<!DEBUG_INFO_EXPRESSION_TYPE("JavaWriterAppender.Builder1<*>..JavaWriterAppender.Builder1<*>?!")!>appender.newBuilder()<!>
<!DEBUG_INFO_EXPRESSION_TYPE("JavaWriterAppender.Builder1<out JavaWriterAppender.Builder1<*>..JavaWriterAppender.Builder1<*>?!>")!>appender.Builder1()<!>
<!DEBUG_INFO_EXPRESSION_TYPE("CapturedType(*)!!..CapturedType(*)?!")!>appender.newBuilder()<!>
<!DEBUG_INFO_EXPRESSION_TYPE("JavaWriterAppender.Builder1<CapturedType(*)>")!>appender.Builder1()<!>
<!DEBUG_INFO_EXPRESSION_TYPE("JavaWriterAppender.Builder1<*> & JavaWriterAppender.Builder2<*>..JavaWriterAppender.Builder1<*>? & JavaWriterAppender.Builder2<*>?")!>appender.intersectTwoSelfTypes()<!>
<!DEBUG_INFO_EXPRESSION_TYPE("CapturedType(*)!!..CapturedType(*)?!")!>appender.intersectTwoSelfTypes()<!>
}
object WriterAppender {