// RUN: %target-swift-frontend -g -enable-objc-interop -primary-file %s -emit-ir | %FileCheck %s -DINT=i%target-ptrsize --check-prefixes=CHECK,CHECK-objc // RUN: %target-swift-frontend -g -disable-objc-interop -primary-file %s -emit-ir | %FileCheck %s -DINT=i%target-ptrsize --check-prefixes=CHECK,CHECK-native // REQUIRES: concurrency, objc_codegen sil_stage canonical import Builtin import Swift public protocol P {} public class C : P {} public class D {} class E {} public protocol Observable { associatedtype Result func subscribe(o: T) async -> () } public protocol Observer { associatedtype Result } sil hidden @witness_method : $@async @convention(thin) (@in S) -> @owned @async @callee_guaranteed (@in O) -> () { bb0(%0 : $*S): %1 = witness_method $S, #Observable.subscribe : $@async @convention(witness_method: Observable) <τ_0_0 where τ_0_0 : Observable><τ_1_0 where τ_1_0 : Observer, τ_0_0.Result == τ_1_0.Result> (@in τ_1_0, @in_guaranteed τ_0_0) -> () %2 = partial_apply [callee_guaranteed] %1(%0) : $@async @convention(witness_method: Observable) <τ_0_0 where τ_0_0 : Observable><τ_1_0 where τ_1_0 : Observer, τ_0_0.Result == τ_1_0.Result> (@in τ_1_0, @in_guaranteed τ_0_0) -> () return %2 : $@async @callee_guaranteed (@in O) -> () } sil hidden @specialized_curried : $@async @convention(thin) (@owned E) -> @owned @async @callee_guaranteed () -> @owned D { bb0(%0 : $E): %1 = function_ref @unspecialized_uncurried : $@async @convention(method) <τ_0_0 where τ_0_0 : P> (@guaranteed E) -> @owned D<τ_0_0> %2 = partial_apply [callee_guaranteed] %1(%0) : $@async @convention(method) <τ_0_0 where τ_0_0 : P> (@guaranteed E) -> @owned D<τ_0_0> return %2 : $@async @callee_guaranteed () -> @owned D } sil hidden @unspecialized_uncurried : $@async @convention(method) <τ_0_0 where τ_0_0 : P> (@guaranteed E) -> @owned D<τ_0_0> { entry(%e : $E): %0 = builtin "int_trap"() : $Never unreachable } sil hidden @takingP : $@async @convention(method) <τ_0_0 where τ_0_0 : P> (@in_guaranteed τ_0_0) -> () { entry(%p : $*τ_0_0): %0 = builtin "int_trap"() : $Never unreachable } sil hidden @reabstract_context : $@async @convention(thin) (@owned C) -> () { bb0(%0 : $C): %6 = alloc_stack $C store %0 to %6 : $*C %8 = function_ref @takingP : $@async @convention(method) <τ_0_0 where τ_0_0 : P> (@in_guaranteed τ_0_0) -> () %9 = partial_apply [callee_guaranteed] %8(%6) : $@async @convention(method) <τ_0_0 where τ_0_0 : P> (@in_guaranteed τ_0_0) -> () dealloc_stack %6 : $*C strong_release %9 : $@async @callee_guaranteed() -> () %10 = tuple () return %10 : $() } public protocol Q { associatedtype Update } public struct BaseProducer : Q { public typealias Update = T } public class WeakBox {} public struct EmptyType {} sil hidden @takingQ : $@async @convention(thin) <τ_0_0 where τ_0_0 : Q> (@owned WeakBox<τ_0_0>) -> () { entry(%b : $WeakBox<τ_0_0>): %0 = builtin "int_trap"() : $Never unreachable } sil hidden @takingQAndEmpty : $@async @convention(thin) <τ_0_0 where τ_0_0 : Q> (@owned WeakBox<τ_0_0>, EmptyType) -> () { entry(%b : $WeakBox<τ_0_0>, %e : $EmptyType): %0 = builtin "int_trap"() : $Never unreachable } sil hidden @takingEmptyAndQ : $@async @convention(thin) <τ_0_0 where τ_0_0 : Q> (EmptyType, @owned WeakBox<τ_0_0>) -> () { entry(%e : $EmptyType, %b : $WeakBox<τ_0_0>): %0 = builtin "int_trap"() : $Never unreachable } // CHECK-LABEL: define{{( dllexport)?}}{{( protected)?}} swift{{(tail)?}}cc void @bind_polymorphic_param_from_context( // CHECK-LABEL: define internal swift{{(tail)?}}cc void @"$s7takingQTA"( sil public @bind_polymorphic_param_from_context : $@async @convention(thin) <τ_0_1>(@in τ_0_1) -> @owned @async @callee_guaranteed () -> () { bb0(%0 : $*τ_0_1): %1 = alloc_ref $WeakBox> %8 = function_ref @takingQ : $@async @convention(thin) <τ_0_0 where τ_0_0 : Q> (@owned WeakBox<τ_0_0>) -> () %9 = partial_apply [callee_guaranteed] %8>(%1) : $@async @convention(thin) <τ_0_0 where τ_0_0 : Q> (@owned WeakBox<τ_0_0>) -> () return %9 : $@async @callee_guaranteed () -> () } // CHECK-LABEL: define{{( dllexport)?}}{{( protected)?}} swift{{(tail)?}}cc void @bind_polymorphic_param_from_context_2( sil public @bind_polymorphic_param_from_context_2 : $@async @convention(thin) <τ_0_1>(@in τ_0_1, EmptyType) -> @owned @async @callee_guaranteed () -> () { bb0(%0 : $*τ_0_1, %2: $EmptyType): %1 = alloc_ref $WeakBox> %8 = function_ref @takingQAndEmpty : $@async @convention(thin) <τ_0_0 where τ_0_0 : Q> (@owned WeakBox<τ_0_0>, EmptyType) -> () %9 = partial_apply [callee_guaranteed] %8>(%1, %2) : $@async @convention(thin) <τ_0_0 where τ_0_0 : Q> (@owned WeakBox<τ_0_0>, EmptyType) -> () return %9 : $@async @callee_guaranteed () -> () } // CHECK-LABEL: define{{( dllexport)?}}{{( protected)?}} swift{{(tail)?}}cc void @bind_polymorphic_param_from_context_3( sil public @bind_polymorphic_param_from_context_3 : $@async @convention(thin) <τ_0_1>(@in τ_0_1, EmptyType) -> @owned @async @callee_guaranteed () -> () { bb0(%0 : $*τ_0_1, %2: $EmptyType): %1 = alloc_ref $WeakBox> %8 = function_ref @takingEmptyAndQ : $@async @convention(thin) <τ_0_0 where τ_0_0 : Q> (EmptyType, @owned WeakBox<τ_0_0>) -> () %9 = partial_apply [callee_guaranteed] %8>(%2, %1) : $@async @convention(thin) <τ_0_0 where τ_0_0 : Q> (EmptyType, @owned WeakBox<τ_0_0>) -> () return %9 : $@async @callee_guaranteed () -> () } // CHECK-LABEL: define{{( dllexport)?}}{{( protected)?}} swift{{(tail)?}}cc void @bind_polymorphic_param_from_forwarder_parameter( sil public @bind_polymorphic_param_from_forwarder_parameter : $@async @convention(thin) <τ_0_1>(@in τ_0_1) -> () { bb0(%0 : $*τ_0_1): %1 = alloc_ref $WeakBox> %8 = function_ref @takingQ : $@async @convention(thin) <τ_0_0 where τ_0_0 : Q> (@owned WeakBox<τ_0_0>) -> () %9 = partial_apply [callee_guaranteed] %8>() : $@async @convention(thin) <τ_0_0 where τ_0_0 : Q> (@owned WeakBox<τ_0_0>) -> () %10 = tuple () return %10 : $() } struct S { var x : Builtin.Int64 } sil hidden @takingQAndS : $@async @convention(thin) <τ_0_0 where τ_0_0 : Q> (S, @owned WeakBox<τ_0_0>) -> () { entry(%s : $S, %b : $WeakBox<τ_0_0>): %0 = builtin "int_trap"() : $Never unreachable } // CHECK-LABEL: define{{( dllexport)?}}{{( protected)?}} swift{{(tail)?}}cc void @bind_polymorphic_param_from_context_with_layout( // CHECK-LABEL: define internal swift{{(tail)?}}cc void @"$s11takingQAndSTA"( sil public @bind_polymorphic_param_from_context_with_layout : $@async @convention(thin) <τ_0_1>(@in τ_0_1, S) -> @owned @async @callee_guaranteed () -> () { bb0(%0 : $*τ_0_1, %1: $S): %2 = alloc_ref $WeakBox> %8 = function_ref @takingQAndS : $@async @convention(thin) <τ_0_0 where τ_0_0 : Q> (S, @owned WeakBox<τ_0_0>) -> () %9 = partial_apply [callee_guaranteed] %8>(%1, %2) : $@async @convention(thin) <τ_0_0 where τ_0_0 : Q> (S, @owned WeakBox<τ_0_0>) -> () return %9 : $@async @callee_guaranteed () -> () } public class Empty {} sil private @inner_closure : $@async @convention(thin) (Empty) -> @owned Empty { bb0(%0 : $Empty): return %0 : $Empty } sil hidden @returns_closure : $@async @convention(thin) (Empty) -> (@owned Empty, @async @callee_guaranteed @owned (Empty) -> @owned Empty) { bb0(%0 : $Empty): %1 = function_ref @inner_closure : $@async @convention(thin) <τ_0_0> (Empty<τ_0_0>) -> @owned Empty<τ_0_0> %2 = partial_apply [callee_guaranteed] %1() : $@async @convention(thin) <τ_0_0> (Empty<τ_0_0>) -> @owned Empty<τ_0_0> %5 = tuple (%0 : $Empty, %2 : $@async @callee_guaranteed (Empty) -> @owned Empty) return %5 : $(Empty, @async @callee_guaranteed (Empty) -> @owned Empty) } sil hidden @specializes_closure_returning_closure : $@async @convention(thin) () -> @async @callee_guaranteed (Empty) -> (@owned Empty, @owned @async @callee_guaranteed (Empty) -> @owned Empty) { bb0: %0 = function_ref @returns_closure : $@async @convention(thin) <τ_0_0> (Empty<τ_0_0>) -> (@owned Empty<τ_0_0>, @owned @async @callee_guaranteed (Empty<τ_0_0>) -> @owned Empty<τ_0_0>) %1 = partial_apply [callee_guaranteed] %0() : $@async @convention(thin) <τ_0_0> (Empty<τ_0_0>) -> (@owned Empty<τ_0_0>, @owned @async @callee_guaranteed (Empty<τ_0_0>) -> @owned Empty<τ_0_0>) return %1 : $@async @callee_guaranteed (Empty) -> (@owned Empty, @owned @async @callee_guaranteed (Empty) -> @owned Empty) } // CHECK-LABEL: define hidden swift{{(tail)?}}cc void @specializes_closure_returning_closure( // CHECK-LABEL: define internal swift{{(tail)?}}cc void @"$s15returns_closureTA"( protocol MyEquatable { static func isEqual (lhs: Self, rhs: Self) -> Builtin.Int1 } protocol MyExtended : MyEquatable { func extended() } public struct Inner { public init() public init(_ e: Element) } extension Inner : MyEquatable where Element : MyEquatable { public static func isEqual (lhs: Inner, rhs: Inner) -> Builtin.Int1 } public struct Outer { init() } extension Outer : MyEquatable where Value : MyEquatable { public static func isEqual (lhs: Outer, rhs: Outer) -> Builtin.Int1 } public struct Outermost { } sil @$closure : $@async @convention(method) (Outer, Outer, @thin Outer.Type) -> Builtin.Int1 { entry(%o1 : $Outer, %o2 : $Outer, %ot : $@thin Outer.Type): %0 = builtin "int_trap"() : $Never unreachable } sil @$closure2 : $@async @convention(method) (Outermost, Outermost, @thin Outermost.Type) -> Builtin.Int1 { entry(%o1 : $Outermost, %o2 : $Outermost, %t : $@thin Outermost.Type): %0 = builtin "int_trap"() : $Never unreachable } sil @$dont_crash_test_capture_specialized_conditional_conformance : $@async @convention(thin) (Outer>) -> () { bb0(%0 : $Outer>): %2 = alloc_stack $Outer> store %0 to %2 : $*Outer> %4 = metatype $@thin Outer>.Type %5 = function_ref @$closure : $@async @convention(method) <τ_0_0 where τ_0_0 : MyEquatable> (Outer<τ_0_0>, Outer<τ_0_0>, @thin Outer<τ_0_0>.Type) -> Builtin.Int1 %6 = partial_apply [callee_guaranteed] %5>(%4) : $@async @convention(method) <τ_0_0 where τ_0_0 : MyEquatable> (Outer<τ_0_0>, Outer<τ_0_0>, @thin Outer<τ_0_0>.Type) -> Builtin.Int1 strong_release %6 : $@async @callee_guaranteed (Outer>, Outer>) -> Builtin.Int1 dealloc_stack %2 : $*Outer> %15 = tuple () return %15 : $() } protocol AssocType { associatedtype A : MyExtended } sil @$dont_crash_test_capture_specialized_conditional_conformance_associated_type : $@async @convention(thin) (Outer>) -> () { bb0(%0 : $Outer>): %2 = alloc_stack $Outer> store %0 to %2 : $*Outer> %4 = metatype $@thin Outer>.Type %5 = function_ref @$closure : $@async @convention(method) <τ_0_0 where τ_0_0 : MyEquatable> (Outer<τ_0_0>, Outer<τ_0_0>, @thin Outer<τ_0_0>.Type) -> Builtin.Int1 %6 = partial_apply [callee_guaranteed] %5>(%4) : $@async @convention(method) <τ_0_0 where τ_0_0 : MyEquatable> (Outer<τ_0_0>, Outer<τ_0_0>, @thin Outer<τ_0_0>.Type) -> Builtin.Int1 strong_release %6 : $@async @callee_guaranteed (Outer>, Outer>) -> Builtin.Int1 dealloc_stack %2 : $*Outer> %15 = tuple () return %15 : $() } sil @$dont_crash_test_capture_specialized_conditional_conformance_nested : $@async @convention(thin) (Outer>) -> () { bb0(%0 : $Outer>): %4 = metatype $@thin Outermost>>.Type %5 = function_ref @$closure2 : $@async @convention(method) (Outermost, Outermost, @thin Outermost.Type) -> Builtin.Int1 %6 = partial_apply [callee_guaranteed] %5>>(%4) : $@async @convention(method) (Outermost, Outermost, @thin Outermost.Type) -> Builtin.Int1 strong_release %6 : $@async @callee_guaranteed (Outermost>>, Outermost>>) -> Builtin.Int1 %15 = tuple () return %15 : $() } sil_vtable WeakBox {} sil_vtable C {} sil_vtable D {} sil_vtable E {} sil_vtable Empty {} sil_witness_table C: P module main {}