Skip to content

Commit 3fe201a

Browse files
committed
[Sema] Update custom executor warning tests, impl
1 parent c499dd2 commit 3fe201a

File tree

3 files changed

+89
-43
lines changed

3 files changed

+89
-43
lines changed

lib/Sema/TypeCheckConcurrency.cpp

Lines changed: 17 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1334,18 +1334,10 @@ void swift::tryDiagnoseExecutorConformance(ASTContext &C,
13341334
ValueDecl *unownedEnqueueWitnessDecl = unownedEnqueueWitness.getDecl();
13351335
ValueDecl *moveOnlyEnqueueWitnessDecl = nullptr;
13361336
ValueDecl *legacyMoveOnlyEnqueueWitnessDecl = nullptr;
1337-
// true iff the nominal type's availability allows the legacy requirement
1338-
// to be omitted in favor of moveOnlyEnqueueRequirement
1339-
bool canRemoveOldDecls = false;
13401337

13411338
if (moveOnlyEnqueueRequirement) {
13421339
moveOnlyEnqueueWitnessDecl = concreteConformance->getWitnessDeclRef(
13431340
moveOnlyEnqueueRequirement).getDecl();
1344-
AvailabilityContext requirementInfo
1345-
= AvailabilityInference::availableRange(moveOnlyEnqueueRequirement, C);
1346-
AvailabilityContext declInfo =
1347-
TypeChecker::overApproximateAvailabilityAtLocation(nominal->getLoc(), dyn_cast<DeclContext>(nominal));
1348-
canRemoveOldDecls = declInfo.isContainedIn(requirementInfo);
13491341
}
13501342
if (legacyMoveOnlyEnqueueRequirement) {
13511343
legacyMoveOnlyEnqueueWitnessDecl = concreteConformance->getWitnessDeclRef(
@@ -1354,6 +1346,23 @@ void swift::tryDiagnoseExecutorConformance(ASTContext &C,
13541346

13551347
// --- Diagnose warnings and errors
13561348

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+
canRemoveOldDecls = false;
1354+
} else if (C.LangOpts.DisableAvailabilityChecking) {
1355+
canRemoveOldDecls = true;
1356+
} else {
1357+
AvailabilityContext requirementInfo
1358+
= AvailabilityInference::availableRange(moveOnlyEnqueueRequirement, C);
1359+
AvailabilityContext declInfo =
1360+
TypeChecker::overApproximateAvailabilityAtLocation(nominal->getLoc(), dyn_cast<DeclContext>(nominal));
1361+
canRemoveOldDecls = declInfo.isContainedIn(requirementInfo);
1362+
}
1363+
1364+
// If both old and new enqueue are implemented, but the old one cannot be removed,
1365+
// emit a warning that the new enqueue is unused.
13571366
if (!canRemoveOldDecls &&
13581367
unownedEnqueueWitnessDecl && unownedEnqueueWitnessDecl->getLoc().isValid() &&
13591368
moveOnlyEnqueueWitnessDecl && moveOnlyEnqueueWitnessDecl->getLoc().isValid()) {
Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
// RUN: %target-typecheck-verify-swift -enable-experimental-move-only
2+
// REQUIRES: concurrency
3+
// REQUIRES: OS=macosx
4+
5+
/// Such a type may be encountered since Swift 5.5 (5.1 backdeployed) if someone implemented the
6+
/// not documented, but public Executor types back then already. Allow these to be implemented
7+
/// without warnings.
8+
@available(SwiftStdlib 5.1, *)
9+
final class OldExecutorOldStdlib: SerialExecutor {
10+
func enqueue(_ job: UnownedJob) {}
11+
12+
func asUnownedSerialExecutor() -> UnownedSerialExecutor {
13+
UnownedSerialExecutor(ordinary: self)
14+
}
15+
}
16+
17+
/// We warn on the ExecutorJob witness if the type has a broader
18+
/// availability, since in this case the UnownedJob version needs to exist.
19+
@available(SwiftStdlib 5.1, *)
20+
final class BothExecutorOldStdlib: SerialExecutor {
21+
func enqueue(_ job: UnownedJob) {}
22+
23+
@available(SwiftStdlib 5.9, *)
24+
func enqueue(_ job: __owned ExecutorJob) {} // expected-warning{{'Executor.enqueue(ExecutorJob)' will never be used, due to the presence of 'enqueue(UnownedJob)'}}
25+
26+
func asUnownedSerialExecutor() -> UnownedSerialExecutor {
27+
UnownedSerialExecutor(ordinary: self)
28+
}
29+
}
30+
31+
/// Meanwhile, we warn on the UnownedJob overload if the availability is new enough
32+
/// that it can be dropped.
33+
@available(SwiftStdlib 5.9, *)
34+
final class BothExecutorNewStdlib: SerialExecutor {
35+
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}}
36+
37+
func enqueue(_ job: __owned ExecutorJob) {}
38+
39+
func asUnownedSerialExecutor() -> UnownedSerialExecutor {
40+
UnownedSerialExecutor(ordinary: self)
41+
}
42+
}
43+
44+
@available(SwiftStdlib 5.9, *)
45+
final class TripleExecutor: SerialExecutor {
46+
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}}
47+
48+
// expected-warning@+2{{'Job' is deprecated: renamed to 'ExecutorJob'}}
49+
// expected-note@+1{{use 'ExecutorJob' instead}}
50+
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}}
51+
52+
func enqueue(_ job: consuming ExecutorJob) {}
53+
54+
func asUnownedSerialExecutor() -> UnownedSerialExecutor {
55+
UnownedSerialExecutor(ordinary: self)
56+
}
57+
}
58+
59+
/// Implementing the new signature on 5.9 platforms is good, no warnings
60+
@available(SwiftStdlib 5.9, *)
61+
final class NewExecutorNewStdlib: SerialExecutor {
62+
func enqueue(_ job: __owned ExecutorJob) {}
63+
64+
func asUnownedSerialExecutor() -> UnownedSerialExecutor {
65+
UnownedSerialExecutor(ordinary: self)
66+
}
67+
}

