1
+ // RUN: %target-swift-frontend -module-name test -swift-version 5 -sil-verify-all -emit-sil %s | %FileCheck --enable-var-scope --implicit-check-not='hop_to_executor' %s
2
+
3
+ // REQUIRES: concurrency
4
+
5
+ enum ActingError < T> : Error {
6
+ case forgotLine
7
+ case smuggledValue( T )
8
+ }
9
+
10
+ func neverReturn( ) -> Never { fatalError ( " quit! " ) }
11
+
12
+ actor BoringActor {
13
+
14
+ // CHECK-LABEL: sil hidden @$s4test11BoringActorCACyYacfc : $@convention(method) @async (@owned BoringActor) -> @owned BoringActor {
15
+ // CHECK: bb0([[SELF:%[0-9]+]] : $BoringActor):
16
+ // CHECK: initializeDefaultActor
17
+ // CHECK-NEXT: hop_to_executor [[SELF]]
18
+ // CHECK: } // end sil function '$s4test11BoringActorCACyYacfc'
19
+ init ( ) async { }
20
+
21
+ // CHECK-LABEL: sil hidden @$s4test11BoringActorC4sizeACSi_tYacfc : $@convention(method) @async (Int, @owned BoringActor) -> @owned BoringActor {
22
+ // CHECK: bb0({{%[0-9]+}} : $Int, [[SELF:%[0-9]+]] : $BoringActor):
23
+ // CHECK: initializeDefaultActor
24
+ // CHECK-NEXT: hop_to_executor [[SELF]]
25
+ // CHECK: } // end sil function '$s4test11BoringActorC4sizeACSi_tYacfc'
26
+ init ( size: Int ) async {
27
+ var sz = size
28
+ while sz > 0 {
29
+ print ( " . " )
30
+ sz -= 1
31
+ }
32
+ print ( " done! " )
33
+ }
34
+
35
+ @MainActor
36
+ init ( mainActor: Void ) async { }
37
+
38
+ // CHECK-LABEL: sil hidden @$s4test11BoringActorC6crashyACSgyt_tYacfc : $@convention(method) @async (@owned BoringActor) -> @owned Optional<BoringActor> {
39
+ // CHECK: bb0([[SELF:%[0-9]+]] : $BoringActor):
40
+ // CHECK: initializeDefaultActor
41
+ // CHECK-NEXT: hop_to_executor [[SELF]]
42
+ // CHECK: } // end sil function '$s4test11BoringActorC6crashyACSgyt_tYacfc'
43
+ init !( crashy: Void ) async { return nil }
44
+
45
+ // CHECK-LABEL: sil hidden @$s4test11BoringActorC5nillyACSgSi_tYacfc : $@convention(method) @async (Int, @owned BoringActor) -> @owned Optional<BoringActor> {
46
+ // CHECK: bb0({{%[0-9]+}} : $Int, [[SELF:%[0-9]+]] : $BoringActor):
47
+ // CHECK: initializeDefaultActor
48
+ // CHECK-NEXT: hop_to_executor [[SELF]]
49
+ // CHECK: } // end sil function '$s4test11BoringActorC5nillyACSgSi_tYacfc'
50
+ init ? ( nilly: Int ) async {
51
+ guard nilly > 0 else { return nil }
52
+ }
53
+ }
54
+
55
+ actor SingleVarActor {
56
+ var myVar : Int
57
+
58
+ // CHECK-LABEL: sil hidden @$s4test14SingleVarActorCACyYacfc : $@convention(method) @async (@owned SingleVarActor) -> @owned SingleVarActor {
59
+ // CHECK: bb0([[SELF:%[0-9]+]] : $SingleVarActor):
60
+ // CHECK: store {{%[0-9]+}} to [[ACCESS:%[0-9]+]]
61
+ // CHECK-NEXT: end_access [[ACCESS]]
62
+ // CHECK-NEXT: hop_to_executor [[SELF]] : $SingleVarActor
63
+ // CHECK: store {{%[0-9]+}} to {{%[0-9]+}}
64
+ // CHECK: } // end sil function '$s4test14SingleVarActorCACyYacfc'
65
+ init ( ) async {
66
+ myVar = 0
67
+ myVar = 1
68
+ }
69
+
70
+ // CHECK-LABEL: sil hidden @$s4test14SingleVarActorC10iterationsACSi_tYacfc : $@convention(method) @async (Int, @owned SingleVarActor) -> @owned SingleVarActor {
71
+ // CHECK: bb0({{%[0-9]+}} : $Int, [[SELF:%[0-9]+]] : $SingleVarActor):
72
+ // CHECK: [[MYVAR_REF:%[0-9]+]] = ref_element_addr [[SELF]] : $SingleVarActor, #SingleVarActor.myVar
73
+ // CHECK: [[MYVAR:%[0-9]+]] = begin_access [modify] [dynamic] [[MYVAR_REF]] : $*Int
74
+ // CHECK: store {{%[0-9]+}} to [[MYVAR]] : $*Int
75
+ // CHECK-NEXT: end_access [[MYVAR]]
76
+ // CHECK-NEXT: hop_to_executor [[SELF]] : $SingleVarActor
77
+ // CHECK: } // end sil function '$s4test14SingleVarActorC10iterationsACSi_tYacfc'
78
+ init ( iterations: Int ) async {
79
+ var iter = iterations
80
+ repeat {
81
+ myVar = 0
82
+ iter -= 1
83
+ } while iter > 0
84
+ }
85
+
86
+ // CHECK-LABEL: sil hidden @$s4test14SingleVarActorC2b12b2ACSb_SbtYacfc : $@convention(method) @async (Bool, Bool, @owned SingleVarActor) -> @owned SingleVarActor {
87
+ // CHECK: bb0({{%[0-9]+}} : $Bool, {{%[0-9]+}} : $Bool, [[SELF:%[0-9]+]] : $SingleVarActor):
88
+
89
+ // CHECK: store {{%[0-9]+}} to [[A1:%[0-9]+]] : $*Int
90
+ // CHECK-NEXT: end_access [[A1]]
91
+ // CHECK-NEXT: hop_to_executor [[SELF]] : $SingleVarActor
92
+
93
+ // CHECK: store {{%[0-9]+}} to [[A2:%[0-9]+]] : $*Int
94
+ // CHECK-NEXT: end_access [[A2]]
95
+ // CHECK-NEXT: hop_to_executor [[SELF]] : $SingleVarActor
96
+
97
+ // CHECK: store {{%[0-9]+}} to [[A3:%[0-9]+]] : $*Int
98
+ // CHECK-NEXT: end_access [[A3]]
99
+ // CHECK-NEXT: hop_to_executor [[SELF]] : $SingleVarActor
100
+
101
+ // CHECK: } // end sil function '$s4test14SingleVarActorC2b12b2ACSb_SbtYacfc'
102
+ init ( b1: Bool , b2: Bool ) async {
103
+ if b1 {
104
+ if b2 {
105
+ myVar = 0
106
+ }
107
+ myVar = 1
108
+ }
109
+ myVar = 2
110
+ }
111
+ }
112
+
113
+ actor DefaultInit {
114
+ var x : DefaultInit ?
115
+ var y : String = " "
116
+ var z : ActingError < Int > = . smuggledValue( 5 )
117
+
118
+ // CHECK-LABEL: sil hidden @$s4test11DefaultInitCACyYacfc : $@convention(method) @async (@owned DefaultInit) -> @owned DefaultInit {
119
+ // CHECK: bb0([[SELF:%[0-9]+]] : $DefaultInit):
120
+ // CHECK: store {{%[0-9]+}} to {{%[0-9]+}} : $*ActingError<Int>
121
+ // CHECK-NEXT: hop_to_executor [[SELF]] : $DefaultInit
122
+ // CHECK: } // end sil function '$s4test11DefaultInitCACyYacfc'
123
+ init ( ) async { }
124
+
125
+ // CHECK-LABEL: sil hidden @$s4test11DefaultInitC5nillyACSgSb_tYacfc : $@convention(method) @async (Bool, @owned DefaultInit) -> @owned Optional<DefaultInit> {
126
+ // CHECK: bb0({{%[0-9]+}} : $Bool, [[SELF:%[0-9]+]] : $DefaultInit):
127
+ // CHECK: store {{%[0-9]+}} to {{%[0-9]+}} : $*ActingError<Int>
128
+ // CHECK-NEXT: hop_to_executor [[SELF]] : $DefaultInit
129
+ // CHECK: } // end sil function '$s4test11DefaultInitC5nillyACSgSb_tYacfc'
130
+ init ? ( nilly: Bool ) async {
131
+ guard nilly else { return nil }
132
+ }
133
+
134
+ init ( sync: Void ) { }
135
+ @MainActor init ( mainActorSync: Void ) { }
136
+ }
137
+
138
+ actor MultiVarActor {
139
+ var firstVar : Int
140
+ var secondVar : Float
141
+
142
+ // CHECK-LABEL: sil hidden @$s4test13MultiVarActorC10doNotThrowACSb_tYaKcfc : $@convention(method) @async (Bool, @owned MultiVarActor) -> (@owned MultiVarActor, @error Error) {
143
+ // CHECK: bb0({{%[0-9]+}} : $Bool, [[SELF:%[0-9]+]] : $MultiVarActor):
144
+ // CHECK: [[REF:%[0-9]+]] = ref_element_addr [[SELF]] : $MultiVarActor, #MultiVarActor.firstVar
145
+ // CHECK: [[VAR:%[0-9]+]] = begin_access [modify] [dynamic] [[REF]] : $*Int
146
+ // CHECK: store {{%[0-9]+}} to [[VAR]] : $*Int
147
+ // CHECK-NEXT: end_access [[VAR]]
148
+ // CHECK-NEXT: hop_to_executor %1 : $MultiVarActor
149
+ // CHECK: } // end sil function '$s4test13MultiVarActorC10doNotThrowACSb_tYaKcfc'
150
+ init ( doNotThrow: Bool ) async throws {
151
+ secondVar = 0
152
+ guard doNotThrow else { throw ActingError< Any> . forgotLine }
153
+ firstVar = 1
154
+ }
155
+
156
+ // CHECK-LABEL: sil hidden @$s4test13MultiVarActorC10noSuccCaseACSb_tYacfc : $@convention(method) @async (Bool, @owned MultiVarActor) -> @owned MultiVarActor {
157
+ // CHECK: store {{%[0-9]+}} to [[A1:%[0-9]+]] : $*Int
158
+ // CHECK-NEXT: end_access [[A1]]
159
+ // CHECK-NEXT: hop_to_executor {{%[0-9]+}} : $MultiVarActor
160
+
161
+ // CHECK: store {{%[0-9]+}} to [[A2:%[0-9]+]] : $*Int
162
+ // CHECK-NEXT: end_access [[A2]]
163
+ // CHECK-NEXT: hop_to_executor {{%[0-9]+}} : $MultiVarActor
164
+ // CHECK: } // end sil function '$s4test13MultiVarActorC10noSuccCaseACSb_tYacfc'
165
+ init ( noSuccCase: Bool ) async {
166
+ secondVar = 0
167
+ if noSuccCase {
168
+ firstVar = 1
169
+ }
170
+ firstVar = 2
171
+ }
172
+
173
+ // CHECK-LABEL: sil hidden @$s4test13MultiVarActorC10noPredCaseACSb_tYacfc : $@convention(method) @async (Bool, @owned MultiVarActor) -> @owned MultiVarActor {
174
+ // CHECK: store {{%[0-9]+}} to [[ACCESS:%[0-9]+]] : $*Int
175
+ // CHECK-NEXT: end_access [[ACCESS]]
176
+ // CHECK-NEXT: hop_to_executor {{%[0-9]+}} : $MultiVarActor
177
+ // CHECK: } // end sil function '$s4test13MultiVarActorC10noPredCaseACSb_tYacfc'
178
+ init ( noPredCase: Bool ) async {
179
+ secondVar = 0
180
+ firstVar = 1
181
+ if noPredCase {
182
+ print ( " hello " )
183
+ }
184
+ print ( " hi " )
185
+ }
186
+
187
+
188
+ // Some cases where we do NOT expect a hop to be emitted because they do
189
+ // not fully-initialize `self`. The implicit check-not flag on this test
190
+ // ensures that any unexpected hops are caught.
191
+
192
+ init ? ( doesNotFullyInit1: Bool ) async {
193
+ firstVar = 1
194
+ return nil
195
+ }
196
+
197
+ init ( doesNotFullyInit2: Bool ) async {
198
+ firstVar = 1
199
+ fatalError ( " I give up! " )
200
+ }
201
+
202
+ init ( doesNotFullyInit3: Bool ) async throws {
203
+ firstVar = 1
204
+ throw ActingError< Any> . forgotLine
205
+ }
206
+
207
+ init ? ( doesNotFullyInit4: Bool ) async {
208
+ firstVar = 1
209
+ neverReturn ( )
210
+ }
211
+ }
212
+
213
+ @available ( SwiftStdlib 5 . 5 , * )
214
+ actor TaskMaster {
215
+ var task : Task < Void , Never > ?
216
+
217
+ func sayHello( ) { print ( " hello " ) }
218
+
219
+ ////// for the initializer
220
+ // CHECK-LABEL: @$s4test10TaskMasterCACyYacfc : $@convention(method) @async (@owned TaskMaster) -> @owned TaskMaster {
221
+ // CHECK: [[ELM:%[0-9]+]] = ref_element_addr [[SELF:%[0-9]+]] : $TaskMaster, #TaskMaster.task
222
+ // CHECK: [[NIL:%[0-9]+]] = enum $Optional<Task<(), Never>>, #Optional.none!enumelt
223
+ // CHECK: store [[NIL]] to [[ELM]] : $*Optional<Task<(), Never>>
224
+ // CHECK-NEXT: hop_to_executor [[SELF]] : $TaskMaster
225
+ // CHECK: } // end sil function '$s4test10TaskMasterCACyYacfc'
226
+ init ( ) async {
227
+
228
+ ////// for the closure
229
+ // CHECK-LABEL: sil private @$s4test10TaskMasterCACyYacfcyyYaYbcfU_ : $@convention(thin) @Sendable @async (@guaranteed TaskMaster) -> () {
230
+ // CHECK: hop_to_executor {{%[0-9]+}} : $TaskMaster
231
+ // CHECK: } // end sil function '$s4test10TaskMasterCACyYacfcyyYaYbcfU_'
232
+ task = Task . detached { await self . sayHello ( ) }
233
+ }
234
+ }
235
+
236
+ actor SomeActor {
237
+ var x : Int = 0
238
+
239
+ // CHECK-LABEL: sil hidden @$s4test9SomeActorCACyYacfc : $@convention(method) @async (@owned SomeActor) -> @owned SomeActor {
240
+ // CHECK-NOT: begin_access
241
+ // CHECK: store {{%[0-9]+}} to {{%[0-9]+}} : $*Int
242
+ // CHECK-NEXT: hop_to_executor {{%[0-9]+}} : $SomeActor
243
+ // CHECK: } // end sil function '$s4test9SomeActorCACyYacfc'
244
+ init ( ) async { }
245
+ }
0 commit comments