7
7
@preconcurrency var sendyHandler : @Sendable ( ) -> Void { get set }
8
8
}
9
9
10
+ @preconcurrency class OldWorld {
11
+ @preconcurrency var handler : ( @Sendable ( ) -> Void ) ?
12
+ @preconcurrency var mainHandler : ( @MainActor ( ) -> Void ) ?
13
+ @preconcurrency var nonOptionalHandler : @Sendable ( ) -> Void = { }
14
+ @preconcurrency var nonOptionalMainHandler : @MainActor ( ) -> Void = { }
15
+ }
16
+
10
17
// CHECK-LABEL: sil hidden [ossa] @$s19objc_preconcurrency19testDynamicDispatch1p17completionHandleryAA1P_p_yyctF
11
18
// CHECK: dynamic_method_br
12
19
// CHECK: bb{{[0-9]+}}(%{{[0-9]+}} : $@convention(objc_method) (@convention(block) @Sendable () -> (), @opened
@@ -19,26 +26,134 @@ func testDynamicDispatch(p: P, completionHandler: @escaping () -> Void) {
19
26
}
20
27
21
28
// CHECK-LABEL: sil hidden [ossa] @$s19objc_preconcurrency21testOptionalVarAccessyySo12NSTouchGrassCF
22
- // CHECK: unchecked_addr_cast {{.*}} : $* Optional<@Sendable @callee_guaranteed () -> ()> to $* Optional<@callee_guaranteed () -> ()>
29
+ // CHECK: unchecked_bitwise_cast {{.*}} : $Optional<@Sendable @callee_guaranteed () -> ()> to $Optional<@callee_guaranteed () -> ()>
23
30
// CHECK: } // end sil function '$s19objc_preconcurrency21testOptionalVarAccessyySo12NSTouchGrassCF'
24
31
func testOptionalVarAccess( _ grass: NSTouchGrass ) {
25
32
grass. cancellationHandler ? ( )
26
33
}
27
34
35
+ // CHECK-LABEL: sil hidden [ossa] @$s19objc_preconcurrency33testOptionalVarAccessPartialApplyyyycSgSo12NSTouchGrassCF
36
+ // CHECK: unchecked_bitwise_cast {{.*}} : $Optional<@Sendable @callee_guaranteed () -> ()> to $Optional<@callee_guaranteed () -> ()>
37
+ // CHECK: } // end sil function '$s19objc_preconcurrency33testOptionalVarAccessPartialApplyyyycSgSo12NSTouchGrassCF'
38
+ func testOptionalVarAccessPartialApply( _ grass: NSTouchGrass ) -> ( ( ) -> Void ) ? {
39
+ let handler = grass. cancellationHandler
40
+ if let unwrapped = handler {
41
+ unwrapped ( )
42
+ }
43
+ return handler
44
+ }
45
+
46
+ // CHECK-LABEL: sil hidden [ossa] @$s19objc_preconcurrency16testObjCVarWriteyySo12NSTouchGrassCF
47
+ // CHECK: unchecked_bitwise_cast {{.*}} : $Optional<@callee_guaranteed () -> ()> to $Optional<@Sendable @callee_guaranteed () -> ()>
48
+ // CHECK: objc_method {{.*}} : $NSTouchGrass, #NSTouchGrass.cancellationHandler!setter.foreign : (NSTouchGrass) -> ((@Sendable () -> ())?) -> (), $@convention(objc_method) (Optional<@convention(block) @Sendable () -> ()>, NSTouchGrass) -> ()
49
+ // CHECK: } // end sil function '$s19objc_preconcurrency16testObjCVarWriteyySo12NSTouchGrassCF'
50
+ func testObjCVarWrite( _ grass: NSTouchGrass ) {
51
+ grass. cancellationHandler = { }
52
+ }
53
+
54
+ // the below looks kinda long and wonky, but is expected. for a summary, the steps are:
55
+ // 1. objc to native
56
+ // 2. Sendable to non-Sendable (major part of this test)
57
+ // 3. non-optional to optional
58
+ // 4. from non-Sendable to Sendable (major part of this test)
59
+ // 5. from native to objc (which involves unwrapping and rewrapping that optional; kinda silly but optimization will clean it up)
60
+ //
61
+ // CHECK-LABEL: sil hidden [ossa] @$s19objc_preconcurrency22testObjCVarWriteAcrossyySo12NSTouchGrassCF
62
+ // CHECK: [[GET_EXCEPTION:%[0-9]+]] = objc_method {{.*}} : $NSTouchGrass, #NSTouchGrass.exceptionHandler!getter.foreign
63
+ // CHECK: [[SENDABLE_BLOCK:%[0-9]+]] = apply [[GET_EXCEPTION]]({{.*}}) : $@convention(objc_method) (NSTouchGrass) -> @autoreleased @convention(block) @Sendable () -> ()
64
+ // << step 1 >>
65
+ // CHECK: [[NATIVE_THUNK:%[0-9]+]] = function_ref @$sIeyBh_Iegh_TR : $@convention(thin) @Sendable (@guaranteed @convention(block) @Sendable () -> ()) -> ()
66
+ // CHECK: [[NATIVE_SENDABLE_EXCEPTION:%[0-9]+]] = partial_apply [callee_guaranteed] [[NATIVE_THUNK]]([[SENDABLE_BLOCK]])
67
+ // << step 2 >>
68
+ // CHECK: [[NATIVE_EXCEPTION:%[0-9]+]] = convert_function [[NATIVE_SENDABLE_EXCEPTION]] : $@Sendable @callee_guaranteed () -> () to $@callee_guaranteed () -> ()
69
+ // << step 3 >>
70
+ // CHECK: [[OPTIONAL_NATIVE_EXCEPTION:%[0-9]+]] = enum $Optional<@callee_guaranteed () -> ()>, #Optional.some!enumelt, [[NATIVE_EXCEPTION]] : $@callee_guaranteed () -> ()
71
+ // << step 4 >>
72
+ // CHECK: = unchecked_bitwise_cast [[OPTIONAL_NATIVE_EXCEPTION]] : $Optional<@callee_guaranteed () -> ()> to $Optional<@Sendable @callee_guaranteed () -> ()>
73
+ // << step 5 >>
74
+ // CHECK: switch_enum {{.*}} : $Optional<@Sendable @callee_guaranteed () -> ()>
75
+ //
76
+ // CHECK: bb1({{.*}} : @owned $@Sendable @callee_guaranteed () -> ()):
77
+ // CHECK: init_block_storage_header {{.*}} : $*@block_storage @Sendable @callee_guaranteed () -> ()
78
+ // CHECK: } // end sil function '$s19objc_preconcurrency22testObjCVarWriteAcrossyySo12NSTouchGrassCF'
79
+ func testObjCVarWriteAcross( _ grass: NSTouchGrass ) {
80
+ grass. cancellationHandler = grass. exceptionHandler // *slaps roof of assignment* this bad boy can fit so much conversion in it!
81
+ }
82
+
83
+ // CHECK-LABEL: sil hidden [ossa] @$s19objc_preconcurrency25testOptionalAssignSetter1yyAA8OldWorldCF
84
+ // CHECK: unchecked_bitwise_cast {{.*}} : $Optional<@callee_guaranteed () -> ()> to $Optional<@Sendable @callee_guaranteed () -> ()>
85
+ // CHECK: #OldWorld.handler!setter : (OldWorld) -> ((@Sendable () -> ())?) -> ()
86
+ // CHECK: } // end sil function '$s19objc_preconcurrency25testOptionalAssignSetter1yyAA8OldWorldCF'
87
+ func testOptionalAssignSetter1( _ oldWorld: OldWorld ) {
88
+ oldWorld. handler = { }
89
+ }
90
+
91
+ // CHECK-LABEL: sil hidden [ossa] @$s19objc_preconcurrency25testOptionalAssignSetter2yyAA8OldWorldCF
92
+ // CHECK: convert_function {{.*}} : $@callee_guaranteed () -> () to $@Sendable @callee_guaranteed () -> ()
93
+ // CHECK: $OldWorld, #OldWorld.nonOptionalHandler!setter : (OldWorld) -> (@escaping @Sendable () -> ()) -> ()
94
+ // CHECK: } // end sil function '$s19objc_preconcurrency25testOptionalAssignSetter2yyAA8OldWorldCF'
95
+ func testOptionalAssignSetter2( _ oldWorld: OldWorld ) {
96
+ oldWorld. nonOptionalHandler = { }
97
+ }
98
+
99
+ // CHECK-LABEL: sil hidden [ossa] @$s19objc_preconcurrency21testMainHandlerWritesyyAA8OldWorldCF
100
+ // CHECK: = unchecked_bitwise_cast {{.*}} : $Optional<@callee_guaranteed () -> ()> to $Optional<@Sendable @callee_guaranteed () -> ()>
101
+ // CHECK: = unchecked_bitwise_cast {{.*}} : $Optional<@Sendable @callee_guaranteed () -> ()> to $Optional<@callee_guaranteed () -> ()>
102
+ // CHECK: } // end sil function '$s19objc_preconcurrency21testMainHandlerWritesyyAA8OldWorldCF'
103
+ func testMainHandlerWrites( _ oldWorld: OldWorld ) {
104
+ oldWorld. handler = oldWorld. mainHandler
105
+ oldWorld. mainHandler = oldWorld. handler
106
+ }
107
+
108
+ // CHECK-LABEL: sil hidden [ossa] @$s19objc_preconcurrency32testMainHandlerNonOptionalWritesyyAA8OldWorldCF
109
+ // CHECK: = convert_function {{.*}} : $@callee_guaranteed () -> () to $@Sendable @callee_guaranteed () -> ()
110
+ // CHECK: = convert_function {{.*}} : $@Sendable @callee_guaranteed () -> () to $@callee_guaranteed () -> ()
111
+ // CHECK: } // end sil function '$s19objc_preconcurrency32testMainHandlerNonOptionalWritesyyAA8OldWorldCF'
112
+ func testMainHandlerNonOptionalWrites( _ oldWorld: OldWorld ) {
113
+ oldWorld. nonOptionalHandler = oldWorld. nonOptionalMainHandler
114
+ oldWorld. nonOptionalMainHandler = oldWorld. nonOptionalHandler
115
+ }
116
+
117
+ // CHECK-LABEL: sil hidden [ossa] @$s19objc_preconcurrency15testMixedWritesyyAA8OldWorldCF
118
+ //
119
+ // << sendable conversions should be here >>
120
+ // CHECK: = unchecked_bitwise_cast {{.*}} : $Optional<@Sendable @callee_guaranteed () -> ()> to $Optional<@callee_guaranteed () -> ()>
121
+ // CHECK: = convert_function {{.*}} : $@callee_guaranteed () -> () to $@Sendable @callee_guaranteed () -> ()
122
+ //
123
+ // << but main actor type mismatches are accepted by SIL >>
124
+ // CHECK: [[NO_MAIN_ACTOR:%[0-9]+]] = partial_apply {{.*}} : $@convention(thin) (@guaranteed @callee_guaranteed () -> @out ()) -> ()
125
+ // CHECK: [[SETTER:%[0-9]+]] = class_method {{.*}} : $OldWorld, #OldWorld.nonOptionalMainHandler!setter : (OldWorld) -> (@escaping @MainActor () -> ()) -> (), $@convention(method) (@owned @callee_guaranteed () -> (), @guaranteed OldWorld) -> ()
126
+ // CHECK: apply [[SETTER]]([[NO_MAIN_ACTOR]]
127
+ // CHECK: } // end sil function '$s19objc_preconcurrency15testMixedWritesyyAA8OldWorldCF'
128
+ func testMixedWrites( _ oldWorld: OldWorld ) {
129
+ oldWorld. nonOptionalHandler = oldWorld. handler ?? { }
130
+ oldWorld. nonOptionalMainHandler = oldWorld. mainHandler ?? { }
131
+ }
132
+
28
133
func modify( _ v: inout ( ) -> Void ) {
29
134
v = { }
30
135
}
31
136
32
137
// CHECK-LABEL: sil hidden [ossa] @$s19objc_preconcurrency15testInoutAccessyySo12NSTouchGrassCF
33
- // CHECK: unchecked_addr_cast {{.*}} : $*@Sendable @callee_guaranteed () -> () to $*@callee_guaranteed () -> ()
138
+ // CHECK: [[BEFORE_MODIFY:%[0-9]+]] = convert_function {{.*}} : $@Sendable @callee_guaranteed () -> () to $@callee_guaranteed () -> ()
139
+ // CHECK: store [[BEFORE_MODIFY]] to [init] [[INOUT_ALLOC:%[0-9]+]] : $*@callee_guaranteed () -> ()
140
+ // CHECK: [[MODIFY_FN:%[0-9]+]] = function_ref @$s19objc_preconcurrency6modifyyyyyczF : $@convention(thin) (@inout @callee_guaranteed () -> ()) -> ()
141
+ // CHECK: = apply [[MODIFY_FN]]([[INOUT_ALLOC]])
142
+ // CHECK: [[AFTER_MODIFY:%[0-9]+]] = load [take] [[INOUT_ALLOC]] : $*@callee_guaranteed () -> ()
143
+ // CHECK: convert_function [[AFTER_MODIFY]] : $@callee_guaranteed () -> () to $@Sendable @callee_guaranteed () -> ()
34
144
// CHECK: } // end sil function '$s19objc_preconcurrency15testInoutAccessyySo12NSTouchGrassCF'
35
145
func testInoutAccess( _ grass: NSTouchGrass ) {
36
146
modify ( & grass. exceptionHandler)
37
147
}
38
148
39
149
40
150
// CHECK-LABEL: sil hidden [ossa] @$s19objc_preconcurrency21testProtocolVarAccess1pyAA1P_p_tF
41
- // CHECK: unchecked_addr_cast {{.*}} : $*@Sendable @callee_guaranteed () -> () to $*@callee_guaranteed () -> ()
151
+ // CHECK: [[BEFORE_MODIFY:%[0-9]+]] = convert_function {{.*}} : $@Sendable @callee_guaranteed () -> () to $@callee_guaranteed () -> ()
152
+ // CHECK: store [[BEFORE_MODIFY]] to [init] [[INOUT_ALLOC:%[0-9]+]] : $*@callee_guaranteed () -> ()
153
+ // CHECK: [[MODIFY_FN:%[0-9]+]] = function_ref @$s19objc_preconcurrency6modifyyyyyczF : $@convention(thin) (@inout @callee_guaranteed () -> ()) -> ()
154
+ // CHECK: = apply [[MODIFY_FN]]([[INOUT_ALLOC]])
155
+ // CHECK: [[AFTER_MODIFY:%[0-9]+]] = load [take] [[INOUT_ALLOC]] : $*@callee_guaranteed () -> ()
156
+ // CHECK: convert_function [[AFTER_MODIFY]] : $@callee_guaranteed () -> () to $@Sendable @callee_guaranteed () -> ()
42
157
// CHECK: } // end sil function '$s19objc_preconcurrency21testProtocolVarAccess1pyAA1P_p_tF'
43
158
func testProtocolVarAccess( p: P ) {
44
159
modify ( & p. sendyHandler)
0 commit comments