test/Concurrency/custom_executor_enqueue_impls.swift

Lines changed: 5 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// RUN: %target-typecheck-verify-swift -enable-experimental-move-only
1+
// RUN: %target-typecheck-verify-swift -enable-experimental-move-only -disable-availability-checking
22
// REQUIRES: concurrency
33

44
// rdar://106849189 move-only types should be supported in freestanding mode
@@ -7,8 +7,10 @@
77
// FIXME: rdar://107112715 test failing on iOS simulator, investigating
88
// UNSUPPORTED: OS=ios
99

10-
// If the availability is recent enough, log a deprecation warning to move to the new signature.
11-
@available(SwiftStdlib 5.9, *)
10+
// Such type may be encountered since Swift 5.5 (5.1 backdeployed) if someone implemented the
11+
// not documented, but public Executor types back then already.
12+
//
13+
// We keep support for them, but also log a deprecation warning that they should move to the new signature.
1214
final class OldExecutor: SerialExecutor {
1315
func enqueue(_ job: UnownedJob) {} // expected-warning{{'Executor.enqueue(UnownedJob)' is deprecated as a protocol requirement; conform type 'OldExecutor' to 'Executor' by implementing 'func enqueue(ExecutorJob)' instead}}
1416

@@ -17,23 +19,10 @@ final class OldExecutor: SerialExecutor {
1719
}
1820
}
1921

