Skip to content

Commit 806de5a

Browse files
committed
[Concurrency] Downgrade Sendable requirement failures in existential
erasure expressions for arguments to `@preconcurrency` functions in Swift 6 mode.
1 parent e21bf2f commit 806de5a

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
@@ -3524,6 +3524,7 @@ class ExprAvailabilityWalker : public ASTWalker {
35243524
ASTContext &Context;
35253525
MemberAccessContext AccessContext = MemberAccessContext::Default;
35263526
SmallVector<const Expr *, 16> ExprStack;
3527+
SmallVector<bool, 4> PreconcurrencyCalleeStack;
35273528
const ExportContext &Where;
35283529

35293530
public:
@@ -3547,6 +3548,15 @@ class ExprAvailabilityWalker : public ASTWalker {
35473548

35483549
ExprStack.push_back(E);
35493550

3551+
if (auto *apply = dyn_cast<ApplyExpr>(E)) {
3552+
bool preconcurrency = false;
3553+
auto declRef = apply->getFn()->getReferencedDecl();
3554+
if (auto *decl = declRef.getDecl()) {
3555+
preconcurrency = decl->preconcurrency();
3556+
}
3557+
PreconcurrencyCalleeStack.push_back(preconcurrency);
3558+
}
3559+
35503560
if (auto DR = dyn_cast<DeclRefExpr>(E)) {
35513561
diagnoseDeclRefAvailability(DR->getDeclRef(), DR->getSourceRange(),
35523562
getEnclosingApplyExpr(), std::nullopt);
@@ -3669,9 +3679,15 @@ class ExprAvailabilityWalker : public ASTWalker {
36693679
EE->getLoc(),
36703680
Where.getDeclContext());
36713681

3682+
bool preconcurrency = false;
3683+
if (!PreconcurrencyCalleeStack.empty()) {
3684+
preconcurrency = PreconcurrencyCalleeStack.back();
3685+
}
3686+
36723687
for (ProtocolConformanceRef C : EE->getConformances()) {
36733688
diagnoseConformanceAvailability(E->getLoc(), C, Where, Type(), Type(),
3674-
/*useConformanceAvailabilityErrorsOpt=*/true);
3689+
/*useConformanceAvailabilityErrorsOpt=*/true,
3690+
/*preconcurrency=*/preconcurrency);
36753691
}
36763692
}
36773693

@@ -3697,6 +3713,10 @@ class ExprAvailabilityWalker : public ASTWalker {
36973713
assert(ExprStack.back() == E);
36983714
ExprStack.pop_back();
36993715

3716+
if (auto *apply = dyn_cast<ApplyExpr>(E)) {
3717+
PreconcurrencyCalleeStack.pop_back();
3718+
}
3719+
37003720
return Action::Continue(E);
37013721
}
37023722

test/Concurrency/predates_concurrency_swift6.swift

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

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

203203
typealias T = RequireSendable<NotSendable>
204204
// expected-warning@-1 {{type 'NotSendable' does not conform to the 'Sendable' protocol}}
@@ -207,3 +207,24 @@ func testRequirementDowngrade(ns: NotSendable) {
207207
requireSendable(ns)
208208
// expected-warning@-1 {{type 'NotSendable' does not conform to the 'Sendable' protocol}}
209209
}
210+
211+
212+
protocol P2 {}
213+
214+
extension NotSendable: P2 {}
215+
216+
@preconcurrency
217+
func requireSendableExistential(_: any P2 & Sendable) {}
218+
219+
func requireSendableExistentialAlways(_: any P2 & Sendable) {}
220+
221+
func testErasureDowngrade(ns: NotSendable) {
222+
requireSendableExistential(ns)
223+
// expected-warning@-1 {{type 'NotSendable' does not conform to the 'Sendable' protocol}}
224+
225+
withSendableClosure {
226+
let ns = NotSendable()
227+
requireSendableExistentialAlways(ns)
228+
// expected-error@-1 {{type 'NotSendable' does not conform to the 'Sendable' protocol}}
229+
}
230+
}

0 commit comments

Comments
 (0)