[FE] KT-51234 Check subtyping between context receivers

This commit is contained in:
Anastasia.Shadrina
2022-03-31 00:50:23 +07:00
committed by teamcity
parent a3fa2dc9bf
commit 292c0c4383
14 changed files with 714 additions and 22 deletions
@@ -3,7 +3,7 @@
class Box<E>(val x: E)
class A<X, Y> {
class A<X, Y : Number> {
context(Box<X>, Y)
fun foo(): String = x.toString() + this@Y.toString()
@@ -12,7 +12,7 @@ class A<X, Y> {
}
context(Box<X>, Y)
fun <X, Y> bar(): String = x.toString() + this@Y.toString()
fun <X, Y : Number> bar(): String = x.toString() + this@Y.toString()
fun box(): String {
return with(Box("OK")) {
@@ -0,0 +1,221 @@
// !DIAGNOSTICS: -UNCHECKED_CAST
// !LANGUAGE: +ContextReceivers
interface A
interface B : A
typealias C = B
interface Inv<T>
interface Cov<out T>
// Functions
context(A, A)
fun f1() {}
context(A, B)
fun f2() {}
context(A, C)
fun f3() {}
context(B, C)
fun f4() {}
context(C, C)
fun f5() {}
context(A, A, A)
fun f6() {}
context(Inv<A>, Inv<B>)
fun f7() {}
context(Inv<A>, Inv<A>)
fun f8() {}
context(Inv<T>, Inv<A>)
fun <T> f9() {}
context(Cov<A>, Cov<B>)
fun f10() {}
context(Cov<T>, Cov<A>)
fun <T> f11() {}
context(T, A)
fun <T> f12() {}
// Classes
context(A, A)
class C1 {
context(A, A)
val p: Any get() = 42
context(A, A)
fun m() {}
}
context(A, B)
class C2 {
context(A, B)
val p: Any get() = 42
context(A, B)
fun m() {}
}
context(A, C)
class C3 {
context(A, C)
val p: Any get() = 42
context(A, C)
fun m() {}
}
context(B, C)
class C4 {
context(B, C)
val p: Any get() = 42
context(B, C)
fun m() {}
}
context(C, C)
class C5 {
context(C, C)
val p: Any get() = 42
context(C, C)
fun m() {}
}
context(A, A, A)
class C6 {
context(A, A, A)
val p: Any get() = 42
context(A, A, A)
fun m() {}
}
context(Inv<A>, Inv<B>)
class C7 {
context(Inv<A>, Inv<B>)
val p: Any get() = 42
context(Inv<A>, Inv<B>)
fun m() {}
}
context(Inv<A>, Inv<A>)
class C8 {
context(Inv<A>, Inv<A>)
val p: Any get() = 42
context(Inv<A>, Inv<A>)
fun m() {}
}
context(Inv<T>, Inv<A>)
class C9<T> {
context(Inv<T>, Inv<A>)
val p: Any get() = 42
context(Inv<T>, Inv<A>)
fun m() {}
}
context(Cov<A>, Cov<B>)
class C10 {
context(Cov<A>, Cov<B>)
val p: Any get() = 42
context(Cov<A>, Cov<B>)
fun m() {}
}
context(Cov<T>, Cov<A>)
class C11<T> {
context(Cov<T>, Cov<A>)
val p: Any get() = 42
context(Cov<T>, Cov<A>)
fun m() {}
}
context(T, A)
class C12<T> {
context(T, A)
val p: Any get() = 42
context(T, A)
fun m() {}
}
// Properties
context(A, A)
val p1: Any?
get() { return null }
context(A, B)
val p2: Any?
get() { return null }
context(A, C)
val p3: Any?
get() { return null }
context(B, C)
val p4: Any?
get() { return null }
context(C, C)
val p5: Any?
get() { return null }
context(A, A, A)
val p6: Any?
get() { return null }
context(Inv<A>, Inv<B>)
val p7: Any?
get() { return null }
context(Inv<A>, Inv<A>)
val p8: Any?
get() { return null }
context(Inv<T>, Inv<A>)
val <T> p9: Any?
get() { return null }
context(Cov<A>, Cov<B>)
val p10: Any?
get() { return null }
context(Cov<T>, Cov<A>)
val <T> p11: Any?
get() { return null }
context(T, A)
val <T> p12: Any?
get() { return null }
// Function types
// Function types are processed with the same function that is used for checking contextual declarations
// So we check here only one simple case: `context(A, B)`
context(A, B)
fun f(g: context(A, B) () -> Unit, value: Any): context(A, B) () -> Unit {
return value as (context(A, B) () -> Unit)
}
fun test() {
val lf: context(A, B) () -> Unit = { }
}
@@ -0,0 +1,221 @@
// !DIAGNOSTICS: -UNCHECKED_CAST
// !LANGUAGE: +ContextReceivers
interface A
interface B : A
typealias C = B
interface Inv<T>
interface Cov<out T>
// Functions
<!SUBTYPING_BETWEEN_CONTEXT_RECEIVERS!>context(A, A)<!>
fun f1() {}
<!SUBTYPING_BETWEEN_CONTEXT_RECEIVERS!>context(A, B)<!>
fun f2() {}
<!SUBTYPING_BETWEEN_CONTEXT_RECEIVERS!>context(A, C)<!>
fun f3() {}
<!SUBTYPING_BETWEEN_CONTEXT_RECEIVERS!>context(B, C)<!>
fun f4() {}
<!SUBTYPING_BETWEEN_CONTEXT_RECEIVERS!>context(C, C)<!>
fun f5() {}
<!SUBTYPING_BETWEEN_CONTEXT_RECEIVERS!>context(A, A, A)<!>
fun f6() {}
context(Inv<A>, Inv<B>)
fun f7() {}
<!SUBTYPING_BETWEEN_CONTEXT_RECEIVERS!>context(Inv<A>, Inv<A>)<!>
fun f8() {}
<!SUBTYPING_BETWEEN_CONTEXT_RECEIVERS!>context(Inv<T>, Inv<A>)<!>
fun <T> f9() {}
<!SUBTYPING_BETWEEN_CONTEXT_RECEIVERS!>context(Cov<A>, Cov<B>)<!>
fun f10() {}
<!SUBTYPING_BETWEEN_CONTEXT_RECEIVERS!>context(Cov<T>, Cov<A>)<!>
fun <T> f11() {}
<!SUBTYPING_BETWEEN_CONTEXT_RECEIVERS!>context(T, A)<!>
fun <T> f12() {}
// Classes
<!SUBTYPING_BETWEEN_CONTEXT_RECEIVERS!>context(A, A)<!>
class C1 {
<!SUBTYPING_BETWEEN_CONTEXT_RECEIVERS!>context(A, A)<!>
val p: Any get() = 42
<!SUBTYPING_BETWEEN_CONTEXT_RECEIVERS!>context(A, A)<!>
fun m() {}
}
<!SUBTYPING_BETWEEN_CONTEXT_RECEIVERS!>context(A, B)<!>
class C2 {
<!SUBTYPING_BETWEEN_CONTEXT_RECEIVERS!>context(A, B)<!>
val p: Any get() = 42
<!SUBTYPING_BETWEEN_CONTEXT_RECEIVERS!>context(A, B)<!>
fun m() {}
}
<!SUBTYPING_BETWEEN_CONTEXT_RECEIVERS!>context(A, C)<!>
class C3 {
<!SUBTYPING_BETWEEN_CONTEXT_RECEIVERS!>context(A, C)<!>
val p: Any get() = 42
<!SUBTYPING_BETWEEN_CONTEXT_RECEIVERS!>context(A, C)<!>
fun m() {}
}
<!SUBTYPING_BETWEEN_CONTEXT_RECEIVERS!>context(B, C)<!>
class C4 {
<!SUBTYPING_BETWEEN_CONTEXT_RECEIVERS!>context(B, C)<!>
val p: Any get() = 42
<!SUBTYPING_BETWEEN_CONTEXT_RECEIVERS!>context(B, C)<!>
fun m() {}
}
<!SUBTYPING_BETWEEN_CONTEXT_RECEIVERS!>context(C, C)<!>
class C5 {
<!SUBTYPING_BETWEEN_CONTEXT_RECEIVERS!>context(C, C)<!>
val p: Any get() = 42
<!SUBTYPING_BETWEEN_CONTEXT_RECEIVERS!>context(C, C)<!>
fun m() {}
}
<!SUBTYPING_BETWEEN_CONTEXT_RECEIVERS!>context(A, A, A)<!>
class C6 {
<!SUBTYPING_BETWEEN_CONTEXT_RECEIVERS!>context(A, A, A)<!>
val p: Any get() = 42
<!SUBTYPING_BETWEEN_CONTEXT_RECEIVERS!>context(A, A, A)<!>
fun m() {}
}
context(Inv<A>, Inv<B>)
class C7 {
context(Inv<A>, Inv<B>)
val p: Any get() = 42
context(Inv<A>, Inv<B>)
fun m() {}
}
<!SUBTYPING_BETWEEN_CONTEXT_RECEIVERS!>context(Inv<A>, Inv<A>)<!>
class C8 {
<!SUBTYPING_BETWEEN_CONTEXT_RECEIVERS!>context(Inv<A>, Inv<A>)<!>
val p: Any get() = 42
<!SUBTYPING_BETWEEN_CONTEXT_RECEIVERS!>context(Inv<A>, Inv<A>)<!>
fun m() {}
}
<!SUBTYPING_BETWEEN_CONTEXT_RECEIVERS!>context(Inv<T>, Inv<A>)<!>
class C9<T> {
<!SUBTYPING_BETWEEN_CONTEXT_RECEIVERS!>context(Inv<T>, Inv<A>)<!>
val p: Any get() = 42
<!SUBTYPING_BETWEEN_CONTEXT_RECEIVERS!>context(Inv<T>, Inv<A>)<!>
fun m() {}
}
<!SUBTYPING_BETWEEN_CONTEXT_RECEIVERS!>context(Cov<A>, Cov<B>)<!>
class C10 {
<!SUBTYPING_BETWEEN_CONTEXT_RECEIVERS!>context(Cov<A>, Cov<B>)<!>
val p: Any get() = 42
<!SUBTYPING_BETWEEN_CONTEXT_RECEIVERS!>context(Cov<A>, Cov<B>)<!>
fun m() {}
}
<!SUBTYPING_BETWEEN_CONTEXT_RECEIVERS!>context(Cov<T>, Cov<A>)<!>
class C11<T> {
<!SUBTYPING_BETWEEN_CONTEXT_RECEIVERS!>context(Cov<T>, Cov<A>)<!>
val p: Any get() = 42
<!SUBTYPING_BETWEEN_CONTEXT_RECEIVERS!>context(Cov<T>, Cov<A>)<!>
fun m() {}
}
<!SUBTYPING_BETWEEN_CONTEXT_RECEIVERS!>context(T, A)<!>
class C12<T> {
<!SUBTYPING_BETWEEN_CONTEXT_RECEIVERS!>context(T, A)<!>
val p: Any get() = 42
<!SUBTYPING_BETWEEN_CONTEXT_RECEIVERS!>context(T, A)<!>
fun m() {}
}
// Properties
<!SUBTYPING_BETWEEN_CONTEXT_RECEIVERS!>context(A, A)<!>
val p1: Any?
get() { return null }
<!SUBTYPING_BETWEEN_CONTEXT_RECEIVERS!>context(A, B)<!>
val p2: Any?
get() { return null }
<!SUBTYPING_BETWEEN_CONTEXT_RECEIVERS!>context(A, C)<!>
val p3: Any?
get() { return null }
<!SUBTYPING_BETWEEN_CONTEXT_RECEIVERS!>context(B, C)<!>
val p4: Any?
get() { return null }
<!SUBTYPING_BETWEEN_CONTEXT_RECEIVERS!>context(C, C)<!>
val p5: Any?
get() { return null }
<!SUBTYPING_BETWEEN_CONTEXT_RECEIVERS!>context(A, A, A)<!>
val p6: Any?
get() { return null }
context(Inv<A>, Inv<B>)
val p7: Any?
get() { return null }
<!SUBTYPING_BETWEEN_CONTEXT_RECEIVERS!>context(Inv<A>, Inv<A>)<!>
val p8: Any?
get() { return null }
<!SUBTYPING_BETWEEN_CONTEXT_RECEIVERS!>context(Inv<T>, Inv<A>)<!>
val <T> p9: Any?
get() { return null }
<!SUBTYPING_BETWEEN_CONTEXT_RECEIVERS!>context(Cov<A>, Cov<B>)<!>
val p10: Any?
get() { return null }
<!SUBTYPING_BETWEEN_CONTEXT_RECEIVERS!>context(Cov<T>, Cov<A>)<!>
val <T> p11: Any?
get() { return null }
<!SUBTYPING_BETWEEN_CONTEXT_RECEIVERS!>context(T, A)<!>
val <T> p12: Any?
get() { return null }
// Function types
// Function types are processed with the same function that is used for checking contextual declarations
// So we check here only one simple case: `context(A, B)`
<!SUBTYPING_BETWEEN_CONTEXT_RECEIVERS!>context(A, B)<!>
fun f(g: <!SUBTYPING_BETWEEN_CONTEXT_RECEIVERS!>context(A, B)<!> () -> Unit, value: Any): <!SUBTYPING_BETWEEN_CONTEXT_RECEIVERS!>context(A, B)<!> () -> Unit {
return value as (<!SUBTYPING_BETWEEN_CONTEXT_RECEIVERS!>context(A, B)<!> () -> Unit)
}
fun test() {
val lf: <!SUBTYPING_BETWEEN_CONTEXT_RECEIVERS!>context(A, B)<!> () -> Unit = { }
}
@@ -0,0 +1,161 @@
package
context(A, A) public val p1: kotlin.Any?
context(Cov<A>, Cov<B>) public val p10: kotlin.Any?
context(Cov<T>, Cov<A>) public val </*0*/ T> p11: kotlin.Any?
context(T, A) public val </*0*/ T> p12: kotlin.Any?
context(A, B) public val p2: kotlin.Any?
context(A, C /* = B */) public val p3: kotlin.Any?
context(B, C /* = B */) public val p4: kotlin.Any?
context(C /* = B */, C /* = B */) public val p5: kotlin.Any?
context(A, A, A) public val p6: kotlin.Any?
context(Inv<A>, Inv<B>) public val p7: kotlin.Any?
context(Inv<A>, Inv<A>) public val p8: kotlin.Any?
context(Inv<T>, Inv<A>) public val </*0*/ T> p9: kotlin.Any?
context(A, B) public fun f(/*0*/ g: context(A, B) () -> kotlin.Unit, /*1*/ value: kotlin.Any): context(A, B) () -> kotlin.Unit
context(A, A) public fun f1(): kotlin.Unit
context(Cov<A>, Cov<B>) public fun f10(): kotlin.Unit
context(Cov<T>, Cov<A>) public fun </*0*/ T> f11(): kotlin.Unit
context(T, A) public fun </*0*/ T> f12(): kotlin.Unit
context(A, B) public fun f2(): kotlin.Unit
context(A, C /* = B */) public fun f3(): kotlin.Unit
context(B, C /* = B */) public fun f4(): kotlin.Unit
context(C /* = B */, C /* = B */) public fun f5(): kotlin.Unit
context(A, A, A) public fun f6(): kotlin.Unit
context(Inv<A>, Inv<B>) public fun f7(): kotlin.Unit
context(Inv<A>, Inv<A>) public fun f8(): kotlin.Unit
context(Inv<T>, Inv<A>) public fun </*0*/ T> f9(): kotlin.Unit
public fun test(): kotlin.Unit
public interface 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 B : 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
}
context(A, A) public final class C1 {
public constructor C1()
context(A, A) public final val p: kotlin.Any
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
context(A, A) public final fun m(): kotlin.Unit
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
}
context(Cov<A>, Cov<B>) public final class C10 {
public constructor C10()
context(Cov<A>, Cov<B>) public final val p: kotlin.Any
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
context(Cov<A>, Cov<B>) public final fun m(): kotlin.Unit
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
}
context(Cov<T>, Cov<A>) public final class C11</*0*/ T> {
public constructor C11</*0*/ T>()
context(Cov<T>, Cov<A>) public final val p: kotlin.Any
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
context(Cov<T>, Cov<A>) public final fun m(): kotlin.Unit
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
}
context(T, A) public final class C12</*0*/ T> {
public constructor C12</*0*/ T>()
context(T, A) public final val p: kotlin.Any
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
context(T, A) public final fun m(): kotlin.Unit
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
}
context(A, B) public final class C2 {
public constructor C2()
context(A, B) public final val p: kotlin.Any
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
context(A, B) public final fun m(): kotlin.Unit
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
}
context(A, C /* = B */) public final class C3 {
public constructor C3()
context(A, C /* = B */) public final val p: kotlin.Any
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
context(A, C /* = B */) public final fun m(): kotlin.Unit
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
}
context(B, C /* = B */) public final class C4 {
public constructor C4()
context(B, C /* = B */) public final val p: kotlin.Any
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
context(B, C /* = B */) public final fun m(): kotlin.Unit
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
}
context(C /* = B */, C /* = B */) public final class C5 {
public constructor C5()
context(C /* = B */, C /* = B */) public final val p: kotlin.Any
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
context(C /* = B */, C /* = B */) public final fun m(): kotlin.Unit
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
}
context(A, A, A) public final class C6 {
public constructor C6()
context(A, A, A) public final val p: kotlin.Any
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
context(A, A, A) public final fun m(): kotlin.Unit
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
}
context(Inv<A>, Inv<B>) public final class C7 {
public constructor C7()
context(Inv<A>, Inv<B>) public final val p: kotlin.Any
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
context(Inv<A>, Inv<B>) public final fun m(): kotlin.Unit
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
}
context(Inv<A>, Inv<A>) public final class C8 {
public constructor C8()
context(Inv<A>, Inv<A>) public final val p: kotlin.Any
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
context(Inv<A>, Inv<A>) public final fun m(): kotlin.Unit
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
}
context(Inv<T>, Inv<A>) public final class C9</*0*/ T> {
public constructor C9</*0*/ T>()
context(Inv<T>, Inv<A>) public final val p: kotlin.Any
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
context(Inv<T>, Inv<A>) public final fun m(): kotlin.Unit
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
}
public interface Cov</*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 interface Inv</*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 typealias C = B