Skip to content

Commit 59e07f1

Browse files
authored
Merge pull request #78698 from drexin/wip-142918657
[IRGen] Add indirect typed error slot when async function has indirec…
2 parents 0a081f8 + 30e7ba1 commit 59e07f1

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
@@ -285,10 +285,35 @@ func checkAsync() async {
285285
await invoke { try await impl.nonMatching_f1(false) }
286286
}
287287

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

0 commit comments

Comments
 (0)