|
| 1 | +// RUN: %target-sil-opt -enable-sil-verify-all -generic-specializer %s | FileCheck %s |
| 2 | +// REQUIRES: rdar://25447450 |
| 3 | + |
| 4 | + |
| 5 | +sil_stage canonical |
| 6 | + |
| 7 | +import Builtin |
| 8 | +import Swift |
| 9 | + |
| 10 | +public protocol RefProto { |
| 11 | + associatedtype T |
| 12 | + var me: Ref<Self.T> { get } |
| 13 | +} |
| 14 | + |
| 15 | +public final class Ref<T> : RefProto { |
| 16 | + public final var me: Ref<T> { get } |
| 17 | + deinit |
| 18 | + init() |
| 19 | +} |
| 20 | + |
| 21 | +extension RefProto { |
| 22 | + public func merge<U>(other: Ref<U>) -> Ref<(Self.T, U)> |
| 23 | +} |
| 24 | + |
| 25 | +public protocol ValProto { |
| 26 | + associatedtype T |
| 27 | + var me: Val<Self.T> { get } |
| 28 | +} |
| 29 | + |
| 30 | +extension ValProto { |
| 31 | + public func merge<U>(other: Val<U>) -> Val<(Self.T, U)> |
| 32 | +} |
| 33 | + |
| 34 | +public struct Val<T> : ValProto { |
| 35 | + public var me: Val<T> { get } |
| 36 | + init() |
| 37 | +} |
| 38 | + |
| 39 | +sil @coerce : $@convention(thin) <T, U, V> (@owned @callee_owned (@owned Ref<T>) -> @owned @callee_owned (@owned Ref<U>) -> @owned Ref<V>) -> @owned @callee_owned (Val<U>) -> Val<V> |
| 40 | + |
| 41 | +sil @merge : $@convention(method) <Self where Self : RefProto><U> (@owned Ref<U>, @in_guaranteed Self) -> @owned Ref<(Self.T, U)> { |
| 42 | + |
| 43 | +bb0(%0 : $Ref<U>, %1 : $*Self): |
| 44 | + %2 = alloc_ref $Ref<(Self.T, U)> |
| 45 | + strong_release %0 : $Ref<U> |
| 46 | + return %2 : $Ref<(Self.T, U)> |
| 47 | +} |
| 48 | + |
| 49 | +sil @merge_curried : $@convention(thin) <Self where Self : RefProto><U> (@in Self) -> @owned @callee_owned (@owned Ref<U>) -> @owned Ref<(Self.T, U)> { |
| 50 | +bb0(%0 : $*Self): |
| 51 | + %1 = function_ref @merge : $@convention(method) <τ_0_0 where τ_0_0 : RefProto><τ_1_0> (@owned Ref<τ_1_0>, @in_guaranteed τ_0_0) -> @owned Ref<(τ_0_0.T, τ_1_0)> |
| 52 | + %2 = partial_apply %1<Self, Self.T, U>(%0) : $@convention(method) <τ_0_0 where τ_0_0 : RefProto><τ_1_0> (@owned Ref<τ_1_0>, @in_guaranteed τ_0_0) -> @owned Ref<(τ_0_0.T, τ_1_0)> |
| 53 | + return %2 : $@callee_owned (@owned Ref<U>) -> @owned Ref<(Self.T, U)> |
| 54 | +} |
| 55 | + |
| 56 | +sil [reabstraction_thunk] @reabstract : $@convention(thin) <Self where Self : ValProto><U> (@owned Ref<Self.T>, @owned @callee_owned (@in Ref<Self.T>) -> @owned @callee_owned (@owned Ref<U>) -> @owned Ref<(Self.T, U)>) -> @owned @callee_owned (@owned Ref<U>) -> @owned Ref<(Self.T, U)> { |
| 57 | +bb0(%0 : $Ref<Self.T>, %1 : $@callee_owned (@in Ref<Self.T>) -> @owned @callee_owned (@owned Ref<U>) -> @owned Ref<(Self.T, U)>): |
| 58 | + %2 = alloc_stack $Ref<Self.T> |
| 59 | + store %0 to %2 : $*Ref<Self.T> |
| 60 | + %4 = apply %1(%2) : $@callee_owned (@in Ref<Self.T>) -> @owned @callee_owned (@owned Ref<U>) -> @owned Ref<(Self.T, U)> |
| 61 | + dealloc_stack %2 : $*Ref<Self.T> |
| 62 | + return %4 : $@callee_owned (@owned Ref<U>) -> @owned Ref<(Self.T, U)> |
| 63 | +} |
| 64 | + |
| 65 | +sil @test : $@convention(thin) (Val<Bool>, Val<Int>) -> Val<(Bool, Int)> { |
| 66 | + |
| 67 | +bb0(%0 : $Val<Bool>, %1 : $Val<Int>): |
| 68 | + %4 = function_ref @coerce : $@convention(thin) <τ_0_0, τ_0_1, τ_0_2> (@owned @callee_owned (@owned Ref<τ_0_0>) -> @owned @callee_owned (@owned Ref<τ_0_1>) -> @owned Ref<τ_0_2>) -> @owned @callee_owned (Val<τ_0_1>) -> Val<τ_0_2> |
| 69 | + %5 = metatype $@thick Ref<Bool>.Type |
| 70 | + %6 = function_ref @merge_curried : $@convention(thin) <τ_0_0 where τ_0_0 : RefProto><τ_1_0> (@in τ_0_0) -> @owned @callee_owned (@owned Ref<τ_1_0>) -> @owned Ref<(τ_0_0.T, τ_1_0)> |
| 71 | + %7 = partial_apply %6<Ref<Bool>, Bool, Int>() : $@convention(thin) <τ_0_0 where τ_0_0 : RefProto><τ_1_0> (@in τ_0_0) -> @owned @callee_owned (@owned Ref<τ_1_0>) -> @owned Ref<(τ_0_0.T, τ_1_0)> |
| 72 | + %8 = function_ref @reabstract : $@convention(thin) <τ_0_0 where τ_0_0 : ValProto><τ_1_0> (@owned Ref<τ_0_0.T>, @owned @callee_owned (@in Ref<τ_0_0.T>) -> @owned @callee_owned (@owned Ref<τ_1_0>) -> @owned Ref<(τ_0_0.T, τ_1_0)>) -> @owned @callee_owned (@owned Ref<τ_1_0>) -> @owned Ref<(τ_0_0.T, τ_1_0)> |
| 73 | + %9 = partial_apply %8<Val<Bool>, Bool, Int>(%7) : $@convention(thin) <τ_0_0 where τ_0_0 : ValProto><τ_1_0> (@owned Ref<τ_0_0.T>, @owned @callee_owned (@in Ref<τ_0_0.T>) -> @owned @callee_owned (@owned Ref<τ_1_0>) -> @owned Ref<(τ_0_0.T, τ_1_0)>) -> @owned @callee_owned (@owned Ref<τ_1_0>) -> @owned Ref<(τ_0_0.T, τ_1_0)> |
| 74 | + %10 = apply %4<Bool, Int, (Bool, Int)>(%9) : $@convention(thin) <τ_0_0, τ_0_1, τ_0_2> (@owned @callee_owned (@owned Ref<τ_0_0>) -> @owned @callee_owned (@owned Ref<τ_0_1>) -> @owned Ref<τ_0_2>) -> @owned @callee_owned (Val<τ_0_1>) -> Val<τ_0_2> |
| 75 | + %11 = apply %10(%1) : $@callee_owned (Val<Int>) -> Val<(Bool, Int)> |
| 76 | + return %11 : $Val<(Bool, Int)> |
| 77 | +} |
0 commit comments