Skip to content

Commit 4028f15

Browse files
committed
[test] add sendable method and function tests
1 parent 6879961 commit 4028f15

File tree

3 files changed

+126
-6
lines changed

3 files changed

+126
-6
lines changed

lib/Sema/TypeCheckConcurrency.cpp

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2467,7 +2467,7 @@ namespace {
24672467
auto valueRef = declRef->getDeclRef();
24682468
auto value = valueRef.getDecl();
24692469
auto loc = declRef->getLoc();
2470-
2470+
24712471
//FIXME: Should this be subsumed in reference checking?
24722472
if (value->isLocalCapture())
24732473
checkLocalCapture(valueRef, loc, declRef);
@@ -3104,11 +3104,6 @@ namespace {
31043104
getContextIsolation().isActorIsolated())
31053105
unsatisfiedIsolation = ActorIsolation::forNonisolated();
31063106

3107-
// move check for sendability of arguments earlier
3108-
if (!ctx.LangOpts.hasFeature(Feature::DeferredSendableChecking)) {
3109-
diagnoseApplyArgSendability(apply, getDeclContext());
3110-
}
3111-
31123107
// If there was no unsatisfied actor isolation, we're done.
31133108
if (!unsatisfiedIsolation)
31143109
return false;

test/Concurrency/sendable_functions.swift

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,3 +46,12 @@ extension S: Sendable where T: Sendable {
4646

4747
@available(SwiftStdlib 5.1, *)
4848
@MainActor @Sendable func globalActorFuncAsync() async { }
49+
50+
func doWork() -> Int {
51+
Int.random(in: 1..<42)
52+
}
53+
54+
// unapplied global func call
55+
let work: @Sendable () -> Int = doWork
56+
Task<Int, Never>.detached(priority: nil, operation: doWork)
57+
Task<Int, Never>.detached(priority: nil, operation: work)
Lines changed: 116 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,116 @@
1+
// RUN: %target-typecheck-verify-swift
2+
// REQUIRES: concurrency
3+
4+
final class C : Sendable {
5+
func f() {}
6+
}
7+
8+
struct S : Sendable {
9+
func f(){}
10+
}
11+
12+
enum E : Sendable {
13+
case a, b, c
14+
15+
func f() {}
16+
}
17+
18+
protocol P : Sendable {
19+
init()
20+
}
21+
22+
func g<T>(_ f: @escaping @Sendable (T) -> (@Sendable () -> Void)) where T: P {
23+
Task {
24+
let instance = T()
25+
f(instance)()
26+
}
27+
}
28+
29+
final class InferredSendableC: P {
30+
func f() { }
31+
}
32+
33+
struct InferredSendableS: P {
34+
func f() { }
35+
}
36+
37+
enum InferredSendableE: P {
38+
case a, b
39+
40+
func f() { }
41+
}
42+
43+
struct GenericS<T>: P {
44+
func f() { }
45+
}
46+
47+
final class GenericC<T>: P {
48+
func f() { }
49+
}
50+
51+
// Conditional Conformances
52+
extension GenericS : Sendable where T : Sendable { }
53+
extension GenericC : Sendable where T : Sendable { }
54+
55+
class NonSendable {
56+
func f() {}
57+
}
58+
59+
extension E {
60+
init(){
61+
self = .a
62+
}
63+
64+
}
65+
66+
extension InferredSendableE {
67+
init(){
68+
self = .a
69+
}
70+
}
71+
72+
// Unapplied Func Parameter
73+
g(InferredSendableS.f)
74+
g(InferredSendableC.f)
75+
g(InferredSendableE.f)
76+
77+
g(GenericS<Int>.f)
78+
g(GenericC<Int>.f)
79+
80+
g(GenericS<NonSendable>.f)
81+
g(GenericC<NonSendable>.f)
82+
83+
func executeAsTask (_ f: @escaping @Sendable () -> Void) {
84+
Task {
85+
f()
86+
}
87+
}
88+
89+
// Partial Apply Parameter
90+
executeAsTask(C().f)
91+
executeAsTask(S().f)
92+
executeAsTask(E().f)
93+
94+
// Declarations
95+
let us: @Sendable (GenericS<Int>) -> (@Sendable () -> Void) = GenericS<Int>.f
96+
let uc: @Sendable (GenericC<Int>) -> (@Sendable () -> Void) = GenericC<Int>.f
97+
98+
let unappliedStruct: @Sendable (S) -> (@Sendable () -> Void) = S.f
99+
let unappliedClass: @Sendable (C) -> (@Sendable () -> Void) = C.f
100+
let unappliedEnum: @Sendable (E) -> (@Sendable () -> Void) = E.f
101+
102+
var partialStruct : @Sendable () -> Void = S().f
103+
var partialClass : @Sendable () -> Void = C().f
104+
var partialEnum : @Sendable () -> Void = E().f
105+
106+
// Reassign
107+
partialClass = NonSendable().f
108+
partialStruct = NonSendable().f
109+
partialEnum = NonSendable().f
110+
111+
// Static Functions
112+
struct World {
113+
static func greet () { print("hello") }
114+
}
115+
116+
let helloworld: @Sendable () -> Void = World.greet

0 commit comments

Comments
 (0)