1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138
|
// RUN: %target-swift-emit-silgen -module-name protocol_optional -parse-as-library -disable-objc-attr-requires-foundation-module -enable-objc-interop %s | %FileCheck %s
@objc protocol P1 {
@objc optional func method(_ x: Int)
@objc optional func methodReturnsSelf() -> Self
@objc optional static func staticMethod(_ x: Int)
@objc optional var prop: Int { get }
@objc optional subscript (i: Int) -> Int { get }
}
// CHECK-LABEL: sil hidden [ossa] @$s17protocol_optional0B13MethodGeneric1tyx_tAA2P1RzlF : $@convention(thin) <T where T : P1> (@guaranteed T) -> ()
func optionalMethodGeneric<T : P1>(t t : T) {
var t = t
// CHECK: bb0([[T:%[0-9]+]] : @guaranteed $T):
// CHECK: [[TBOX:%[0-9]+]] = alloc_box $<τ_0_0 where τ_0_0 : P1> { var τ_0_0 } <T>
// CHECK: [[TLIFETIME:%[^,]+]] = begin_borrow [lexical] [var_decl] [[TBOX]]
// CHECK: [[PT:%[0-9]+]] = project_box [[TLIFETIME]]
// CHECK: [[T_COPY:%.*]] = copy_value [[T]]
// CHECK: store [[T_COPY]] to [init] [[PT]] : $*T
// CHECK: [[OPT_BOX:%[0-9]+]] = alloc_box ${ var Optional<@callee_guaranteed (Int) -> ()> }
// CHECK: [[OPT_LIFETIME:%[^,]+]] = begin_borrow [lexical] [var_decl] [[OPT_BOX]]
// CHECK: project_box [[OPT_LIFETIME]]
// CHECK: [[READ:%.*]] = begin_access [read] [unknown] [[PT]] : $*T
// CHECK: [[T:%[0-9]+]] = load [copy] [[READ]] : $*T
// CHECK: alloc_stack $Optional<@callee_guaranteed (Int) -> ()>
// CHECK: dynamic_method_br [[T]] : $T, #P1.method!foreign
var methodRef = t.method
}
// CHECK: } // end sil function '$s17protocol_optional0B13MethodGeneric1tyx_tAA2P1RzlF'
// CHECK-LABEL: sil hidden [ossa] @$s17protocol_optional0B22StaticMethodRefGeneric1tyx_tAA2P1RzlF : $@convention(thin) <T where T : P1> (@guaranteed T) -> () {
func optionalStaticMethodRefGeneric<T: P1>(t: T) {
// CHECK: bb0(%0 : @guaranteed $T):
// CHECK: [[BOX:%[0-9]+]] = alloc_box ${ var Optional<@callee_guaranteed (Int) -> ()> }, var
// CHECK: [[BOX_LIFETIME:%[0-9]+]] = begin_borrow [lexical] [var_decl] [[BOX]]
// CHECK: [[UNBOX:%[0-9]+]] = project_box [[BOX_LIFETIME]]
// CHECK: [[META:%[0-9]+]] = metatype $@thick T.Type
// CHECK: [[OBJC_META:%[0-9]+]] = thick_to_objc_metatype [[META]]
// CHECK: alloc_stack $Optional<@callee_guaranteed (Int) -> ()>
// CHECK: dynamic_method_br [[OBJC_META]] : $@objc_metatype T.Type, #P1.staticMethod!foreign, bb1, bb2
var methodRef = T.self.staticMethod
}
// CHECK: } // end sil function '$s17protocol_optional0B22StaticMethodRefGeneric1tyx_tAA2P1RzlF'
// CHECK-LABEL: sil hidden [ossa] @$s17protocol_optional0B23MethodUnboundRefGeneric1tyx_tAA2P1RzlF : $@convention(thin) <T where T : P1> (@guaranteed T) -> () {
// CHECK: bb0([[T:%[0-9]+]] : @guaranteed $T):
// CHECK: [[BOX:%[0-9]+]] = alloc_box $<τ_0_0 where τ_0_0 : P1> { var @callee_guaranteed @substituted <τ_0_0 where τ_0_0 : AnyObject> (@guaranteed τ_0_0) -> @owned Optional<@callee_guaranteed (Int) -> ()> for <τ_0_0> } <T>
// CHECK: [[BOX_LIFETIME:%[0-9]+]] = begin_borrow [lexical] [var_decl] [[BOX]]
// CHECK: [[PBOX:%[0-9]+]] = project_box [[BOX_LIFETIME]]
// CHECK: [[THUNK:%[0-9]+]] = function_ref @$[[THUNK_NAME:[_0-9a-zA-Z]+]]
// CHECK: [[SPEC_THUNK:%[0-9]+]] = partial_apply [callee_guaranteed] [[THUNK]]<T>()
// CHECK: [[SUBST_THUNK:%[0-9]+]] = convert_function [[SPEC_THUNK]]
// CHECK: store [[SUBST_THUNK]] to [init] [[PBOX]]
// CHECK: } // end sil function '$s17protocol_optional0B23MethodUnboundRefGeneric1tyx_tAA2P1RzlF'
// CHECK: sil private [ossa] @$[[THUNK_NAME]] : $@convention(thin) <T where T : P1> (@guaranteed T) -> @owned Optional<@callee_guaranteed (Int) -> ()> {
// CHECK: bb0([[T:%[0-9]+]] : @guaranteed $T):
// CHECK: [[T_COPY:%[0-9]+]] = copy_value [[T]]
// CHECK: alloc_stack $Optional<@callee_guaranteed (Int) -> ()>
// CHECK: dynamic_method_br [[T_COPY]] : $T, #P1.method!foreign, bb1, bb2
// CHECK: } // end sil function '$[[THUNK_NAME]]'
func optionalMethodUnboundRefGeneric<T : P1>(t: T) {
var methodRef = T.method
}
// CHECK-LABEL: sil hidden [ossa] @$s17protocol_optional0B27MethodUnboundRefExistentialyyF : $@convention(thin) () -> () {
// CHECK: bb0:
// CHECK: [[BOX:%[0-9]+]] = alloc_box ${ var @callee_guaranteed (@guaranteed any P1) -> @owned Optional<@callee_guaranteed () -> @owned any P1> }
// CHECK: [[BOX_LIFETIME:%[0-9]+]] = begin_borrow [lexical] [var_decl] [[BOX]]
// CHECK: [[PBOX:%[0-9]+]] = project_box [[BOX_LIFETIME]]
// CHECK: [[THUNK:%[0-9]+]] = function_ref @$[[THUNK_NAME:[_0-9a-zA-Z]+]]
// CHECK: [[THUNK_THICK:%[0-9]+]] = thin_to_thick_function [[THUNK]]
// CHECK: store [[THUNK_THICK]] to [init] [[PBOX]]
// CHECK: end_borrow [[BOX_LIFETIME]]
// CHECK: } // end sil function '$s17protocol_optional0B27MethodUnboundRefExistentialyyF'
// CHECK: sil private [ossa] @$[[THUNK_NAME]] : $@convention(thin) (@guaranteed any P1) -> @owned Optional<@callee_guaranteed () -> @owned any P1> {
// CHECK: bb0([[EXIST:%[0-9]+]] : @guaranteed $any P1):
// CHECK: [[OPENED:%[0-9]+]] = open_existential_ref [[EXIST]] : $any P1 to $[[OPENED_TY:@opened\("[-A-F0-9]+", any P1\) Self]]
// CHECK: [[OPENED_COPY:%[0-9]+]] = copy_value [[OPENED]]
// CHECK: alloc_stack $Optional<@callee_guaranteed @substituted <τ_0_0 where τ_0_0 : AnyObject> () -> @owned τ_0_0 for <[[OPENED_TY]]>>
// CHECK: dynamic_method_br [[OPENED_COPY]] : $[[OPENED_TY]], #P1.methodReturnsSelf!foreign, bb1, bb2
//
// CHECK: bb{{[0-9]+}}([[ARG:%[0-9]+]] : @owned $@callee_guaranteed @substituted <τ_0_0 where τ_0_0 : AnyObject> () -> @owned τ_0_0 for <[[OPENED_TY]]>):
// CHECK: [[ERASED:%[0-9]+]] = convert_function [[ARG]] : {{.*}} to $@callee_guaranteed () -> @owned any P1
// CHECK: } // end sil function '$[[THUNK_NAME]]'
func optionalMethodUnboundRefExistential() {
// Test that we erase to existential bounds.
var methodRef = P1.methodReturnsSelf
}
// CHECK-LABEL: sil hidden [ossa] @$s17protocol_optional0B15PropertyGeneric{{[_0-9a-zA-Z]*}}F : $@convention(thin) <T where T : P1> (@guaranteed T) -> ()
func optionalPropertyGeneric<T : P1>(t t : T) {
var t = t
// CHECK: bb0([[T:%[0-9]+]] : @guaranteed $T):
// CHECK: [[TBOX:%[0-9]+]] = alloc_box $<τ_0_0 where τ_0_0 : P1> { var τ_0_0 } <T>
// CHECK: [[TLIFETIME:%[^,]+]] = begin_borrow [lexical] [var_decl] [[TBOX]]
// CHECK: [[PT:%[0-9]+]] = project_box [[TLIFETIME]]
// CHECK: [[T_COPY:%.*]] = copy_value [[T]]
// CHECK: store [[T_COPY]] to [init] [[PT]] : $*T
// CHECK: [[OPT_BOX:%[0-9]+]] = alloc_box ${ var Optional<Int> }
// CHECK: [[OPT_LIFETIME:%.*]] = begin_borrow [var_decl] [[OPT_BOX]]
// CHECK: project_box [[OPT_LIFETIME]]
// CHECK: [[READ:%.*]] = begin_access [read] [unknown] [[PT]] : $*T
// CHECK: [[T:%[0-9]+]] = load [copy] [[READ]] : $*T
// CHECK: alloc_stack $Optional<Int>
// CHECK: dynamic_method_br [[T]] : $T, #P1.prop!getter.foreign
var propertyRef = t.prop
}
// CHECK: } // end sil function '$s17protocol_optional0B15PropertyGeneric{{[_0-9a-zA-Z]*}}F'
// CHECK-LABEL: sil hidden [ossa] @$s17protocol_optional0B16SubscriptGeneric{{[_0-9a-zA-Z]*}}F : $@convention(thin) <T where T : P1> (@guaranteed T) -> ()
func optionalSubscriptGeneric<T : P1>(t t : T) {
var t = t
// CHECK: bb0([[T:%[0-9]+]] : @guaranteed $T):
// CHECK: [[TBOX:%[0-9]+]] = alloc_box $<τ_0_0 where τ_0_0 : P1> { var τ_0_0 } <T>
// CHECK: [[TLIFETIME:%[^,]+]] = begin_borrow [lexical] [var_decl] [[TBOX]]
// CHECK: [[PT:%[0-9]+]] = project_box [[TLIFETIME]]
// CHECK: [[T_COPY:%.*]] = copy_value [[T]]
// CHECK: store [[T_COPY]] to [init] [[PT]] : $*T
// CHECK: [[OPT_BOX:%[0-9]+]] = alloc_box ${ var Optional<Int> }
// CHECK: [[OPT_LIFETIME:%.*]] = begin_borrow [var_decl] [[OPT_BOX]]
// CHECK: project_box [[OPT_LIFETIME]]
// CHECK: [[READ:%.*]] = begin_access [read] [unknown] [[PT]] : $*T
// CHECK: [[T:%[0-9]+]] = load [copy] [[READ]] : $*T
// CHECK: [[FIVELIT:%[0-9]+]] = integer_literal $Builtin.IntLiteral, 5
// CHECK: [[INT64:%[0-9]+]] = metatype $@thin Int.Type
// CHECK: [[INTCONV:%[0-9]+]] = function_ref @$sSi2{{[_0-9a-zA-Z]*}}fC
// CHECK: [[FIVE:%[0-9]+]] = apply [[INTCONV]]([[FIVELIT]], [[INT64]]) : $@convention(method) (Builtin.IntLiteral, @thin Int.Type) -> Int
// CHECK: alloc_stack $Optional<Int>
// CHECK: dynamic_method_br [[T]] : $T, #P1.subscript!getter.foreign
var subscriptRef = t[5]
}
// CHECK: } // end sil function '$s17protocol_optional0B16SubscriptGeneric{{[_0-9a-zA-Z]*}}F'
|