interface A { fun foo() } interface B { fun bar() } interface C { fun baz() } interface Inv() { fun k(): K fun t(): T } typealias Inv0 = Inv typealias Inv1 = Inv typealias Inv2 = Inv typealias Inv3 = Inv fun testBase(inv: Inv) { inv.k() inv.t() } fun test_0(inv: Inv0) { inv.k().foo() inv.t().bar() } fun test_1(inv: Inv1) { inv.k().foo() inv.t().bar() } fun test_2(inv: Inv2) { inv.k().foo() inv.t().bar() } fun test_3(inv: Inv3) { inv.k().foo() inv.t().bar() inv.t().baz() } typealias Inv02 = Inv, C1> fun test_4(inv: Inv02) { inv.k().k().foo() inv.k().t().bar() inv.t().baz() } interface In { fun take(x: T) } interface Out { fun value(): T } interface Invariant { fun take(x: T) fun value(): T } typealias In1 = In typealias Out1 = Out typealias Invariant1 = Invariant fun test_5(a: A, in1: In1, in2: In1, in3: In1) { in1.take(a) in2.take(a) in3.take(a) } fun test_6(a: A, out1: Out1, out2: Out1, out3: Out1) { out1.value().foo() out2.value().foo() out3.value().foo() } fun test_7(a: A, inv1: Invariant1, inv2: Invariant1, inv3: Invariant1) { inv1.value().foo() inv2.value().foo() inv3.value().foo() inv1.take(a) inv2.take(a) inv3.take(a) }