mirror of
https://github.com/apple/swift.git
synced 2025-12-14 20:36:38 +01:00
[CSFix] SE-0470: Warn about missing @Sendable for unapplied static member references until future Swift version
Static member referenced were marked as `@Sendable` by `InferSendableFromCaptures` because metatypes used to be always Sendable which is no longer the case, so in order to maintain the source compatibility we need to downgrade missing `@Sendable` to a warning for unapplied static member references. This affects primarily operators at the moment because other static members form a curry thunk with a call inside and would be diagnosed as a capture. Resolves: rdar://150777469
This commit is contained in:
@@ -282,10 +282,30 @@ getConcurrencyFixBehavior(ConstraintSystem &cs, ConstraintKind constraintKind,
|
|||||||
// We can only handle the downgrade for conversions.
|
// We can only handle the downgrade for conversions.
|
||||||
switch (constraintKind) {
|
switch (constraintKind) {
|
||||||
case ConstraintKind::Conversion:
|
case ConstraintKind::Conversion:
|
||||||
case ConstraintKind::ArgumentConversion:
|
|
||||||
case ConstraintKind::Subtype:
|
case ConstraintKind::Subtype:
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case ConstraintKind::ArgumentConversion: {
|
||||||
|
if (!forSendable)
|
||||||
|
break;
|
||||||
|
|
||||||
|
// Passing a static member reference as an argument needs to be downgraded
|
||||||
|
// to a warning until future major mode to maintain source compatibility for
|
||||||
|
// code with non-Sendable metatypes.
|
||||||
|
if (!cs.getASTContext().LangOpts.isSwiftVersionAtLeast(7)) {
|
||||||
|
auto *argLoc = cs.getConstraintLocator(locator);
|
||||||
|
if (auto *argument = getAsExpr(simplifyLocatorToAnchor(argLoc))) {
|
||||||
|
if (auto overload = cs.findSelectedOverloadFor(
|
||||||
|
argument->getSemanticsProvidingExpr())) {
|
||||||
|
auto *decl = overload->choice.getDecl();
|
||||||
|
if (decl && decl->isStatic())
|
||||||
|
return FixBehavior::DowngradeToWarning;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
default:
|
default:
|
||||||
if (!cs.shouldAttemptFixes())
|
if (!cs.shouldAttemptFixes())
|
||||||
return std::nullopt;
|
return std::nullopt;
|
||||||
|
|||||||
@@ -147,3 +147,31 @@ final class TestStaticMembers<T> {
|
|||||||
let _: @Sendable () -> GenericS<Int> = GenericS.h // Ok
|
let _: @Sendable () -> GenericS<Int> = GenericS.h // Ok
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Downgrade use of static member references on non-Sendable base to a warning until next major mode to maintain source compatibility.
|
||||||
|
do {
|
||||||
|
struct S<U> {
|
||||||
|
static func test(_: U, _: U) -> Bool { false }
|
||||||
|
}
|
||||||
|
|
||||||
|
func compute<T>(_: S<T>, _: @escaping @Sendable (T, T) -> Bool) {}
|
||||||
|
|
||||||
|
func test<T: Comparable>(s: S<T>) {
|
||||||
|
compute(s, >) // expected-warning {{converting non-sendable function value to '@Sendable (T, T) -> Bool' may introduce data races}}
|
||||||
|
compute(s, S.test) // expected-warning {{capture of non-sendable type 'T.Type' in an isolated closure}}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
infix operator <=> : ComparisonPrecedence
|
||||||
|
|
||||||
|
struct TestUnapplied<U> : Comparable {
|
||||||
|
static func <(_: TestUnapplied<U>, _: TestUnapplied<U>) -> Bool { false }
|
||||||
|
}
|
||||||
|
|
||||||
|
extension TestUnapplied {
|
||||||
|
static func <=>(_: Self, _: @escaping @Sendable (U, U) -> Bool) {}
|
||||||
|
}
|
||||||
|
|
||||||
|
func testUnappliedWithOpetator<T: Comparable>(v: TestUnapplied<T>) {
|
||||||
|
v<=>(>) // expected-error {{converting non-sendable function value to '@Sendable (T, T) -> Bool' may introduce data races}}
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user