Skip to content

Commit 2044cb7

Browse files
authored
Merge pull request #66934 from kabiroberai/main
2 parents 9ccc740 + 4f52380 commit 2044cb7

File tree

3 files changed

+101
-1
lines changed

3 files changed

+101
-1
lines changed

include/swift/AST/DiagnosticsSema.def

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6723,6 +6723,10 @@ WARNING(executor_enqueue_deprecated_owned_job_implementation,Deprecation,
67236723
"'Executor.enqueue(Job)' is deprecated as a protocol requirement; "
67246724
"conform type %0 to 'Executor' by implementing 'func enqueue(ExecutorJob)' instead",
67256725
(Type))
6726+
WARNING(executor_enqueue_unused_implementation, none,
6727+
"'Executor.enqueue(ExecutorJob)' will never be used, due to the presence of "
6728+
"'enqueue(UnownedJob)'",
6729+
())
67266730

67276731
//------------------------------------------------------------------------------
67286732
// MARK: property wrapper diagnostics

lib/Sema/TypeCheckConcurrency.cpp

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1346,8 +1346,34 @@ void swift::tryDiagnoseExecutorConformance(ASTContext &C,
13461346

13471347
// --- Diagnose warnings and errors
13481348

1349+
// true iff the nominal type's availability allows the legacy requirement
1350+
// to be omitted in favor of moveOnlyEnqueueRequirement
1351+
bool canRemoveOldDecls;
1352+
if (!moveOnlyEnqueueRequirement) {
1353+
// The move only enqueue does not exist in this lib version, we must keep relying on the UnownedJob version
1354+
canRemoveOldDecls = false;
1355+
} else if (C.LangOpts.DisableAvailabilityChecking) {
1356+
// Assume we have all APIs available, and thus can use the ExecutorJob
1357+
canRemoveOldDecls = true;
1358+
} else {
1359+
// Check if the availability of nominal is high enough to be using the ExecutorJob version
1360+
AvailabilityContext requirementInfo
1361+
= AvailabilityInference::availableRange(moveOnlyEnqueueRequirement, C);
1362+
AvailabilityContext declInfo =
1363+
TypeChecker::overApproximateAvailabilityAtLocation(nominal->getLoc(), dyn_cast<DeclContext>(nominal));
1364+
canRemoveOldDecls = declInfo.isContainedIn(requirementInfo);
1365+
}
1366+
1367+
// If both old and new enqueue are implemented, but the old one cannot be removed,
1368+
// emit a warning that the new enqueue is unused.
1369+
if (!canRemoveOldDecls &&
1370+
unownedEnqueueWitnessDecl && unownedEnqueueWitnessDecl->getLoc().isValid() &&
1371+
moveOnlyEnqueueWitnessDecl && moveOnlyEnqueueWitnessDecl->getLoc().isValid()) {
1372+
diags.diagnose(moveOnlyEnqueueWitnessDecl->getLoc(), diag::executor_enqueue_unused_implementation);
1373+
}
1374+
13491375
// Old UnownedJob based impl is present, warn about it suggesting the new protocol requirement.
1350-
if (unownedEnqueueWitnessDecl && unownedEnqueueWitnessDecl->getLoc().isValid()) {
1376+
if (canRemoveOldDecls && unownedEnqueueWitnessDecl && unownedEnqueueWitnessDecl->getLoc().isValid()) {
13511377
diags.diagnose(unownedEnqueueWitnessDecl->getLoc(), diag::executor_enqueue_unowned_implementation, nominalTy);
13521378
}
13531379
// Old Job based impl is present, warn about it suggesting the new protocol requirement.
Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
// RUN: %target-typecheck-verify-swift -enable-experimental-move-only
2+
// REQUIRES: concurrency
3+
// REQUIRES: OS=macosx
4+
5+
// rdar://106849189 move-only types should be supported in freestanding mode
6+
// UNSUPPORTED: freestanding
7+
8+
/// Such a type may be encountered since Swift 5.5 (5.1 backdeployed) if someone implemented the
9+
/// not documented, but public Executor types back then already. Allow these to be implemented
10+
/// without warnings.
11+
@available(SwiftStdlib 5.1, *)
12+
final class OldExecutorOldStdlib: SerialExecutor {
13+
func enqueue(_ job: UnownedJob) {}
14+
15+
func asUnownedSerialExecutor() -> UnownedSerialExecutor {
16+
UnownedSerialExecutor(ordinary: self)
17+
}
18+
}
19+
20+
/// We warn on the ExecutorJob witness if the type has a broader
21+
/// availability, since in this case the UnownedJob version needs to exist.
22+
@available(SwiftStdlib 5.1, *)
23+
final class BothExecutorOldStdlib: SerialExecutor {
24+
func enqueue(_ job: UnownedJob) {}
25+
26+
@available(SwiftStdlib 5.9, *)
27+
func enqueue(_ job: __owned ExecutorJob) {} // expected-warning{{'Executor.enqueue(ExecutorJob)' will never be used, due to the presence of 'enqueue(UnownedJob)'}}
28+
29+
func asUnownedSerialExecutor() -> UnownedSerialExecutor {
30+
UnownedSerialExecutor(ordinary: self)
31+
}
32+
}
33+
34+
/// Meanwhile, we warn on the UnownedJob overload if the availability is new enough
35+
/// that it can be dropped.
36+
@available(SwiftStdlib 5.9, *)
37+
final class BothExecutorNewStdlib: SerialExecutor {
38+
func enqueue(_ job: UnownedJob) {} // expected-warning{{'Executor.enqueue(UnownedJob)' is deprecated as a protocol requirement; conform type 'BothExecutorNewStdlib' to 'Executor' by implementing 'func enqueue(ExecutorJob)' instead}}
39+
40+
func enqueue(_ job: __owned ExecutorJob) {}
41+
42+
func asUnownedSerialExecutor() -> UnownedSerialExecutor {
43+
UnownedSerialExecutor(ordinary: self)
44+
}
45+
}
46+
47+
@available(SwiftStdlib 5.9, *)
48+
final class TripleExecutor: SerialExecutor {
49+
func enqueue(_ job: UnownedJob) {} // expected-warning{{'Executor.enqueue(UnownedJob)' is deprecated as a protocol requirement; conform type 'TripleExecutor' to 'Executor' by implementing 'func enqueue(ExecutorJob)' instead}}
50+
51+
// expected-warning@+2{{'Job' is deprecated: renamed to 'ExecutorJob'}}
52+
// expected-note@+1{{use 'ExecutorJob' instead}}
53+
func enqueue(_ job: __owned Job) {} // expected-warning{{'Executor.enqueue(Job)' is deprecated as a protocol requirement; conform type 'TripleExecutor' to 'Executor' by implementing 'func enqueue(ExecutorJob)' instead}}
54+
55+
func enqueue(_ job: consuming ExecutorJob) {}
56+
57+
func asUnownedSerialExecutor() -> UnownedSerialExecutor {
58+
UnownedSerialExecutor(ordinary: self)
59+
}
60+
}
61+
62+
/// Implementing the new signature on 5.9 platforms is good, no warnings
63+
@available(SwiftStdlib 5.9, *)
64+
final class NewExecutorNewStdlib: SerialExecutor {
65+
func enqueue(_ job: __owned ExecutorJob) {}
66+
67+
func asUnownedSerialExecutor() -> UnownedSerialExecutor {
68+
UnownedSerialExecutor(ordinary: self)
69+
}
70+
}

0 commit comments

Comments
 (0)