Skip to content

Commit 7d9a1b6

Browse files
authored
Merge pull request #41016 from DougGregor/sr-15766-async-override-thunk-5.6
Emit a separate vtable entry + override thunk for async overrides that drop throws
2 parents 73746e0 + f926994 commit 7d9a1b6

File tree

4 files changed

+25
-3
lines changed

4 files changed

+25
-3
lines changed

lib/AST/Type.cpp

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2962,10 +2962,15 @@ static bool matchesFunctionType(CanAnyFunctionType fn1, CanAnyFunctionType fn2,
29622962
auto ext1 = fn1->getExtInfo();
29632963
auto ext2 = fn2->getExtInfo();
29642964
if (matchMode.contains(TypeMatchFlags::AllowOverride)) {
2965-
if (ext2.isThrowing()) {
2965+
// Removing 'throwing' is ABI-compatible for synchronous functions, but
2966+
// not for async ones.
2967+
if (ext2.isThrowing() &&
2968+
!(ext2.isAsync() &&
2969+
matchMode.contains(TypeMatchFlags::AllowABICompatible))) {
29662970
ext1 = ext1.withThrows(true);
29672971
}
29682972
}
2973+
29692974
// If specified, allow an escaping function parameter to override a
29702975
// non-escaping function parameter when the parameter is optional.
29712976
// Note that this is checking 'ext2' rather than 'ext1' because parameters

lib/SIL/IR/SILFunctionType.cpp

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4348,8 +4348,9 @@ SILFunctionType::isABICompatibleWith(CanSILFunctionType other,
43484348
if (getRepresentation() != other->getRepresentation())
43494349
return ABICompatibilityCheckResult::DifferentFunctionRepresentations;
43504350

4351-
// `() async -> ()` is not compatible with `() async -> @error Error`.
4352-
if (!hasErrorResult() && other->hasErrorResult() && isAsync()) {
4351+
// `() async -> ()` is not compatible with `() async -> @error Error` and
4352+
// vice versa.
4353+
if (hasErrorResult() != other->hasErrorResult() && isAsync()) {
43534354
return ABICompatibilityCheckResult::DifferentErrorResultConventions;
43544355
}
43554356

lib/SIL/IR/TypeLowering.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3370,6 +3370,12 @@ TypeConverter::checkFunctionForABIDifferences(SILModule &M,
33703370
return ABIDifference::NeedsThunk;
33713371
}
33723372

3373+
// Asynchronous functions require a thunk if they differ in whether they
3374+
// have an error result.
3375+
if (fnTy1->hasErrorResult() != fnTy2->hasErrorResult() &&
3376+
(fnTy1->isAsync() || fnTy2->isAsync()))
3377+
return ABIDifference::NeedsThunk;
3378+
33733379
for (unsigned i = 0, e = fnTy1->getParameters().size(); i < e; ++i) {
33743380
auto param1 = fnTy1->getParameters()[i], param2 = fnTy2->getParameters()[i];
33753381

test/SILGen/async_vtable_thunk.swift

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,21 @@
33

44
class BaseClass<T> {
55
func wait() async -> T {}
6+
func waitOrDie() async throws -> T {}
67
}
78

89
class Derived : BaseClass<Int> {
910
override func wait() async -> Int {}
11+
override func waitOrDie() async -> Int {}
1012
}
1113

1214
// CHECK-LABEL: sil private [thunk] [ossa] @$s18async_vtable_thunk7DerivedC4waitSiyYaFAA9BaseClassCADxyYaFTV : $@convention(method) @async (@guaranteed Derived) -> @out Int {
1315

16+
// CHECK-LABEL: sil_vtable Derived {
17+
// CHECK: #BaseClass.wait: <T> (BaseClass<T>) -> () async -> T : @$s18async_vtable_thunk7DerivedC4waitSiyYaFAA9BaseClassCADxyYaFTV [override]
18+
// CHECK-NEXT: #BaseClass.waitOrDie: <T> (BaseClass<T>) -> () async throws -> T : @$s18async_vtable_thunk7DerivedC9waitOrDieSiyYaFAA9BaseClassCADxyYaKFTV [override]
19+
// CHECK-NEXT: #BaseClass.init!allocator: <T> (BaseClass<T>.Type) -> () -> BaseClass<T> : @$s18async_vtable_thunk7DerivedCACycfC [override]
20+
// CHECK-NEXT: #Derived.waitOrDie: (Derived) -> () async -> Int : @$s18async_vtable_thunk7DerivedC9waitOrDieSiyYaF
21+
// CHECK-NEXT: #Derived.deinit!deallocator: @$s18async_vtable_thunk7DerivedCfD
22+
// CHECK-NEXT: }
23+

0 commit comments

Comments
 (0)