[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
@@ -1,8 +1,8 @@
// ISSUE: KT-62959
fun bar(x: Inv<out CharSequence>) {
x.foo { <!ARGUMENT_TYPE_MISMATCH("CapturedType(out kotlin.CharSequence); kotlin.CharSequence")!>it<!> }
x.bar { <!ARGUMENT_TYPE_MISMATCH("CapturedType(out kotlin.CharSequence); kotlin.CharSequence"), TYPE_MISMATCH("CapturedType(out kotlin.CharSequence); CapturedType(out kotlin.CharSequence)")!>it.e()<!> }
x.foo { it }
x.bar { it.e() }
}
interface Inv<E> {
@@ -5,10 +5,10 @@ class Bound<T: Number>(val value: T)
fun test_1() {
val b: Bound<in Int> = Bound(1)
val vl: Number = <!DEBUG_INFO_EXPRESSION_TYPE("kotlin.Number")!>b.value<!>
val vl: Number = <!DEBUG_INFO_EXPRESSION_TYPE("CapturedType(in kotlin.Int)")!>b.value<!>
}
fun test_2() {
val b: Bound<*> = Bound(1)
val vl: Number = <!DEBUG_INFO_EXPRESSION_TYPE("kotlin.Number")!>b.value<!>
val vl: Number = <!DEBUG_INFO_EXPRESSION_TYPE("CapturedType(*)")!>b.value<!>
}
@@ -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 {
@@ -65,17 +65,17 @@ fun test10(b: Boolean) {
}
fun test11(b: Boolean) {
var x = <!DEBUG_INFO_EXPRESSION_TYPE("kotlin.Any")!>foo11 { 1 }.value<!>
var x = <!DEBUG_INFO_EXPRESSION_TYPE("CapturedType(out kotlin.Any)")!>foo11 { 1 }.value<!>
if (b) {
x = <!DEBUG_INFO_EXPRESSION_TYPE("kotlin.Any")!>foo11 { 2 }.value<!>
x = <!DEBUG_INFO_EXPRESSION_TYPE("CapturedType(out kotlin.Any)")!>foo11 { 2 }.value<!>
}
x.<!UNRESOLVED_REFERENCE!>bar<!>()
}
fun test12(b: Boolean) {
var x = <!DEBUG_INFO_EXPRESSION_TYPE("kotlin.Any")!>foo12 { 1 }.value.value<!>
var x = <!DEBUG_INFO_EXPRESSION_TYPE("CapturedType(out kotlin.Any)")!>foo12 { 1 }.value.value<!>
if (b) {
x = <!DEBUG_INFO_EXPRESSION_TYPE("kotlin.Any")!>foo12 { 2 }.value.value<!>
x = <!DEBUG_INFO_EXPRESSION_TYPE("CapturedType(out kotlin.Any)")!>foo12 { 2 }.value.value<!>
}
x.<!UNRESOLVED_REFERENCE!>bar<!>()
}
@@ -91,17 +91,17 @@ fun test20(b: Boolean) {
}
fun test21(b: Boolean) {
var x = <!DEBUG_INFO_EXPRESSION_TYPE("I1")!>foo21 { 1 }.value<!>
var x = <!DEBUG_INFO_EXPRESSION_TYPE("CapturedType(out I1)")!>foo21 { 1 }.value<!>
if (b) {
x = <!DEBUG_INFO_EXPRESSION_TYPE("I1")!>foo21 { 2 }.value<!>
x = <!DEBUG_INFO_EXPRESSION_TYPE("CapturedType(out I1)")!>foo21 { 2 }.value<!>
}
x.<!UNRESOLVED_REFERENCE!>bar<!>()
}
fun test22(b: Boolean) {
var x = <!DEBUG_INFO_EXPRESSION_TYPE("I1")!>foo22 { 1 }.value.value<!>
var x = <!DEBUG_INFO_EXPRESSION_TYPE("CapturedType(out I1)")!>foo22 { 1 }.value.value<!>
if (b) {
x = <!DEBUG_INFO_EXPRESSION_TYPE("I1")!>foo22 { 2 }.value.value<!>
x = <!DEBUG_INFO_EXPRESSION_TYPE("CapturedType(out I1)")!>foo22 { 2 }.value.value<!>
}
x.<!UNRESOLVED_REFERENCE!>bar<!>()
}
@@ -117,17 +117,17 @@ fun test30(b: Boolean) {
}
fun test31(b: Boolean) {
var x = <!DEBUG_INFO_EXPRESSION_TYPE("I1")!>foo31 { 1 }.value<!>
var x = <!DEBUG_INFO_EXPRESSION_TYPE("CapturedType(out I1)")!>foo31 { 1 }.value<!>
if (b) {
x = <!DEBUG_INFO_EXPRESSION_TYPE("I1")!>foo31 { 2 }.value<!>
x = <!DEBUG_INFO_EXPRESSION_TYPE("CapturedType(out I1)")!>foo31 { 2 }.value<!>
}
x.<!UNRESOLVED_REFERENCE!>bar<!>()
}
fun test32(b: Boolean) {
var x = <!DEBUG_INFO_EXPRESSION_TYPE("I1")!>foo32 { 1 }.value.value<!>
var x = <!DEBUG_INFO_EXPRESSION_TYPE("CapturedType(out I1)")!>foo32 { 1 }.value.value<!>
if (b) {
x = <!DEBUG_INFO_EXPRESSION_TYPE("I1")!>foo32 { 2 }.value.value<!>
x = <!DEBUG_INFO_EXPRESSION_TYPE("CapturedType(out I1)")!>foo32 { 2 }.value.value<!>
}
x.<!UNRESOLVED_REFERENCE!>bar<!>()
}
@@ -0,0 +1,18 @@
// FIR_IDENTICAL
abstract class FirBasedSymbol<E : FirDeclaration> {
val fir: E get() = null!!
}
abstract class FirCallableSymbol<D : FirCallableDeclaration> : FirBasedSymbol<D>()
sealed class FirDeclaration
sealed class FirCallableDeclaration : FirDeclaration()
class FirFunction : FirCallableDeclaration()
class FirVariable : FirCallableDeclaration()
val FirCallableSymbol<*>.isExtension: Boolean
get() = when (fir) {
is FirFunction -> true
is FirVariable -> false
}
@@ -10,6 +10,6 @@ fun <T> listOf(): List<T> = null!!
// Unresolved reference is ok here:
// we can't create a substituted signature for type alias constructor
// since it has 'out' type projection in 'in' position.
val test1 = BOutIn(<!ARGUMENT_TYPE_MISMATCH!>listOf()<!>, null!!)
val test1 = <!UPPER_BOUND_VIOLATED!>BOutIn(<!ARGUMENT_TYPE_MISMATCH!>listOf()<!>, null!!)<!>
val test2 = BInIn(listOf(), null!!)
val test2 = <!UPPER_BOUND_VIOLATED!>BInIn(listOf(), null!!)<!>