20-
/// Such a type may be encountered since Swift 5.5 (5.1 backdeployed) if someone implemented the
21-
/// not documented, but public Executor types back then already. Allow these to be implemented
22-
/// without warnings.
23-
@available(SwiftStdlib 5.1, *)
24-
final class OldExecutorOldStdlib: SerialExecutor {
25-
func enqueue(_ job: UnownedJob) {}
26-
27-
func asUnownedSerialExecutor() -> UnownedSerialExecutor {
28-
UnownedSerialExecutor(ordinary: self)
29-
}
30-
}
31-
3222
/// Implementing both enqueue methods is legal, but somewhat useless --
3323
/// we call into the "old one"; so the Owned version is not used in such impl.
3424
///
3525
/// That's why we do log the deprecation warning, people should use the move-only version.
36-
@available(SwiftStdlib 5.9, *)
3726
final class BothExecutor: SerialExecutor {
3827
func enqueue(_ job: UnownedJob) {} // expected-warning{{'Executor.enqueue(UnownedJob)' is deprecated as a protocol requirement; conform type 'BothExecutor' to 'Executor' by implementing 'func enqueue(ExecutorJob)' instead}}
3928

@@ -44,22 +33,7 @@ final class BothExecutor: SerialExecutor {
4433
}
4534
}
4635

47-
/// Meanwhile, we warn on the ExecutorJob witness if the type has a broader
48-
/// availability, since in this case the UnownedJob version needs to exist.
49-
@available(SwiftStdlib 5.1, *)
50-
final class BothExecutorOld: SerialExecutor {
51-
func enqueue(_ job: UnownedJob) {}
52-
53-
@available(SwiftStdlib 5.9, *)
54-
func enqueue(_ job: __owned ExecutorJob) {} // expected-warning{{'Executor.enqueue(ExecutorJob)' will never be used, due to the presence of 'enqueue(UnownedJob)'}}
55-
56-
func asUnownedSerialExecutor() -> UnownedSerialExecutor {
57-
UnownedSerialExecutor(ordinary: self)
58-
}
59-
}
60-
6136
/// For now we must keep all 3 implementation kinds and warn about deprecated ones
62-
@available(SwiftStdlib 5.9, *)
6337
final class TripleExecutor: SerialExecutor {
6438
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}}
6539

@@ -78,7 +52,6 @@ final class TripleExecutor: SerialExecutor {
7852
/// we manually detect and emit an error if neither of them is implemented.
7953
///
8054
/// We do so because we implement them recursively, so one of them must be implemented basically.
81-
@available(SwiftStdlib 5.9, *)
8255
final class NoneExecutor: SerialExecutor { // expected-error{{type 'NoneExecutor' does not conform to protocol 'Executor'}}
8356

8457
func asUnownedSerialExecutor() -> UnownedSerialExecutor {
@@ -87,7 +60,6 @@ final class NoneExecutor: SerialExecutor { // expected-error{{type 'NoneExecutor
8760
}
8861

8962
/// Job still is deprecated
90-
@available(SwiftStdlib 5.9, *)
9163
final class StillDeprecated: SerialExecutor {
9264
// expected-warning@+2{{'Job' is deprecated: renamed to 'ExecutorJob'}}
9365
// expected-note@+1{{use 'ExecutorJob' instead}}
@@ -99,7 +71,6 @@ final class StillDeprecated: SerialExecutor {
9971
}
10072

10173
/// Just implementing the new signature causes no warnings, good.
102-
@available(SwiftStdlib 5.9, *)
10374
final class NewExecutor: SerialExecutor {
10475
func enqueue(_ job: consuming ExecutorJob) {} // no warnings
10576

@@ -109,7 +80,6 @@ final class NewExecutor: SerialExecutor {
10980
}
11081

11182
// Good impl, but missing the ownership keyword
112-
@available(SwiftStdlib 5.9, *)
11383
final class MissingOwnership: SerialExecutor {
11484
func enqueue(_ job: ExecutorJob) {} // expected-error{{noncopyable parameter must specify its ownership}}
11585
// expected-note@-1{{add 'borrowing' for an immutable reference}}

0 commit comments

Comments
 (0)