Skip to content

Commit cfb9eda

Browse files
authored
Merge pull request #78798 from drexin/wip-142918657-6.1
[6.1][IRGen] Add indirect typed error slot when async function has indirec…
2 parents c86341e + 6d3d25b commit cfb9eda

File tree

3 files changed

+41
-5
lines changed

3 files changed

+41
-5
lines changed

lib/IRGen/GenCall.cpp

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3027,11 +3027,7 @@ class AsyncCallEmission final : public CallEmission {
30273027

30283028
if (nativeSchema.requiresIndirect() ||
30293029
errorSchema.shouldReturnTypedErrorIndirectly() ||
3030-
(errorSchema.empty() &&
3031-
fnConv.hasIndirectSILResults())) { // direct empty typed errors are
3032-
// passed
3033-
// indirectly for compatibility with generic
3034-
// functions.
3030+
fnConv.hasIndirectSILResults()) {
30353031
// Return the error indirectly.
30363032
auto buf = IGF.getCalleeTypedErrorResultSlot(silErrorTy);
30373033
Args[--LastArgWritten] = buf.getAddress();

test/IRGen/typed_throws.swift

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -295,3 +295,18 @@ enum LargeError: Error {
295295
func callClosureAsyncIndirectError(f: () async throws(LargeError) -> Int) async throws(LargeError) -> Int {
296296
return try await f()
297297
}
298+
299+
protocol AsyncGenProto<A> {
300+
associatedtype A
301+
func fn(arg: Int) async throws(SmallError) -> A
302+
}
303+
304+
// CHECK: define internal swifttailcc void @"$s12typed_throws23callAsyncIndirectResult1p1xxAA0D8GenProto_px1ARts_XP_SitYaAA10SmallErrorVYKlFTY0_"(ptr swiftasync %0)
305+
// CHECK: musttail call swifttailcc void {{%.*}}(ptr noalias {{%.*}}, ptr swiftasync {{%.*}}, i64 {{%.*}}, ptr noalias swiftself {{%.*}}, ptr %swifterror, ptr {{%.*}}, ptr {{%.*}})
306+
// CHECK: ret void
307+
// CHECK: }
308+
@inline(never)
309+
func callAsyncIndirectResult<A>(p: any AsyncGenProto<A>, x: Int) async throws(SmallError) -> A {
310+
return try await p.fn(arg: x)
311+
}
312+

test/Interpreter/typed_throws_abi.swift

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -284,10 +284,35 @@ func checkAsync() async {
284284
await invoke { try await impl.nonMatching_f1(false) }
285285
}
286286

287+
enum MyError: Error {
288+
case x
289+
case y
290+
}
291+
292+
protocol AsyncGenProto<A> {
293+
associatedtype A
294+
func fn(arg: Int) async throws(MyError) -> A
295+
}
296+
297+
@inline(never)
298+
func callAsyncIndirectResult<A>(p: any AsyncGenProto<A>, x: Int) async throws(MyError) -> A {
299+
return try await p.fn(arg: x)
300+
}
301+
302+
303+
struct AsyncGenProtoImpl: AsyncGenProto {
304+
func fn(arg: Int) async throws(MyError) -> Int {
305+
print("Arg is \(arg)")
306+
return arg
307+
}
308+
}
309+
287310
@main
288311
public struct Main {
289312
public static func main() async {
290313
await checkSync()
291314
await checkAsync()
315+
// CHECK: Arg is 10
316+
print(try! await callAsyncIndirectResult(p: AsyncGenProtoImpl(), x: 10))
292317
}
293318
}

0 commit comments

Comments
 (0)