Skip to content

Commit 0ffa5f8

Browse files
Merge pull request #36822 from varungandhi-apple/vg-async-method-emit-once
[Concurrency] Emit async methods in ObjC protocols once.
2 parents 8f68583 + b6ed507 commit 0ffa5f8

File tree

3 files changed

+30
-1
lines changed

3 files changed

+30
-1
lines changed

lib/IRGen/GenClass.cpp

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1153,8 +1153,19 @@ namespace {
11531153
Protocols.push_back(proto);
11541154
}
11551155

1156-
for (Decl *member : theProtocol->getMembers())
1156+
for (Decl *member : theProtocol->getMembers()) {
1157+
// Async methods coming from ObjC protocols shouldn't be recorded twice.
1158+
// At the moment, the language doesn't allow suppressing the
1159+
// completionHandler-based variant, so this is sufficient.
1160+
if (theProtocol->hasClangNode() && theProtocol->isObjC()) {
1161+
if (auto funcOrAccessor = dyn_cast<AbstractFunctionDecl>(member)) {
1162+
if (funcOrAccessor->isAsyncContext()) {
1163+
continue;
1164+
}
1165+
}
1166+
}
11571167
visit(member);
1168+
}
11581169
}
11591170

11601171
/// Gather protocol records for all of the explicitly-specified Objective-C

test/Concurrency/Inputs/Delegate.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,5 +17,8 @@
1717

1818
@end
1919

20+
@protocol MyAsyncProtocol
21+
-(void)myAsyncMethod:(void (^ _Nullable)(NSError * _Nullable, NSString * _Nullable))completionHandler;
22+
@end
2023

2124
#endif
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
// RUN: %target-swift-frontend(mock-sdk: %clang-importer-sdk) -enable-experimental-concurrency -import-objc-header %S/Inputs/Delegate.h %s -emit-ir -o - | %FileCheck %s
2+
// REQUIRES: concurrency
3+
// REQUIRES: objc_interop
4+
5+
6+
let anyObject: AnyObject = (MyAsyncProtocol.self as AnyObject) // or something like this
7+
8+
// rdar://76192003
9+
// Make sure we don't emit 2 copies of methods, due to a completion-handler
10+
// version and another due to an async based version.
11+
12+
// CHECK-LABEL: @_PROTOCOL_INSTANCE_METHODS_MyAsyncProtocol = internal constant
13+
// CHECK-SAME: selector_data(myAsyncMethod:)
14+
// CHECK-NOT: selector_data(myAsyncMethod:)
15+
// CHECK-SAME: align 8

0 commit comments

Comments
 (0)