Skip to content

Commit f298bde

Browse files
authored
Merge pull request #81345 from xedin/rdar-150777469
[CSFix] SE-0470: Warn about missing `@Sendable` for unapplied static …
2 parents 46c5e9e + a57310b commit f298bde

File tree

2 files changed

+49
-1
lines changed

2 files changed

+49
-1
lines changed

lib/Sema/CSFix.cpp

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -282,10 +282,30 @@ getConcurrencyFixBehavior(ConstraintSystem &cs, ConstraintKind constraintKind,
282282
// We can only handle the downgrade for conversions.
283283
switch (constraintKind) {
284284
case ConstraintKind::Conversion:
285-
case ConstraintKind::ArgumentConversion:
286285
case ConstraintKind::Subtype:
287286
break;
288287

288+
case ConstraintKind::ArgumentConversion: {
289+
if (!forSendable)
290+
break;
291+
292+
// Passing a static member reference as an argument needs to be downgraded
293+
// to a warning until future major mode to maintain source compatibility for
294+
// code with non-Sendable metatypes.
295+
if (!cs.getASTContext().LangOpts.isSwiftVersionAtLeast(7)) {
296+
auto *argLoc = cs.getConstraintLocator(locator);
297+
if (auto *argument = getAsExpr(simplifyLocatorToAnchor(argLoc))) {
298+
if (auto overload = cs.findSelectedOverloadFor(
299+
argument->getSemanticsProvidingExpr())) {
300+
auto *decl = overload->choice.getDecl();
301+
if (decl && decl->isStatic())
302+
return FixBehavior::DowngradeToWarning;
303+
}
304+
}
305+
}
306+
break;
307+
}
308+
289309
default:
290310
if (!cs.shouldAttemptFixes())
291311
return std::nullopt;

test/Concurrency/sendable_metatype_typecheck.swift

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -147,3 +147,31 @@ final class TestStaticMembers<T> {
147147
let _: @Sendable () -> GenericS<Int> = GenericS.h // Ok
148148
}
149149
}
150+
151+
// Downgrade use of static member references on non-Sendable base to a warning until next major mode to maintain source compatibility.
152+
do {
153+
struct S<U> {
154+
static func test(_: U, _: U) -> Bool { false }
155+
}
156+
157+
func compute<T>(_: S<T>, _: @escaping @Sendable (T, T) -> Bool) {}
158+
159+
func test<T: Comparable>(s: S<T>) {
160+
compute(s, >) // expected-warning {{converting non-sendable function value to '@Sendable (T, T) -> Bool' may introduce data races}}
161+
compute(s, S.test) // expected-warning {{capture of non-sendable type 'T.Type' in an isolated closure}}
162+
}
163+
}
164+
165+
infix operator <=> : ComparisonPrecedence
166+
167+
struct TestUnapplied<U> : Comparable {
168+
static func <(_: TestUnapplied<U>, _: TestUnapplied<U>) -> Bool { false }
169+
}
170+
171+
extension TestUnapplied {
172+
static func <=>(_: Self, _: @escaping @Sendable (U, U) -> Bool) {}
173+
}
174+
175+
func testUnappliedWithOpetator<T: Comparable>(v: TestUnapplied<T>) {
176+
v<=>(>) // expected-error {{converting non-sendable function value to '@Sendable (T, T) -> Bool' may introduce data races}}
177+
}

0 commit comments

Comments
 (0)