Skip to content

Commit 336ff2d

Browse files
committed
SIL test for hop_to_executor in async actor inits
1 parent 1e54503 commit 336ff2d

File tree

1 file changed

+245
-0
lines changed

1 file changed

+245
-0
lines changed
Lines changed: 245 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,245 @@
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

Comments
 (0)