Skip to content

Commit 7f84ba4

Browse files
committed
[TypeChecker] Adjust witness matching to strip concurrency from ObjC requirements
`swift_attr` attributes in the type context were ignored before, which means that we need to maintain status quo to avoid breaking witness matching by stripping everything concurrency related from inner types. Resolves: rdar://122592751
1 parent 1d73afb commit 7f84ba4

File tree

2 files changed

+41
-0
lines changed

2 files changed

+41
-0
lines changed

lib/Sema/TypeCheckProtocol.cpp

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1169,6 +1169,33 @@ swift::matchWitness(WitnessChecker::RequirementEnvironmentCache &reqEnvCache,
11691169
// Match a type in the requirement to a type in the witness.
11701170
auto matchTypes = [&](Type reqType,
11711171
Type witnessType) -> llvm::Optional<RequirementMatch> {
1172+
// `swift_attr` attributes in the type context were ignored before,
1173+
// which means that we need to maintain status quo to avoid breaking
1174+
// witness matching by stripping everything concurrency related from
1175+
// inner types.
1176+
if (req->isObjC()) {
1177+
if (reqType->is<FunctionType>()) {
1178+
auto *fnTy = reqType->castTo<FunctionType>();
1179+
SmallVector<AnyFunctionType::Param, 4> params;
1180+
llvm::transform(fnTy->getParams(), std::back_inserter(params),
1181+
[&](const AnyFunctionType::Param &param) {
1182+
return param.withType(
1183+
param.getPlainType()->stripConcurrency(
1184+
/*recursive=*/true,
1185+
/*dropGlobalActor=*/true));
1186+
});
1187+
1188+
auto resultTy =
1189+
fnTy->getResult()->stripConcurrency(/*recursive=*/true,
1190+
/*dropGlobalActor=*/true);
1191+
1192+
reqType = FunctionType::get(params, resultTy, fnTy->getExtInfo());
1193+
} else {
1194+
reqType = reqType->stripConcurrency(/*recursive=*/true,
1195+
/*dropGlobalActor=*/true);
1196+
}
1197+
}
1198+
11721199
cs->addConstraint(ConstraintKind::Bind, reqType, witnessType, locator);
11731200
// FIXME: Check whether this has already failed.
11741201
return llvm::None;

test/Concurrency/sendable_objc_attr_in_type_context.swift

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
//--- Test.h
1515
#define SWIFT_SENDABLE __attribute__((__swift_attr__("@Sendable")))
1616
#define NONSENDABLE __attribute__((__swift_attr__("@_nonSendable")))
17+
#define MAIN_ACTOR __attribute__((__swift_attr__("@MainActor")))
1718

1819
#pragma clang assume_nonnull begin
1920

@@ -56,6 +57,11 @@ void doSomethingConcurrently(__attribute__((noescape)) void SWIFT_SENDABLE (^blo
5657
-(void) add: (T) object;
5758
@end
5859

60+
@protocol InnerSendableTypes
61+
-(void) test:(NSDictionary<NSString *, SWIFT_SENDABLE id> *)options;
62+
-(void) testWithCallback:(NSString *)name handler:(MAIN_ACTOR void (^)(NSDictionary<NSString *, SWIFT_SENDABLE id> *, NSError * _Nullable))handler;
63+
@end
64+
5965
#pragma clang assume_nonnull end
6066

6167
//--- main.swift
@@ -105,3 +111,11 @@ func test_sendable_attr_in_type_context(test: Test) {
105111
TestWithSendableSuperclass().add(MyValue())
106112
// expected-warning@-1 3 {{type 'MyValue' does not conform to the 'Sendable' protocol}}
107113
}
114+
115+
class TestConformanceWithStripping : InnerSendableTypes {
116+
func test(_ options: [String: Any]) { // Ok
117+
}
118+
119+
func test(withCallback name: String, handler: @escaping @MainActor ([String : Any], (any Error)?) -> Void) { // Ok
120+
}
121+
}

0 commit comments

Comments
 (0)