Skip to content

Commit 29e50a2

Browse files
committed
[Concurrency] Downgrade Sendable requirement failures in existential
erasure expressions for arguments to `@preconcurrency` functions in Swift 6 mode. (cherry picked from commit 806de5a)
1 parent ed533bf commit 29e50a2

File tree

2 files changed

+43
-2
lines changed

2 files changed

+43
-2
lines changed

lib/Sema/TypeCheckAvailability.cpp

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3442,6 +3442,7 @@ class ExprAvailabilityWalker : public ASTWalker {
34423442
ASTContext &Context;
34433443
MemberAccessContext AccessContext = MemberAccessContext::Default;
34443444
SmallVector<const Expr *, 16> ExprStack;
3445+
SmallVector<bool, 4> PreconcurrencyCalleeStack;
34453446
const ExportContext &Where;
34463447

34473448
public:
@@ -3469,6 +3470,15 @@ class ExprAvailabilityWalker : public ASTWalker {
34693470

34703471
ExprStack.push_back(E);
34713472

3473+
if (auto *apply = dyn_cast<ApplyExpr>(E)) {
3474+
bool preconcurrency = false;
3475+
auto declRef = apply->getFn()->getReferencedDecl();
3476+
if (auto *decl = declRef.getDecl()) {
3477+
preconcurrency = decl->preconcurrency();
3478+
}
3479+
PreconcurrencyCalleeStack.push_back(preconcurrency);
3480+
}
3481+
34723482
if (auto DR = dyn_cast<DeclRefExpr>(E)) {
34733483
diagnoseDeclRefAvailability(DR->getDeclRef(), DR->getSourceRange(),
34743484
getEnclosingApplyExpr(), std::nullopt);
@@ -3573,9 +3583,15 @@ class ExprAvailabilityWalker : public ASTWalker {
35733583
EE->getLoc(),
35743584
Where.getDeclContext());
35753585

3586+
bool preconcurrency = false;
3587+
if (!PreconcurrencyCalleeStack.empty()) {
3588+
preconcurrency = PreconcurrencyCalleeStack.back();
3589+
}
3590+
35763591
for (ProtocolConformanceRef C : EE->getConformances()) {
35773592
diagnoseConformanceAvailability(E->getLoc(), C, Where, Type(), Type(),
3578-
/*useConformanceAvailabilityErrorsOpt=*/true);
3593+
/*useConformanceAvailabilityErrorsOpt=*/true,
3594+
/*preconcurrency=*/preconcurrency);
35793595
}
35803596
}
35813597

@@ -3601,6 +3617,10 @@ class ExprAvailabilityWalker : public ASTWalker {
36013617
assert(ExprStack.back() == E);
36023618
ExprStack.pop_back();
36033619

3620+
if (auto *apply = dyn_cast<ApplyExpr>(E)) {
3621+
PreconcurrencyCalleeStack.pop_back();
3622+
}
3623+
36043624
return Action::Continue(E);
36053625
}
36063626

test/Concurrency/predates_concurrency_swift6.swift

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -180,7 +180,7 @@ func requireSendable<T: Sendable>(_: T) {}
180180
@preconcurrency
181181
struct RequireSendable<T: Sendable> {}
182182

183-
class NotSendable {} // expected-note 2 {{class 'NotSendable' does not conform to the 'Sendable' protocol}}
183+
class NotSendable {} // expected-note 4 {{class 'NotSendable' does not conform to the 'Sendable' protocol}}
184184

185185
typealias T = RequireSendable<NotSendable>
186186
// expected-warning@-1 {{type 'NotSendable' does not conform to the 'Sendable' protocol}}
@@ -189,3 +189,24 @@ func testRequirementDowngrade(ns: NotSendable) {
189189
requireSendable(ns)
190190
// expected-warning@-1 {{type 'NotSendable' does not conform to the 'Sendable' protocol}}
191191
}
192+
193+
194+
protocol P2 {}
195+
196+
extension NotSendable: P2 {}
197+
198+
@preconcurrency
199+
func requireSendableExistential(_: any P2 & Sendable) {}
200+
201+
func requireSendableExistentialAlways(_: any P2 & Sendable) {}
202+
203+
func testErasureDowngrade(ns: NotSendable) {
204+
requireSendableExistential(ns)
205+
// expected-warning@-1 {{type 'NotSendable' does not conform to the 'Sendable' protocol}}
206+
207+
withSendableClosure {
208+
let ns = NotSendable()
209+
requireSendableExistentialAlways(ns)
210+
// expected-error@-1 {{type 'NotSendable' does not conform to the 'Sendable' protocol}}
211+
}
212+
}

0 commit comments

Comments
 (0)