Skip to content

Commit 20047a2

Browse files
authored
Merge pull request #41003 from DougGregor/sr-15766-async-override-thunk
2 parents 4aa2013 + 43f1581 commit 20047a2

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
@@ -3043,10 +3043,15 @@ static bool matchesFunctionType(CanAnyFunctionType fn1, CanAnyFunctionType fn2,
30433043
auto ext1 = fn1->getExtInfo();
30443044
auto ext2 = fn2->getExtInfo();
30453045
if (matchMode.contains(TypeMatchFlags::AllowOverride)) {
3046-
if (ext2.isThrowing()) {
3046+
// Removing 'throwing' is ABI-compatible for synchronous functions, but
3047+
// not for async ones.
3048+
if (ext2.isThrowing() &&
3049+
!(ext2.isAsync() &&
3050+
matchMode.contains(TypeMatchFlags::AllowABICompatible))) {
30473051
ext1 = ext1.withThrows(true);
30483052
}
30493053
}
3054+
30503055
// If specified, allow an escaping function parameter to override a
30513056
// non-escaping function parameter when the parameter is optional.
30523057
// 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
@@ -4390,8 +4390,9 @@ SILFunctionType::isABICompatibleWith(CanSILFunctionType other,
43904390
if (getRepresentation() != other->getRepresentation())
43914391
return ABICompatibilityCheckResult::DifferentFunctionRepresentations;
43924392

4393-
// `() async -> ()` is not compatible with `() async -> @error Error`.
4394-
if (!hasErrorResult() && other->hasErrorResult() && isAsync()) {
4393+
// `() async -> ()` is not compatible with `() async -> @error Error` and
4394+
// vice versa.
4395+
if (hasErrorResult() != other->hasErrorResult() && isAsync()) {
43954396
return ABICompatibilityCheckResult::DifferentErrorResultConventions;
43964397
}
43974398

lib/SIL/IR/TypeLowering.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3407,6 +3407,12 @@ TypeConverter::checkFunctionForABIDifferences(SILModule &M,
34073407
return ABIDifference::NeedsThunk;
34083408
}
34093409

3410+
// Asynchronous functions require a thunk if they differ in whether they
3411+
// have an error result.
3412+
if (fnTy1->hasErrorResult() != fnTy2->hasErrorResult() &&
3413+
(fnTy1->isAsync() || fnTy2->isAsync()))
3414+
return ABIDifference::NeedsThunk;
3415+
34103416
for (unsigned i = 0, e = fnTy1->getParameters().size(); i < e; ++i) {
34113417
auto param1 = fnTy1->getParameters()[i], param2 = fnTy2->getParameters()[i];
34123418

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)