Refine member scope for types with projections
Instead of erasing descriptors with conflicting substitution, use invariant CapturedType(<projection>) as replacement for type parameter within default member scope. After substitution leave such types 'as is' everywhere except return types, use common approximation for them. #KT-9294 In Progress #KT-5411 Fixed #KT-8647 Fixed #KT-9462 Fixed #KT-9893 Fixed #KT-7581 Fixed #KT-7296 In Progress
This commit is contained in:
+1
-1
@@ -2,5 +2,5 @@
|
|||||||
|
|
||||||
fun foo() {
|
fun foo() {
|
||||||
val f : Function1<*, *> = { x -> x.toString() }
|
val f : Function1<*, *> = { x -> x.toString() }
|
||||||
<!FUNCTION_EXPECTED, UNUSED_EXPRESSION!>f<!>(1)
|
f(<!CONSTANT_EXPECTED_TYPE_MISMATCH!>1<!>)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -36,13 +36,13 @@ fun testInOut() {
|
|||||||
|
|
||||||
Inv<Int>().f(1)
|
Inv<Int>().f(1)
|
||||||
(null <!CAST_NEVER_SUCCEEDS!>as<!> Inv<in Int>).f(1)
|
(null <!CAST_NEVER_SUCCEEDS!>as<!> Inv<in Int>).f(1)
|
||||||
(null <!CAST_NEVER_SUCCEEDS!>as<!> Inv<out Int>).<!UNRESOLVED_REFERENCE!>f<!>(1) // !!
|
(null <!CAST_NEVER_SUCCEEDS!>as<!> Inv<out Int>).f(<!CONSTANT_EXPECTED_TYPE_MISMATCH!>1<!>) // !!
|
||||||
(null <!CAST_NEVER_SUCCEEDS!>as<!> Inv<*>).<!UNRESOLVED_REFERENCE!>f<!>(1) // !!
|
(null <!CAST_NEVER_SUCCEEDS!>as<!> Inv<*>).f(<!CONSTANT_EXPECTED_TYPE_MISMATCH!>1<!>) // !!
|
||||||
|
|
||||||
Inv<Int>().inf(1)
|
Inv<Int>().inf(1)
|
||||||
(null <!CAST_NEVER_SUCCEEDS!>as<!> Inv<in Int>).inf(1)
|
(null <!CAST_NEVER_SUCCEEDS!>as<!> Inv<in Int>).inf(1)
|
||||||
(null <!CAST_NEVER_SUCCEEDS!>as<!> Inv<out Int>).<!UNRESOLVED_REFERENCE!>inf<!>(1) // !!
|
(null <!CAST_NEVER_SUCCEEDS!>as<!> Inv<out Int>).inf(<!CONSTANT_EXPECTED_TYPE_MISMATCH!>1<!>) // !!
|
||||||
(null <!CAST_NEVER_SUCCEEDS!>as<!> Inv<*>).<!UNRESOLVED_REFERENCE!>inf<!>(1) // !!
|
(null <!CAST_NEVER_SUCCEEDS!>as<!> Inv<*>).inf(<!CONSTANT_EXPECTED_TYPE_MISMATCH!>1<!>) // !!
|
||||||
|
|
||||||
Inv<Int>().outf()
|
Inv<Int>().outf()
|
||||||
checkSubtype<Int>(<!TYPE_MISMATCH!>(null <!CAST_NEVER_SUCCEEDS!>as<!> Inv<in Int>).outf()<!>) // Type mismatch
|
checkSubtype<Int>(<!TYPE_MISMATCH!>(null <!CAST_NEVER_SUCCEEDS!>as<!> Inv<in Int>).outf()<!>) // Type mismatch
|
||||||
|
|||||||
+3
-4
@@ -28,10 +28,9 @@ fun main() {
|
|||||||
checkSubtype<Outer<out CharSequence>.Inner>(outer.bar())
|
checkSubtype<Outer<out CharSequence>.Inner>(outer.bar())
|
||||||
checkSubtype<Outer<out CharSequence>.Inner>(outer.Inner())
|
checkSubtype<Outer<out CharSequence>.Inner>(outer.Inner())
|
||||||
|
|
||||||
// Should not actually work as in Java (captured constructor type mismatch)
|
outer.set(<!TYPE_MISMATCH(kotlin.Nothing; Outer<out kotlin.String>.Inner)!>outer.bar()<!>)
|
||||||
outer.set(outer.bar())
|
outer.set(<!TYPE_MISMATCH(kotlin.Nothing; Outer<out kotlin.String>.Inner)!>outer.Inner()<!>)
|
||||||
outer.set(outer.Inner())
|
|
||||||
|
|
||||||
val x: Outer<String>.Inner = factoryString()
|
val x: Outer<String>.Inner = factoryString()
|
||||||
outer.set(x)
|
outer.set(<!TYPE_MISMATCH(kotlin.Nothing; Outer<kotlin.String>.Inner)!>x<!>)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,18 @@
|
|||||||
|
// !CHECK_TYPE
|
||||||
|
|
||||||
|
// FILE: A.java
|
||||||
|
public class A {
|
||||||
|
public java.util.List<? extends CharSequence> foo() {}
|
||||||
|
}
|
||||||
|
|
||||||
|
// FILE: main.kt
|
||||||
|
|
||||||
|
fun foo2(x: A, y: MutableList<out CharSequence>) {
|
||||||
|
x.foo().isEmpty()
|
||||||
|
x.foo().get(0) checkType { _<CharSequence>() }
|
||||||
|
x.foo().iterator() checkType { _<MutableIterator<CharSequence>>() }
|
||||||
|
|
||||||
|
y.isEmpty()
|
||||||
|
y.get(0) checkType { _<CharSequence>() }
|
||||||
|
y.iterator() checkType { _<MutableIterator<CharSequence>>() }
|
||||||
|
}
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
package
|
||||||
|
|
||||||
|
public fun foo2(/*0*/ x: A, /*1*/ y: kotlin.MutableList<out kotlin.CharSequence>): kotlin.Unit
|
||||||
|
|
||||||
|
public open class A {
|
||||||
|
public constructor A()
|
||||||
|
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||||
|
public open fun foo(): (kotlin.MutableList<out kotlin.CharSequence!>..kotlin.List<kotlin.CharSequence!>?)
|
||||||
|
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||||
|
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||||
|
}
|
||||||
@@ -0,0 +1,27 @@
|
|||||||
|
// !DIAGNOSTICS: -UNUSED_PARAMETER
|
||||||
|
|
||||||
|
interface C<out T>
|
||||||
|
interface MC<T> : C<T> {
|
||||||
|
fun addAll(x: C<T>): Boolean
|
||||||
|
fun addAllMC(x: MC<out T>): Boolean
|
||||||
|
}
|
||||||
|
|
||||||
|
interface Open
|
||||||
|
class Derived : Open
|
||||||
|
|
||||||
|
fun <T> mc(): MC<T> = null!!
|
||||||
|
fun <T> c(): C<T> = null!!
|
||||||
|
|
||||||
|
fun foo(x: MC<out Open>) {
|
||||||
|
x.addAll(<!TYPE_MISMATCH(C<kotlin.Nothing>; MC<out Open>)!>x<!>)
|
||||||
|
x.addAllMC(<!TYPE_MISMATCH(MC<kotlin.Nothing>; MC<out Open>)!>x<!>)
|
||||||
|
|
||||||
|
x.addAll(<!TYPE_MISMATCH(C<kotlin.Nothing>; MC<Open>)!>mc<Open>()<!>)
|
||||||
|
x.addAllMC(<!TYPE_MISMATCH(MC<kotlin.Nothing>; MC<Open>)!>mc<Open>()<!>)
|
||||||
|
|
||||||
|
x.addAll(<!TYPE_MISMATCH(C<kotlin.Nothing>; MC<Derived>)!>mc<Derived>()<!>)
|
||||||
|
x.addAllMC(<!TYPE_MISMATCH(MC<kotlin.Nothing>; MC<Derived>)!>mc<Derived>()<!>)
|
||||||
|
|
||||||
|
x.addAll(c())
|
||||||
|
x.addAll(c<Nothing>())
|
||||||
|
}
|
||||||
@@ -0,0 +1,32 @@
|
|||||||
|
package
|
||||||
|
|
||||||
|
public fun </*0*/ T> c(): C<T>
|
||||||
|
public fun foo(/*0*/ x: MC<out Open>): kotlin.Unit
|
||||||
|
public fun </*0*/ T> mc(): MC<T>
|
||||||
|
|
||||||
|
public interface C</*0*/ out T> {
|
||||||
|
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||||
|
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||||
|
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||||
|
}
|
||||||
|
|
||||||
|
public final class Derived : Open {
|
||||||
|
public constructor Derived()
|
||||||
|
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||||
|
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||||
|
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||||
|
}
|
||||||
|
|
||||||
|
public interface MC</*0*/ T> : C<T> {
|
||||||
|
public abstract fun addAll(/*0*/ x: C<T>): kotlin.Boolean
|
||||||
|
public abstract fun addAllMC(/*0*/ x: MC<out T>): kotlin.Boolean
|
||||||
|
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||||
|
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||||
|
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||||
|
}
|
||||||
|
|
||||||
|
public interface Open {
|
||||||
|
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||||
|
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||||
|
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||||
|
}
|
||||||
Vendored
+13
@@ -0,0 +1,13 @@
|
|||||||
|
// !DIAGNOSTICS: -UNUSED_PARAMETER
|
||||||
|
|
||||||
|
class A<T> {
|
||||||
|
fun foo() = 1
|
||||||
|
}
|
||||||
|
|
||||||
|
interface B
|
||||||
|
|
||||||
|
public fun <E : B> E.bar() : A<out E> = null!!
|
||||||
|
|
||||||
|
fun baz(x: B) {
|
||||||
|
x.bar().foo()
|
||||||
|
}
|
||||||
Vendored
+18
@@ -0,0 +1,18 @@
|
|||||||
|
package
|
||||||
|
|
||||||
|
public fun baz(/*0*/ x: B): kotlin.Unit
|
||||||
|
public fun </*0*/ E : B> E.bar(): A<out E>
|
||||||
|
|
||||||
|
public final class A</*0*/ T> {
|
||||||
|
public constructor A</*0*/ T>()
|
||||||
|
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||||
|
public final fun foo(): kotlin.Int
|
||||||
|
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||||
|
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||||
|
}
|
||||||
|
|
||||||
|
public interface B {
|
||||||
|
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||||
|
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||||
|
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||||
|
}
|
||||||
@@ -0,0 +1,14 @@
|
|||||||
|
// !DIAGNOSTICS: -UNUSED_VARIABLE
|
||||||
|
// !CHECK_TYPE
|
||||||
|
import java.util.ArrayList
|
||||||
|
|
||||||
|
class ListOfLists<T>(public val x : ArrayList<ArrayList<T>>)
|
||||||
|
|
||||||
|
fun main(args : Array<String>) {
|
||||||
|
val a : ArrayList<ArrayList<String>> = ArrayList()
|
||||||
|
val b : ListOfLists<String> = ListOfLists(a)
|
||||||
|
val c : ListOfLists<*> = b
|
||||||
|
val d : ArrayList<ArrayList<*>> = <!TYPE_MISMATCH!>c.x<!>
|
||||||
|
|
||||||
|
c.x checkType { _<ArrayList<out ArrayList<*>>>() }
|
||||||
|
}
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
package
|
||||||
|
|
||||||
|
public fun main(/*0*/ args: kotlin.Array<kotlin.String>): kotlin.Unit
|
||||||
|
|
||||||
|
public final class ListOfLists</*0*/ T> {
|
||||||
|
public constructor ListOfLists</*0*/ T>(/*0*/ x: java.util.ArrayList<java.util.ArrayList<T>>)
|
||||||
|
public final val x: java.util.ArrayList<java.util.ArrayList<T>>
|
||||||
|
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||||
|
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||||
|
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||||
|
}
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
interface Subscriber<T>
|
||||||
|
|
||||||
|
interface Observable<T> {
|
||||||
|
fun subscribe(s: Subscriber<in T>)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun foo(o: Observable<out CharSequence>, y: Subscriber<in CharSequence>) = o.subscribe(y) // type safe
|
||||||
|
|
||||||
@@ -0,0 +1,16 @@
|
|||||||
|
package
|
||||||
|
|
||||||
|
public fun foo(/*0*/ o: Observable<out kotlin.CharSequence>, /*1*/ y: Subscriber<in kotlin.CharSequence>): kotlin.Unit
|
||||||
|
|
||||||
|
public interface Observable</*0*/ T> {
|
||||||
|
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||||
|
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||||
|
public abstract fun subscribe(/*0*/ s: Subscriber<in T>): kotlin.Unit
|
||||||
|
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||||
|
}
|
||||||
|
|
||||||
|
public interface Subscriber</*0*/ T> {
|
||||||
|
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||||
|
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||||
|
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||||
|
}
|
||||||
+16
@@ -0,0 +1,16 @@
|
|||||||
|
// !DIAGNOSTICS: -UNUSED_PARAMETER
|
||||||
|
// !CHECK_TYPE
|
||||||
|
|
||||||
|
class A<T> {
|
||||||
|
fun foo(f: (T) -> Unit) {}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun test(a: A<out Number>, b: A<in Number>) {
|
||||||
|
a.foo {
|
||||||
|
it checkType { _<Number>() }
|
||||||
|
}
|
||||||
|
|
||||||
|
b.foo {
|
||||||
|
it checkType { _<Any?>() }
|
||||||
|
}
|
||||||
|
}
|
||||||
+11
@@ -0,0 +1,11 @@
|
|||||||
|
package
|
||||||
|
|
||||||
|
public fun test(/*0*/ a: A<out kotlin.Number>, /*1*/ b: A<in kotlin.Number>): kotlin.Unit
|
||||||
|
|
||||||
|
public final class A</*0*/ T> {
|
||||||
|
public constructor A</*0*/ T>()
|
||||||
|
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||||
|
public final fun foo(/*0*/ f: (T) -> kotlin.Unit): kotlin.Unit
|
||||||
|
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||||
|
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||||
|
}
|
||||||
+10
@@ -0,0 +1,10 @@
|
|||||||
|
// !DIAGNOSTICS: -UNUSED_PARAMETER
|
||||||
|
// See KT-7296
|
||||||
|
interface A<T>
|
||||||
|
interface B<T> : A<A<T>>
|
||||||
|
|
||||||
|
fun foo(x : B<*>) {
|
||||||
|
bar(x) // this should not be valid
|
||||||
|
}
|
||||||
|
|
||||||
|
fun bar(x : A<A<*>>) { }
|
||||||
+16
@@ -0,0 +1,16 @@
|
|||||||
|
package
|
||||||
|
|
||||||
|
public fun bar(/*0*/ x: A<A<*>>): kotlin.Unit
|
||||||
|
public fun foo(/*0*/ x: B<*>): kotlin.Unit
|
||||||
|
|
||||||
|
public interface A</*0*/ T> {
|
||||||
|
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||||
|
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||||
|
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||||
|
}
|
||||||
|
|
||||||
|
public interface B</*0*/ T> : A<A<T>> {
|
||||||
|
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||||
|
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||||
|
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||||
|
}
|
||||||
+16
@@ -0,0 +1,16 @@
|
|||||||
|
// !DIAGNOSTICS: -UNUSED_PARAMETER
|
||||||
|
// !CHECK_TYPE
|
||||||
|
// See KT-9893
|
||||||
|
open class A
|
||||||
|
|
||||||
|
public interface I<T : A> {
|
||||||
|
public fun foo(): T?
|
||||||
|
}
|
||||||
|
|
||||||
|
fun acceptA(a: A) {
|
||||||
|
}
|
||||||
|
|
||||||
|
fun main(i: I<*>) {
|
||||||
|
i.foo() checkType { _<A?>() }
|
||||||
|
acceptA(<!TYPE_MISMATCH!>i.foo()<!>) // i.foo() should be nullable but isn't
|
||||||
|
}
|
||||||
+18
@@ -0,0 +1,18 @@
|
|||||||
|
package
|
||||||
|
|
||||||
|
public fun acceptA(/*0*/ a: A): kotlin.Unit
|
||||||
|
public fun main(/*0*/ i: I<*>): kotlin.Unit
|
||||||
|
|
||||||
|
public open class A {
|
||||||
|
public constructor A()
|
||||||
|
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||||
|
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||||
|
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||||
|
}
|
||||||
|
|
||||||
|
public interface I</*0*/ T : A> {
|
||||||
|
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||||
|
public abstract fun foo(): T?
|
||||||
|
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||||
|
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||||
|
}
|
||||||
+8
@@ -0,0 +1,8 @@
|
|||||||
|
// !DIAGNOSTICS: -UNUSED_PARAMETER
|
||||||
|
// !CHECK_TYPE
|
||||||
|
interface A<T : A<T?>?> {
|
||||||
|
fun foo(): T?
|
||||||
|
}
|
||||||
|
fun testA(a: A<*>) {
|
||||||
|
a.foo() checkType { _<A<*>?>() }
|
||||||
|
}
|
||||||
+10
@@ -0,0 +1,10 @@
|
|||||||
|
package
|
||||||
|
|
||||||
|
public fun testA(/*0*/ a: A<*>): kotlin.Unit
|
||||||
|
|
||||||
|
public interface A</*0*/ T : A<T?>?> {
|
||||||
|
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||||
|
public abstract fun foo(): T?
|
||||||
|
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||||
|
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||||
|
}
|
||||||
@@ -0,0 +1,12 @@
|
|||||||
|
// !CHECK_TYPE
|
||||||
|
|
||||||
|
interface Clazz<T> {
|
||||||
|
val t: T
|
||||||
|
fun getSuperClass(): Clazz<in T>
|
||||||
|
}
|
||||||
|
|
||||||
|
fun test(clazz: Clazz<*>) {
|
||||||
|
clazz.t checkType { _<Any?>() }
|
||||||
|
clazz.getSuperClass() checkType { _<Clazz<*>>() }
|
||||||
|
clazz.getSuperClass().t checkType { _<Any?>() }
|
||||||
|
}
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
package
|
||||||
|
|
||||||
|
public fun test(/*0*/ clazz: Clazz<*>): kotlin.Unit
|
||||||
|
|
||||||
|
public interface Clazz</*0*/ T> {
|
||||||
|
public abstract val t: T
|
||||||
|
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||||
|
public abstract fun getSuperClass(): Clazz<in T>
|
||||||
|
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||||
|
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||||
|
}
|
||||||
+43
@@ -0,0 +1,43 @@
|
|||||||
|
// !CHECK_TYPE
|
||||||
|
// !DIAGNOSTICS: -UNUSED_PARAMETER
|
||||||
|
|
||||||
|
class Out<out X>
|
||||||
|
class In<in Y>
|
||||||
|
class Inv<Z>
|
||||||
|
|
||||||
|
class A<T> {
|
||||||
|
fun <E : Out<T>> foo1(x: E) = 1
|
||||||
|
fun <F : Inv<T>> foo2(x: F) = 1
|
||||||
|
fun <G : In<T>> foo3(x: G) = 1
|
||||||
|
}
|
||||||
|
|
||||||
|
fun foo2(a: A<out CharSequence>, b: A<in CharSequence>) {
|
||||||
|
a.<!TYPE_INFERENCE_UPPER_BOUND_VIOLATED!>foo1<!>(Out<CharSequence>())
|
||||||
|
a.foo1<<!UPPER_BOUND_VIOLATED!>Out<CharSequence><!>>(Out())
|
||||||
|
|
||||||
|
a.foo1(Out())
|
||||||
|
a.foo1(Out<Nothing>())
|
||||||
|
|
||||||
|
a.<!TYPE_INFERENCE_INCORPORATION_ERROR!>foo2<!>(<!TYPE_INFERENCE_NO_INFORMATION_FOR_PARAMETER!>Inv<!>())
|
||||||
|
a.<!TYPE_INFERENCE_UPPER_BOUND_VIOLATED!>foo2<!>(Inv<CharSequence>())
|
||||||
|
a.foo2<<!UPPER_BOUND_VIOLATED!>Inv<CharSequence><!>>(Inv())
|
||||||
|
|
||||||
|
a.foo3(In())
|
||||||
|
a.foo3(In<CharSequence>())
|
||||||
|
a.foo3<In<CharSequence>>(In())
|
||||||
|
|
||||||
|
b.foo1(Out())
|
||||||
|
b.foo1(Out<CharSequence>())
|
||||||
|
b.foo1<Out<CharSequence>>(Out())
|
||||||
|
|
||||||
|
b.<!TYPE_INFERENCE_INCORPORATION_ERROR!>foo2<!>(<!TYPE_INFERENCE_NO_INFORMATION_FOR_PARAMETER!>Inv<!>())
|
||||||
|
b.<!TYPE_INFERENCE_UPPER_BOUND_VIOLATED!>foo2<!>(Inv<CharSequence>())
|
||||||
|
b.foo2<<!UPPER_BOUND_VIOLATED!>Inv<CharSequence><!>>(Inv())
|
||||||
|
|
||||||
|
|
||||||
|
b.<!TYPE_INFERENCE_UPPER_BOUND_VIOLATED!>foo3<!>(In<CharSequence>())
|
||||||
|
b.foo3<<!UPPER_BOUND_VIOLATED!>In<CharSequence><!>>(In())
|
||||||
|
|
||||||
|
b.foo3(In<Any?>())
|
||||||
|
b.foo3(In())
|
||||||
|
}
|
||||||
+34
@@ -0,0 +1,34 @@
|
|||||||
|
package
|
||||||
|
|
||||||
|
public fun foo2(/*0*/ a: A<out kotlin.CharSequence>, /*1*/ b: A<in kotlin.CharSequence>): kotlin.Unit
|
||||||
|
|
||||||
|
public final class A</*0*/ T> {
|
||||||
|
public constructor A</*0*/ T>()
|
||||||
|
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||||
|
public final fun </*0*/ E : Out<T>> foo1(/*0*/ x: E): kotlin.Int
|
||||||
|
public final fun </*0*/ F : Inv<T>> foo2(/*0*/ x: F): kotlin.Int
|
||||||
|
public final fun </*0*/ G : In<T>> foo3(/*0*/ x: G): kotlin.Int
|
||||||
|
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||||
|
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||||
|
}
|
||||||
|
|
||||||
|
public final class In</*0*/ in Y> {
|
||||||
|
public constructor In</*0*/ in Y>()
|
||||||
|
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||||
|
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||||
|
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||||
|
}
|
||||||
|
|
||||||
|
public final class Inv</*0*/ Z> {
|
||||||
|
public constructor Inv</*0*/ Z>()
|
||||||
|
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||||
|
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||||
|
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||||
|
}
|
||||||
|
|
||||||
|
public final class Out</*0*/ out X> {
|
||||||
|
public constructor Out</*0*/ out X>()
|
||||||
|
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||||
|
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||||
|
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||||
|
}
|
||||||
+9
@@ -0,0 +1,9 @@
|
|||||||
|
|
||||||
|
interface A<out K> {
|
||||||
|
fun foo(x: @UnsafeVariance K): Unit
|
||||||
|
}
|
||||||
|
|
||||||
|
fun test(a: A<*>) {
|
||||||
|
a.foo(null)
|
||||||
|
a.foo(Any())
|
||||||
|
}
|
||||||
+10
@@ -0,0 +1,10 @@
|
|||||||
|
package
|
||||||
|
|
||||||
|
public fun test(/*0*/ a: A<*>): kotlin.Unit
|
||||||
|
|
||||||
|
public interface A</*0*/ out K> {
|
||||||
|
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||||
|
public abstract fun foo(/*0*/ x: @kotlin.UnsafeVariance() K): kotlin.Unit
|
||||||
|
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||||
|
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||||
|
}
|
||||||
+1
@@ -7,5 +7,6 @@ class A<T> {
|
|||||||
fun <E> A<E>.bar(): A<in E> = this
|
fun <E> A<E>.bar(): A<in E> = this
|
||||||
|
|
||||||
fun baz(x: A<out CharSequence>) {
|
fun baz(x: A<out CharSequence>) {
|
||||||
|
x.bar() checkType { _<A<*>>() }
|
||||||
x.bar().foo() checkType { _<Any?>() } // See KT-10448
|
x.bar().foo() checkType { _<Any?>() } // See KT-10448
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,14 @@
|
|||||||
|
// !CHECK_TYPE
|
||||||
|
|
||||||
|
// FILE: A.java
|
||||||
|
public class A<T> {
|
||||||
|
public A<T>[] baz() { return null; }
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// FILE: main.kt
|
||||||
|
|
||||||
|
fun foo1(x: A<*>) = x.baz()
|
||||||
|
fun foo2(x: A<*>) {
|
||||||
|
x.baz() checkType { _<Array<out A<*>>>() }
|
||||||
|
}
|
||||||
@@ -0,0 +1,12 @@
|
|||||||
|
package
|
||||||
|
|
||||||
|
public fun foo1(/*0*/ x: A<*>): kotlin.Array<out A<out kotlin.Any!>>
|
||||||
|
public fun foo2(/*0*/ x: A<*>): kotlin.Unit
|
||||||
|
|
||||||
|
public open class A</*0*/ T : kotlin.Any!> {
|
||||||
|
public constructor A</*0*/ T : kotlin.Any!>()
|
||||||
|
public open fun baz(): kotlin.Array<(out) A<T!>!>!
|
||||||
|
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||||
|
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||||
|
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||||
|
}
|
||||||
@@ -0,0 +1,13 @@
|
|||||||
|
fun test(mc: MutableCollection<out CharSequence>) {
|
||||||
|
mc.addAll(<!TYPE_MISMATCH!>mc<!>)
|
||||||
|
|
||||||
|
mc.addAll(<!TYPE_MISMATCH!>arrayListOf<CharSequence>()<!>)
|
||||||
|
mc.addAll(arrayListOf())
|
||||||
|
|
||||||
|
mc.addAll(<!TYPE_INFERENCE_EXPECTED_TYPE_MISMATCH!>listOf("")<!>)
|
||||||
|
mc.addAll(<!TYPE_MISMATCH!>listOf<String>("")<!>)
|
||||||
|
mc.addAll(<!TYPE_MISMATCH!>listOf<CharSequence>("")<!>)
|
||||||
|
|
||||||
|
mc.addAll(emptyList())
|
||||||
|
mc.addAll(emptyList<Nothing>())
|
||||||
|
}
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
package
|
||||||
|
|
||||||
|
public fun test(/*0*/ mc: kotlin.MutableCollection<out kotlin.CharSequence>): kotlin.Unit
|
||||||
+7
-7
@@ -18,13 +18,13 @@ class Inv<T>() {
|
|||||||
fun testInOut() {
|
fun testInOut() {
|
||||||
In<String>().`In.f:T->Unit`f("1");
|
In<String>().`In.f:T->Unit`f("1");
|
||||||
(return as In<in String>).`In.f:T->Unit`f("1");
|
(return as In<in String>).`In.f:T->Unit`f("1");
|
||||||
(return as In<out String>).`In.f:Int->Int`f("1")
|
(return as In<out String>).`In.f:T->Unit`f("1")
|
||||||
(return as In<*>).`In.f:Int->Int`f("1");
|
(return as In<*>).`In.f:T->Unit`f("1");
|
||||||
|
|
||||||
In<String>().`In.f:Int->Int`f(1);
|
In<String>().`In.f:Int->Int`f(1);
|
||||||
(return as In<in String>).`In.f:Int->Int`f(1);
|
(return as In<in String>).`In.f:Int->Int`f(1);
|
||||||
(return as In<out String>).`In.f:Int->Int`f(1)
|
(return as In<out String>).`In.f:Int->Int`f(1)
|
||||||
(return as In<out String>).`!`f1(1)
|
(return as In<out String>).`In.f1`f1(1)
|
||||||
(return as In<*>).`In.f:Int->Int`f(1);
|
(return as In<*>).`In.f:Int->Int`f(1);
|
||||||
|
|
||||||
Out<Int>().`Out.f(a)`f(1)
|
Out<Int>().`Out.f(a)`f(1)
|
||||||
@@ -39,13 +39,13 @@ fun testInOut() {
|
|||||||
|
|
||||||
Inv<Int>().`Inv.f`f(1)
|
Inv<Int>().`Inv.f`f(1)
|
||||||
(return as Inv<in Int>).`Inv.f`f(1)
|
(return as Inv<in Int>).`Inv.f`f(1)
|
||||||
(return as Inv<out Int>).`!`f(1)
|
(return as Inv<out Int>).`Inv.f`f(1)
|
||||||
(return as Inv<*>).`!`f(1)
|
(return as Inv<*>).`Inv.f`f(1)
|
||||||
|
|
||||||
Inv<Int>().`Inv.inf`inf(1)
|
Inv<Int>().`Inv.inf`inf(1)
|
||||||
(return as Inv<in Int>).`Inv.inf`inf(1)
|
(return as Inv<in Int>).`Inv.inf`inf(1)
|
||||||
(return as Inv<out Int>).`!`inf(1)
|
(return as Inv<out Int>).`Inv.inf`inf(1)
|
||||||
(return as Inv<*>).`!`inf(1)
|
(return as Inv<*>).`Inv.inf`inf(1)
|
||||||
|
|
||||||
Inv<Int>().`Inv.outf`outf()
|
Inv<Int>().`Inv.outf`outf()
|
||||||
((return as Inv<in Int>).`Inv.outf`outf())`:kotlin::Any`
|
((return as Inv<in Int>).`Inv.outf`outf())`:kotlin::Any`
|
||||||
|
|||||||
@@ -7116,6 +7116,87 @@ public class DiagnosticsTestGenerated extends AbstractDiagnosticsTest {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("compiler/testData/diagnostics/tests/generics/projectionsScope")
|
||||||
|
@TestDataPath("$PROJECT_ROOT")
|
||||||
|
@RunWith(JUnit3RunnerWithInners.class)
|
||||||
|
public static class ProjectionsScope extends AbstractDiagnosticsTest {
|
||||||
|
@TestMetadata("addAll.kt")
|
||||||
|
public void testAddAll() throws Exception {
|
||||||
|
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/generics/projectionsScope/addAll.kt");
|
||||||
|
doTest(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testAllFilesPresentInProjectionsScope() throws Exception {
|
||||||
|
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/diagnostics/tests/generics/projectionsScope"), Pattern.compile("^(.+)\\.kt$"), true);
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("extensionResultSubstitution.kt")
|
||||||
|
public void testExtensionResultSubstitution() throws Exception {
|
||||||
|
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/generics/projectionsScope/extensionResultSubstitution.kt");
|
||||||
|
doTest(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("kt7296.kt")
|
||||||
|
public void testKt7296() throws Exception {
|
||||||
|
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/generics/projectionsScope/kt7296.kt");
|
||||||
|
doTest(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("kt8647.kt")
|
||||||
|
public void testKt8647() throws Exception {
|
||||||
|
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/generics/projectionsScope/kt8647.kt");
|
||||||
|
doTest(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("lambdaArgument.kt")
|
||||||
|
public void testLambdaArgument() throws Exception {
|
||||||
|
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/generics/projectionsScope/lambdaArgument.kt");
|
||||||
|
doTest(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("MLOut.kt")
|
||||||
|
public void testMLOut() throws Exception {
|
||||||
|
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/generics/projectionsScope/MLOut.kt");
|
||||||
|
doTest(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("recursiveUpperBoundStar.kt")
|
||||||
|
public void testRecursiveUpperBoundStar() throws Exception {
|
||||||
|
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/generics/projectionsScope/recursiveUpperBoundStar.kt");
|
||||||
|
doTest(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("starNullability.kt")
|
||||||
|
public void testStarNullability() throws Exception {
|
||||||
|
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/generics/projectionsScope/starNullability.kt");
|
||||||
|
doTest(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("starNullabilityRecursive.kt")
|
||||||
|
public void testStarNullabilityRecursive() throws Exception {
|
||||||
|
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/generics/projectionsScope/starNullabilityRecursive.kt");
|
||||||
|
doTest(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("superClass.kt")
|
||||||
|
public void testSuperClass() throws Exception {
|
||||||
|
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/generics/projectionsScope/superClass.kt");
|
||||||
|
doTest(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("typeParameterBounds.kt")
|
||||||
|
public void testTypeParameterBounds() throws Exception {
|
||||||
|
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/generics/projectionsScope/typeParameterBounds.kt");
|
||||||
|
doTest(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("unsafeVarianceStar.kt")
|
||||||
|
public void testUnsafeVarianceStar() throws Exception {
|
||||||
|
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/generics/projectionsScope/unsafeVarianceStar.kt");
|
||||||
|
doTest(fileName);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("compiler/testData/diagnostics/tests/generics/starProjections")
|
@TestMetadata("compiler/testData/diagnostics/tests/generics/starProjections")
|
||||||
@TestDataPath("$PROJECT_ROOT")
|
@TestDataPath("$PROJECT_ROOT")
|
||||||
@RunWith(JUnit3RunnerWithInners.class)
|
@RunWith(JUnit3RunnerWithInners.class)
|
||||||
@@ -9447,6 +9528,12 @@ public class DiagnosticsTestGenerated extends AbstractDiagnosticsTest {
|
|||||||
doTest(fileName);
|
doTest(fileName);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("arrayOfStarParametrized.kt")
|
||||||
|
public void testArrayOfStarParametrized() throws Exception {
|
||||||
|
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/j+k/arrayOfStarParametrized.kt");
|
||||||
|
doTest(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("canDeclareIfSamAdapterIsInherited.kt")
|
@TestMetadata("canDeclareIfSamAdapterIsInherited.kt")
|
||||||
public void testCanDeclareIfSamAdapterIsInherited() throws Exception {
|
public void testCanDeclareIfSamAdapterIsInherited() throws Exception {
|
||||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/j+k/canDeclareIfSamAdapterIsInherited.kt");
|
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/j+k/canDeclareIfSamAdapterIsInherited.kt");
|
||||||
|
|||||||
@@ -31,6 +31,12 @@ import java.util.regex.Pattern;
|
|||||||
@TestDataPath("$PROJECT_ROOT")
|
@TestDataPath("$PROJECT_ROOT")
|
||||||
@RunWith(JUnit3RunnerWithInners.class)
|
@RunWith(JUnit3RunnerWithInners.class)
|
||||||
public class DiagnosticsTestWithStdLibGenerated extends AbstractDiagnosticsTestWithStdLib {
|
public class DiagnosticsTestWithStdLibGenerated extends AbstractDiagnosticsTestWithStdLib {
|
||||||
|
@TestMetadata("addAllProjection.kt")
|
||||||
|
public void testAddAllProjection() throws Exception {
|
||||||
|
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/testsWithStdLib/addAllProjection.kt");
|
||||||
|
doTest(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
public void testAllFilesPresentInTestsWithStdLib() throws Exception {
|
public void testAllFilesPresentInTestsWithStdLib() throws Exception {
|
||||||
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/diagnostics/testsWithStdLib"), Pattern.compile("^(.+)\\.kt$"), true);
|
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/diagnostics/testsWithStdLib"), Pattern.compile("^(.+)\\.kt$"), true);
|
||||||
}
|
}
|
||||||
|
|||||||
+17
-16
@@ -16,26 +16,25 @@
|
|||||||
|
|
||||||
package org.jetbrains.kotlin.resolve.typeApproximation
|
package org.jetbrains.kotlin.resolve.typeApproximation
|
||||||
|
|
||||||
import org.jetbrains.kotlin.test.KotlinLiteFixture
|
|
||||||
import org.jetbrains.kotlin.cli.jvm.compiler.KotlinCoreEnvironment
|
import org.jetbrains.kotlin.cli.jvm.compiler.KotlinCoreEnvironment
|
||||||
import org.jetbrains.kotlin.test.ConfigurationKind
|
import org.jetbrains.kotlin.descriptors.TypeParameterDescriptor
|
||||||
import java.io.File
|
import org.jetbrains.kotlin.diagnostics.Severity
|
||||||
import org.jetbrains.kotlin.resolve.lazy.JvmResolveUtil
|
import org.jetbrains.kotlin.psi.KtPsiFactory
|
||||||
import org.jetbrains.kotlin.resolve.BindingContext
|
import org.jetbrains.kotlin.resolve.BindingContext
|
||||||
import org.jetbrains.kotlin.types.TypeSubstitutor
|
import org.jetbrains.kotlin.resolve.calls.inference.createCapturedType
|
||||||
|
import org.jetbrains.kotlin.resolve.jvm.platform.JvmPlatform
|
||||||
|
import org.jetbrains.kotlin.resolve.lazy.JvmResolveUtil
|
||||||
|
import org.jetbrains.kotlin.test.ConfigurationKind
|
||||||
|
import org.jetbrains.kotlin.test.KotlinLiteFixture
|
||||||
|
import org.jetbrains.kotlin.test.KotlinTestUtils
|
||||||
|
import org.jetbrains.kotlin.types.TypeProjection
|
||||||
import org.jetbrains.kotlin.types.TypeProjectionImpl
|
import org.jetbrains.kotlin.types.TypeProjectionImpl
|
||||||
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
|
import org.jetbrains.kotlin.types.TypeSubstitutor
|
||||||
import org.jetbrains.kotlin.types.Variance.*
|
import org.jetbrains.kotlin.types.Variance.*
|
||||||
import org.jetbrains.kotlin.types.typesApproximation.approximateCapturedTypes
|
import org.jetbrains.kotlin.types.typesApproximation.approximateCapturedTypes
|
||||||
import org.jetbrains.kotlin.test.KotlinTestUtils
|
|
||||||
import org.jetbrains.kotlin.psi.KtPsiFactory
|
|
||||||
import org.jetbrains.kotlin.resolve.calls.inference.createCapturedType
|
|
||||||
import org.jetbrains.kotlin.diagnostics.Severity
|
|
||||||
import org.jetbrains.kotlin.types.typesApproximation.approximateCapturedTypesIfNecessary
|
import org.jetbrains.kotlin.types.typesApproximation.approximateCapturedTypesIfNecessary
|
||||||
import java.util.ArrayList
|
import java.io.File
|
||||||
import org.jetbrains.kotlin.types.TypeProjection
|
import java.util.*
|
||||||
import org.jetbrains.kotlin.descriptors.TypeParameterDescriptor
|
|
||||||
import org.jetbrains.kotlin.resolve.jvm.platform.JvmPlatform
|
|
||||||
|
|
||||||
public class CapturedTypeApproximationTest() : KotlinLiteFixture() {
|
public class CapturedTypeApproximationTest() : KotlinLiteFixture() {
|
||||||
|
|
||||||
@@ -85,7 +84,7 @@ public class CapturedTypeApproximationTest() : KotlinLiteFixture() {
|
|||||||
fun createTestSubstitutor(testSubstitution: Map<TypeParameterDescriptor, TypeProjection>): TypeSubstitutor {
|
fun createTestSubstitutor(testSubstitution: Map<TypeParameterDescriptor, TypeProjection>): TypeSubstitutor {
|
||||||
val substitutionContext = testSubstitution.map {
|
val substitutionContext = testSubstitution.map {
|
||||||
val (typeParameter, typeProjection) = it
|
val (typeParameter, typeProjection) = it
|
||||||
typeParameter.getTypeConstructor() to TypeProjectionImpl(createCapturedType(typeProjection))
|
typeParameter.typeConstructor to TypeProjectionImpl(createCapturedType(typeProjection))
|
||||||
}.toMap()
|
}.toMap()
|
||||||
return TypeSubstitutor.create(substitutionContext)
|
return TypeSubstitutor.create(substitutionContext)
|
||||||
}
|
}
|
||||||
@@ -111,7 +110,9 @@ public class CapturedTypeApproximationTest() : KotlinLiteFixture() {
|
|||||||
val typeWithCapturedType = typeSubstitutor.substituteWithoutApproximation(TypeProjectionImpl(INVARIANT, type!!))!!.getType()
|
val typeWithCapturedType = typeSubstitutor.substituteWithoutApproximation(TypeProjectionImpl(INVARIANT, type!!))!!.getType()
|
||||||
|
|
||||||
val (lower, upper) = approximateCapturedTypes(typeWithCapturedType)
|
val (lower, upper) = approximateCapturedTypes(typeWithCapturedType)
|
||||||
val substitution = approximateCapturedTypesIfNecessary(TypeProjectionImpl(INVARIANT, typeWithCapturedType))
|
val substitution =
|
||||||
|
approximateCapturedTypesIfNecessary(
|
||||||
|
TypeProjectionImpl(INVARIANT, typeWithCapturedType), approximateContravariant = false)
|
||||||
|
|
||||||
append(" ")
|
append(" ")
|
||||||
for (typeParameter in testSubstitution.keySet()) {
|
for (typeParameter in testSubstitution.keySet()) {
|
||||||
|
|||||||
+14
-1
@@ -41,7 +41,20 @@ public abstract class AbstractReceiverParameterDescriptor extends DeclarationDes
|
|||||||
@Override
|
@Override
|
||||||
public ReceiverParameterDescriptor substitute(@NotNull TypeSubstitutor substitutor) {
|
public ReceiverParameterDescriptor substitute(@NotNull TypeSubstitutor substitutor) {
|
||||||
if (substitutor.isEmpty()) return this;
|
if (substitutor.isEmpty()) return this;
|
||||||
KotlinType substitutedType = substitutor.substitute(getType(), Variance.INVARIANT);
|
|
||||||
|
KotlinType substitutedType;
|
||||||
|
if (getContainingDeclaration() instanceof ClassDescriptor) {
|
||||||
|
// Due to some reasons we check that receiver value type is a subtype of dispatch parameter
|
||||||
|
// (although we get members exactly from it's scope)
|
||||||
|
// So to make receiver with projections be a subtype of parameter's type with captured type arguments,
|
||||||
|
// we approximate latter to it's upper bound.
|
||||||
|
// See approximateDispatchReceiver.kt test for clarification
|
||||||
|
substitutedType = substitutor.substitute(getType(), Variance.OUT_VARIANCE);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
substitutedType = substitutor.substitute(getType(), Variance.INVARIANT);
|
||||||
|
}
|
||||||
|
|
||||||
if (substitutedType == null) return null;
|
if (substitutedType == null) return null;
|
||||||
|
|
||||||
return new ReceiverParameterDescriptorImpl(getContainingDeclaration(), new TransientReceiver(substitutedType));
|
return new ReceiverParameterDescriptorImpl(getContainingDeclaration(), new TransientReceiver(substitutedType));
|
||||||
|
|||||||
+31
@@ -96,3 +96,34 @@ public class CapturedType(
|
|||||||
public fun createCapturedType(typeProjection: TypeProjection): KotlinType = CapturedType(typeProjection)
|
public fun createCapturedType(typeProjection: TypeProjection): KotlinType = CapturedType(typeProjection)
|
||||||
|
|
||||||
public fun KotlinType.isCaptured(): Boolean = getConstructor() is CapturedTypeConstructor
|
public fun KotlinType.isCaptured(): Boolean = getConstructor() is CapturedTypeConstructor
|
||||||
|
|
||||||
|
public fun TypeSubstitution.wrapWithCapturingSubstitution(): TypeSubstitution =
|
||||||
|
if (this is IndexedParametersSubstitution)
|
||||||
|
IndexedParametersSubstitution(
|
||||||
|
this.parameters,
|
||||||
|
this.arguments.zip(this.parameters).map {
|
||||||
|
it.first.createCapturedIfNeeded(it.second)
|
||||||
|
}.toTypedArray(),
|
||||||
|
approximateCapturedTypes = true)
|
||||||
|
else
|
||||||
|
object : DelegatedTypeSubstitution(this@wrapWithCapturingSubstitution) {
|
||||||
|
override fun approximateContravariantCapturedTypes() = true
|
||||||
|
override fun get(key: KotlinType) = super.get(key)?.createCapturedIfNeeded(key.constructor.declarationDescriptor as? TypeParameterDescriptor)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun TypeProjection.createCapturedIfNeeded(typeParameterDescriptor: TypeParameterDescriptor?): TypeProjection {
|
||||||
|
if (typeParameterDescriptor == null || projectionKind == Variance.INVARIANT) return this
|
||||||
|
|
||||||
|
// Treat consistent projections as invariant
|
||||||
|
if (typeParameterDescriptor.variance == projectionKind) {
|
||||||
|
// TODO: Make star projection type lazy
|
||||||
|
return if (isStarProjection)
|
||||||
|
TypeProjectionImpl(object : DelegatingType() {
|
||||||
|
override fun getDelegate() = this@createCapturedIfNeeded.type
|
||||||
|
})
|
||||||
|
else
|
||||||
|
TypeProjectionImpl(this@createCapturedIfNeeded.type)
|
||||||
|
}
|
||||||
|
|
||||||
|
return TypeProjectionImpl(createCapturedType(this))
|
||||||
|
}
|
||||||
|
|||||||
@@ -19,29 +19,37 @@ package org.jetbrains.kotlin.resolve.scopes
|
|||||||
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
|
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
|
||||||
import org.jetbrains.kotlin.incremental.components.LookupLocation
|
import org.jetbrains.kotlin.incremental.components.LookupLocation
|
||||||
import org.jetbrains.kotlin.name.Name
|
import org.jetbrains.kotlin.name.Name
|
||||||
|
import org.jetbrains.kotlin.resolve.calls.inference.wrapWithCapturingSubstitution
|
||||||
import org.jetbrains.kotlin.types.TypeSubstitutor
|
import org.jetbrains.kotlin.types.TypeSubstitutor
|
||||||
import org.jetbrains.kotlin.utils.Printer
|
import org.jetbrains.kotlin.utils.Printer
|
||||||
import org.jetbrains.kotlin.utils.newHashSetWithExpectedSize
|
import org.jetbrains.kotlin.utils.newHashSetWithExpectedSize
|
||||||
|
import org.jetbrains.kotlin.utils.sure
|
||||||
import java.util.*
|
import java.util.*
|
||||||
|
|
||||||
public class SubstitutingScope(private val workerScope: MemberScope, private val substitutor: TypeSubstitutor) : MemberScope {
|
public class SubstitutingScope(private val workerScope: MemberScope, givenSubstitutor: TypeSubstitutor) : MemberScope {
|
||||||
|
|
||||||
private var substitutedDescriptors: MutableMap<DeclarationDescriptor, DeclarationDescriptor?>? = null
|
private val substitutor = givenSubstitutor.substitution.wrapWithCapturingSubstitution().buildSubstitutor()
|
||||||
|
|
||||||
|
private var substitutedDescriptors: MutableMap<DeclarationDescriptor, DeclarationDescriptor>? = null
|
||||||
|
|
||||||
private val _allDescriptors by lazy { substitute(workerScope.getContributedDescriptors()) }
|
private val _allDescriptors by lazy { substitute(workerScope.getContributedDescriptors()) }
|
||||||
|
|
||||||
private fun <D : DeclarationDescriptor> substitute(descriptor: D?): D? {
|
private fun <D : DeclarationDescriptor> substitute(descriptor: D): D {
|
||||||
if (descriptor == null) return null
|
if (substitutor.isEmpty) return descriptor
|
||||||
if (substitutor.isEmpty()) return descriptor
|
|
||||||
|
|
||||||
if (substitutedDescriptors == null) {
|
if (substitutedDescriptors == null) {
|
||||||
substitutedDescriptors = HashMap<DeclarationDescriptor, DeclarationDescriptor?>()
|
substitutedDescriptors = HashMap<DeclarationDescriptor, DeclarationDescriptor>()
|
||||||
}
|
}
|
||||||
|
|
||||||
val substituted = substitutedDescriptors!!.getOrPut(descriptor, { descriptor.substitute(substitutor) })
|
val substituted = substitutedDescriptors!!.getOrPut(descriptor, {
|
||||||
|
descriptor.substitute(substitutor).sure {
|
||||||
|
"We expect that no conflict should happen while substitution is guaranteed to generate invariant projection, " +
|
||||||
|
"but $descriptor substitution fails"
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
@Suppress("UNCHECKED_CAST")
|
@Suppress("UNCHECKED_CAST")
|
||||||
return substituted as D?
|
return substituted as D
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun <D : DeclarationDescriptor> substitute(descriptors: Collection<D>): Collection<D> {
|
private fun <D : DeclarationDescriptor> substitute(descriptors: Collection<D>): Collection<D> {
|
||||||
@@ -51,9 +59,7 @@ public class SubstitutingScope(private val workerScope: MemberScope, private val
|
|||||||
val result = newHashSetWithExpectedSize<D>(descriptors.size)
|
val result = newHashSetWithExpectedSize<D>(descriptors.size)
|
||||||
for (descriptor in descriptors) {
|
for (descriptor in descriptors) {
|
||||||
val substitute = substitute(descriptor)
|
val substitute = substitute(descriptor)
|
||||||
if (substitute != null) {
|
result.add(substitute)
|
||||||
result.add(substitute)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return result
|
return result
|
||||||
@@ -61,7 +67,8 @@ public class SubstitutingScope(private val workerScope: MemberScope, private val
|
|||||||
|
|
||||||
override fun getContributedVariables(name: Name, location: LookupLocation) = substitute(workerScope.getContributedVariables(name, location))
|
override fun getContributedVariables(name: Name, location: LookupLocation) = substitute(workerScope.getContributedVariables(name, location))
|
||||||
|
|
||||||
override fun getContributedClassifier(name: Name, location: LookupLocation) = substitute(workerScope.getContributedClassifier(name, location))
|
override fun getContributedClassifier(name: Name, location: LookupLocation) =
|
||||||
|
workerScope.getContributedClassifier(name, location)?.let { substitute(it) }
|
||||||
|
|
||||||
override fun getContributedFunctions(name: Name, location: LookupLocation) = substitute(workerScope.getContributedFunctions(name, location))
|
override fun getContributedFunctions(name: Name, location: LookupLocation) = substitute(workerScope.getContributedFunctions(name, location))
|
||||||
|
|
||||||
|
|||||||
@@ -59,7 +59,7 @@ private fun TypeProjection.toTypeArgument(typeParameter: TypeParameterDescriptor
|
|||||||
Variance.OUT_VARIANCE -> TypeArgument(typeParameter, typeParameter.builtIns.nothingType, type)
|
Variance.OUT_VARIANCE -> TypeArgument(typeParameter, typeParameter.builtIns.nothingType, type)
|
||||||
}
|
}
|
||||||
|
|
||||||
public fun approximateCapturedTypesIfNecessary(typeProjection: TypeProjection?): TypeProjection? {
|
public fun approximateCapturedTypesIfNecessary(typeProjection: TypeProjection?, approximateContravariant: Boolean): TypeProjection? {
|
||||||
if (typeProjection == null) return null
|
if (typeProjection == null) return null
|
||||||
if (typeProjection.isStarProjection()) return typeProjection
|
if (typeProjection.isStarProjection()) return typeProjection
|
||||||
|
|
||||||
@@ -73,10 +73,17 @@ public fun approximateCapturedTypesIfNecessary(typeProjection: TypeProjection?):
|
|||||||
val approximation = approximateCapturedTypes(type)
|
val approximation = approximateCapturedTypes(type)
|
||||||
return TypeProjectionImpl(howThisTypeIsUsed, approximation.upper)
|
return TypeProjectionImpl(howThisTypeIsUsed, approximation.upper)
|
||||||
}
|
}
|
||||||
return substituteCapturedTypes(typeProjection)
|
|
||||||
|
if (approximateContravariant) {
|
||||||
|
// TODO: assert that howThisTypeIsUsed is always IN
|
||||||
|
val approximation = approximateCapturedTypes(type).lower
|
||||||
|
return TypeProjectionImpl(howThisTypeIsUsed, approximation)
|
||||||
|
}
|
||||||
|
|
||||||
|
return substituteCapturedTypesWithProjections(typeProjection)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun substituteCapturedTypes(typeProjection: TypeProjection): TypeProjection? {
|
private fun substituteCapturedTypesWithProjections(typeProjection: TypeProjection): TypeProjection? {
|
||||||
val typeSubstitutor = TypeSubstitutor.create(object : TypeConstructorSubstitution() {
|
val typeSubstitutor = TypeSubstitutor.create(object : TypeConstructorSubstitution() {
|
||||||
override fun get(key: TypeConstructor): TypeProjection? {
|
override fun get(key: TypeConstructor): TypeProjection? {
|
||||||
return (key as? CapturedTypeConstructor)?.typeProjection
|
return (key as? CapturedTypeConstructor)?.typeProjection
|
||||||
|
|||||||
@@ -67,7 +67,7 @@ public class DescriptorSubstitutor {
|
|||||||
for (TypeParameterDescriptor descriptor : typeParameters) {
|
for (TypeParameterDescriptor descriptor : typeParameters) {
|
||||||
TypeParameterDescriptorImpl substituted = substitutedMap.get(descriptor);
|
TypeParameterDescriptorImpl substituted = substitutedMap.get(descriptor);
|
||||||
for (KotlinType upperBound : descriptor.getUpperBounds()) {
|
for (KotlinType upperBound : descriptor.getUpperBounds()) {
|
||||||
KotlinType substitutedBound = substitutor.substitute(upperBound, Variance.INVARIANT);
|
KotlinType substitutedBound = substitutor.substitute(upperBound, Variance.IN_VARIANCE);
|
||||||
assert substitutedBound != null : "Upper bound failed to substitute: " + descriptor;
|
assert substitutedBound != null : "Upper bound failed to substitute: " + descriptor;
|
||||||
substituted.addUpperBound(substitutedBound);
|
substituted.addUpperBound(substitutedBound);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -37,6 +37,7 @@ public class DisjointKeysUnionTypeSubstitution private constructor(
|
|||||||
override fun isEmpty() = false
|
override fun isEmpty() = false
|
||||||
|
|
||||||
override fun approximateCapturedTypes() = first.approximateCapturedTypes() || second.approximateCapturedTypes()
|
override fun approximateCapturedTypes() = first.approximateCapturedTypes() || second.approximateCapturedTypes()
|
||||||
|
override fun approximateContravariantCapturedTypes() = first.approximateContravariantCapturedTypes() || second.approximateContravariantCapturedTypes()
|
||||||
|
|
||||||
override fun filterAnnotations(annotations: Annotations) = second.filterAnnotations(first.filterAnnotations(annotations))
|
override fun filterAnnotations(annotations: Annotations) = second.filterAnnotations(first.filterAnnotations(annotations))
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,6 +16,7 @@
|
|||||||
|
|
||||||
package org.jetbrains.kotlin.types
|
package org.jetbrains.kotlin.types
|
||||||
|
|
||||||
|
import org.jetbrains.kotlin.descriptors.ClassDescriptor
|
||||||
import org.jetbrains.kotlin.descriptors.TypeParameterDescriptor
|
import org.jetbrains.kotlin.descriptors.TypeParameterDescriptor
|
||||||
import org.jetbrains.kotlin.descriptors.annotations.Annotations
|
import org.jetbrains.kotlin.descriptors.annotations.Annotations
|
||||||
|
|
||||||
@@ -34,6 +35,7 @@ public abstract class TypeSubstitution {
|
|||||||
open fun isEmpty(): Boolean = false
|
open fun isEmpty(): Boolean = false
|
||||||
|
|
||||||
open fun approximateCapturedTypes(): Boolean = false
|
open fun approximateCapturedTypes(): Boolean = false
|
||||||
|
open fun approximateContravariantCapturedTypes(): Boolean = false
|
||||||
|
|
||||||
open fun filterAnnotations(annotations: Annotations) = annotations
|
open fun filterAnnotations(annotations: Annotations) = annotations
|
||||||
|
|
||||||
@@ -73,9 +75,10 @@ public abstract class TypeConstructorSubstitution : TypeSubstitution() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public class IndexedParametersSubstitution private constructor(
|
public class IndexedParametersSubstitution(
|
||||||
private val parameters: Array<TypeParameterDescriptor>,
|
val parameters: Array<TypeParameterDescriptor>,
|
||||||
private val arguments: Array<TypeProjection>
|
val arguments: Array<TypeProjection>,
|
||||||
|
private val approximateCapturedTypes: Boolean = false
|
||||||
) : TypeSubstitution() {
|
) : TypeSubstitution() {
|
||||||
init {
|
init {
|
||||||
assert(parameters.size() <= arguments.size()) {
|
assert(parameters.size() <= arguments.size()) {
|
||||||
@@ -89,6 +92,8 @@ public class IndexedParametersSubstitution private constructor(
|
|||||||
|
|
||||||
override fun isEmpty(): Boolean = arguments.isEmpty()
|
override fun isEmpty(): Boolean = arguments.isEmpty()
|
||||||
|
|
||||||
|
override fun approximateContravariantCapturedTypes() = approximateCapturedTypes
|
||||||
|
|
||||||
override fun get(key: KotlinType): TypeProjection? {
|
override fun get(key: KotlinType): TypeProjection? {
|
||||||
val parameter = key.constructor.declarationDescriptor as? TypeParameterDescriptor ?: return null
|
val parameter = key.constructor.declarationDescriptor as? TypeParameterDescriptor ?: return null
|
||||||
val index = parameter.index
|
val index = parameter.index
|
||||||
@@ -164,6 +169,7 @@ private class CompositeTypeSubstitution(
|
|||||||
override fun isEmpty() = first.isEmpty() && second.isEmpty()
|
override fun isEmpty() = first.isEmpty() && second.isEmpty()
|
||||||
|
|
||||||
override fun approximateCapturedTypes() = first.approximateCapturedTypes() || second.approximateCapturedTypes()
|
override fun approximateCapturedTypes() = first.approximateCapturedTypes() || second.approximateCapturedTypes()
|
||||||
|
override fun approximateContravariantCapturedTypes() = first.approximateContravariantCapturedTypes() || second.approximateContravariantCapturedTypes()
|
||||||
|
|
||||||
override fun filterAnnotations(annotations: Annotations): Annotations = second.filterAnnotations(first.filterAnnotations(annotations))
|
override fun filterAnnotations(annotations: Annotations): Annotations = second.filterAnnotations(first.filterAnnotations(annotations))
|
||||||
}
|
}
|
||||||
@@ -174,6 +180,7 @@ public open class DelegatedTypeSubstitution(val substitution: TypeSubstitution):
|
|||||||
override fun isEmpty() = substitution.isEmpty()
|
override fun isEmpty() = substitution.isEmpty()
|
||||||
|
|
||||||
override fun approximateCapturedTypes() = substitution.approximateCapturedTypes()
|
override fun approximateCapturedTypes() = substitution.approximateCapturedTypes()
|
||||||
|
override fun approximateContravariantCapturedTypes() = substitution.approximateContravariantCapturedTypes()
|
||||||
|
|
||||||
override fun filterAnnotations(annotations: Annotations) = substitution.filterAnnotations(annotations)
|
override fun filterAnnotations(annotations: Annotations) = substitution.filterAnnotations(annotations)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -104,10 +104,11 @@ public class TypeSubstitutor {
|
|||||||
@Nullable
|
@Nullable
|
||||||
public TypeProjection substitute(@NotNull TypeProjection typeProjection) {
|
public TypeProjection substitute(@NotNull TypeProjection typeProjection) {
|
||||||
TypeProjection substitutedTypeProjection = substituteWithoutApproximation(typeProjection);
|
TypeProjection substitutedTypeProjection = substituteWithoutApproximation(typeProjection);
|
||||||
if (!substitution.approximateCapturedTypes()) {
|
if (!substitution.approximateCapturedTypes() && !substitution.approximateContravariantCapturedTypes()) {
|
||||||
return substitutedTypeProjection;
|
return substitutedTypeProjection;
|
||||||
}
|
}
|
||||||
return CapturedTypeApproximationKt.approximateCapturedTypesIfNecessary(substitutedTypeProjection);
|
return CapturedTypeApproximationKt.approximateCapturedTypesIfNecessary(
|
||||||
|
substitutedTypeProjection, substitution.approximateContravariantCapturedTypes());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
// PARAM_TYPES: kotlin.Array<T>, kotlin.Cloneable, java.io.Serializable, Any
|
// PARAM_TYPES: kotlin.Array<T>, Cloneable, java.io.Serializable, Any
|
||||||
// PARAM_DESCRIPTOR: public fun <T> kotlin.Array<T>.test(): kotlin.Unit defined in root package
|
// PARAM_DESCRIPTOR: public fun <T> kotlin.Array<T>.test(): kotlin.Unit defined in root package
|
||||||
// SIBLING:
|
// SIBLING:
|
||||||
fun <T> Array<T>.test() {
|
fun <T> Array<T>.test() {
|
||||||
|
|||||||
+1
-1
@@ -1,4 +1,4 @@
|
|||||||
// PARAM_TYPES: kotlin.Array<T>, kotlin.Cloneable, java.io.Serializable, Any
|
// PARAM_TYPES: kotlin.Array<T>, Cloneable, java.io.Serializable, Any
|
||||||
// PARAM_DESCRIPTOR: public fun <T> kotlin.Array<T>.test(): kotlin.Unit defined in root package
|
// PARAM_DESCRIPTOR: public fun <T> kotlin.Array<T>.test(): kotlin.Unit defined in root package
|
||||||
// SIBLING:
|
// SIBLING:
|
||||||
fun <T> Array<T>.test() {
|
fun <T> Array<T>.test() {
|
||||||
|
|||||||
+1
-1
@@ -1,4 +1,4 @@
|
|||||||
// PARAM_TYPES: kotlin.String, Comparable<String>, CharSequence, java.io.Serializable, kotlin.Any
|
// PARAM_TYPES: kotlin.String, Comparable<String>, CharSequence, java.io.Serializable, Any
|
||||||
// PARAM_TYPES: X<kotlin.Any>
|
// PARAM_TYPES: X<kotlin.Any>
|
||||||
// PARAM_DESCRIPTOR: value-parameter val s: kotlin.String? defined in foo
|
// PARAM_DESCRIPTOR: value-parameter val s: kotlin.String? defined in foo
|
||||||
// PARAM_DESCRIPTOR: value-parameter val x: X<kotlin.Any> defined in foo
|
// PARAM_DESCRIPTOR: value-parameter val x: X<kotlin.Any> defined in foo
|
||||||
|
|||||||
Vendored
+1
-1
@@ -1,4 +1,4 @@
|
|||||||
// PARAM_TYPES: kotlin.String, Comparable<String>, CharSequence, java.io.Serializable, kotlin.Any
|
// PARAM_TYPES: kotlin.String, Comparable<String>, CharSequence, java.io.Serializable, Any
|
||||||
// PARAM_TYPES: X<kotlin.Any>
|
// PARAM_TYPES: X<kotlin.Any>
|
||||||
// PARAM_DESCRIPTOR: value-parameter val s: kotlin.String? defined in foo
|
// PARAM_DESCRIPTOR: value-parameter val s: kotlin.String? defined in foo
|
||||||
// PARAM_DESCRIPTOR: value-parameter val x: X<kotlin.Any> defined in foo
|
// PARAM_DESCRIPTOR: value-parameter val x: X<kotlin.Any> defined in foo
|
||||||
|
|||||||
+1
-1
@@ -1,4 +1,4 @@
|
|||||||
// PARAM_TYPES: kotlin.String, Comparable<String>, CharSequence, java.io.Serializable, kotlin.Any
|
// PARAM_TYPES: kotlin.String, Comparable<String>, CharSequence, java.io.Serializable, Any
|
||||||
// PARAM_DESCRIPTOR: public fun kotlin.String.test(): kotlin.Unit defined in root package
|
// PARAM_DESCRIPTOR: public fun kotlin.String.test(): kotlin.Unit defined in root package
|
||||||
fun String.foo(f: () -> Unit) {
|
fun String.foo(f: () -> Unit) {
|
||||||
f()
|
f()
|
||||||
|
|||||||
+1
-1
@@ -1,4 +1,4 @@
|
|||||||
// PARAM_TYPES: kotlin.String, Comparable<String>, CharSequence, java.io.Serializable, kotlin.Any
|
// PARAM_TYPES: kotlin.String, Comparable<String>, CharSequence, java.io.Serializable, Any
|
||||||
// PARAM_DESCRIPTOR: public fun kotlin.String.test(): kotlin.Unit defined in root package
|
// PARAM_DESCRIPTOR: public fun kotlin.String.test(): kotlin.Unit defined in root package
|
||||||
fun String.foo(f: () -> Unit) {
|
fun String.foo(f: () -> Unit) {
|
||||||
f()
|
f()
|
||||||
|
|||||||
Reference in New Issue
Block a user