Skip to content

Commit b5daa70

Browse files
committed
[Tests] NFC: Add test-cases for actor isolation erasure thunking
1 parent aff9248 commit b5daa70

File tree

1 file changed

+162
-0
lines changed

1 file changed

+162
-0
lines changed
Lines changed: 162 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,162 @@
1+
// RUN: %empty-directory(%t/src)
2+
// RUN: split-file %s %t/src
3+
4+
/// Build the library A
5+
// RUN: %target-swift-frontend -emit-module %t/src/API.swift \
6+
// RUN: -module-name API -swift-version 5 -enable-library-evolution \
7+
// RUN: -emit-module-path %t/API.swiftmodule \
8+
// RUN: -emit-module-interface-path %t/API.swiftinterface
9+
10+
// Build client with module
11+
// RUN: %target-swift-emit-silgen \
12+
// RUN: -I %t \
13+
// RUN: -disable-availability-checking \
14+
// RUN: -module-name Client \
15+
// RUN: -enable-experimental-feature PreconcurrencyConformances \
16+
// RUN: %t/src/Client.swift -verify | %FileCheck %s
17+
18+
// Delete swiftmodule to test building against swiftinterface
19+
// RUN: rm %t/API.swiftmodule
20+
21+
// Build client from interface
22+
// RUN: %target-swift-emit-silgen \
23+
// RUN: -I %t \
24+
// RUN: -disable-availability-checking \
25+
// RUN: -module-name Client \
26+
// RUN: -enable-experimental-feature PreconcurrencyConformances \
27+
// RUN: %t/src/Client.swift -verify | %FileCheck %s
28+
29+
// REQUIRES: asserts
30+
// REQUIRES: concurrency
31+
32+
//--- API.swift
33+
public func compute<T>(_: ((T) -> Void)?) {}
34+
35+
public struct S<T> {
36+
public init() {}
37+
38+
public func test<U>(_: ((T) -> U)?) {}
39+
40+
public subscript(fn: () -> T) -> T {
41+
get { fn() }
42+
}
43+
}
44+
45+
//--- Client.swift
46+
import API
47+
48+
@MainActor func test(_: Int?) {
49+
}
50+
51+
// CHECK-LABEL: sil hidden [ossa] @$s6Client20testMainActorContextyyF : $@convention(thin) () -> ()
52+
// CHECK: [[TEST_REF:%.*]] = function_ref @$s6Client4testyySiSgF : $@convention(thin) (Optional<Int>) -> ()
53+
// CHECK-NEXT: [[TEST_FN:%.*]] = thin_to_thick_function [[TEST_REF]] : $@convention(thin) (Optional<Int>) -> () to $@callee_guaranteed (Optional<Int>) -> ()
54+
// CHECK: [[THUNK:%.*]] = function_ref @$sSiSgIegy_AAIegy_TRScMTU : $@convention(thin) (Optional<Int>, @guaranteed @callee_guaranteed (Optional<Int>) -> ()) -> ()
55+
// CHECK-NEXT: [[THUNKED_TEST_REF:%.*]] = partial_apply [callee_guaranteed] [[THUNK]]([[TEST_FN]]) : $@convention(thin) (Optional<Int>, @guaranteed @callee_guaranteed (Optional<Int>) -> ()) -> ()
56+
// CHECK-NEXT: [[OPTIONAL_TEST:%.*]] = enum $Optional<@callee_guaranteed (Optional<Int>) -> ()>, #Optional.some!enumelt, [[THUNKED_TEST_REF]] : $@callee_guaranteed (Optional<Int>) -> ()
57+
// CHECK-NEXT: switch_enum [[OPTIONAL_TEST]] : $Optional<@callee_guaranteed (Optional<Int>) -> ()>, case #Optional.some!enumelt: bb1, case #Optional.none!enumelt: bb2
58+
// CHECK: bb3([[UNWRAPPED_TEST_REF:%.*]] : @owned $Optional<@callee_guaranteed @substituted <τ_0_0> (@in_guaranteed τ_0_0) -> () for <Optional<Int>>>):
59+
// CHECK: [[COMPUTE_REF:%.*]] = function_ref @$s3API7computeyyyxcSglF : $@convention(thin) <τ_0_0> (@guaranteed Optional<@callee_guaranteed @substituted <τ_0_0> (@in_guaranteed τ_0_0) -> () for <τ_0_0>>) -> ()
60+
// CHECK-NEXT: {{.*}} = apply [[COMPUTE_REF]]<Int?>([[UNWRAPPED_TEST_REF]]) : $@convention(thin) <τ_0_0> (@guaranteed Optional<@callee_guaranteed @substituted <τ_0_0> (@in_guaranteed τ_0_0) -> () for <τ_0_0>>) -> ()
61+
@MainActor
62+
func testMainActorContext() {
63+
compute(test) // no warning
64+
}
65+
66+
// CHECK-LABEL: sil shared [transparent] [serialized] [reabstraction_thunk] [ossa] @$sSiSgIegy_AAIegy_TRScMTU : $@convention(thin) (Optional<Int>, @guaranteed @callee_guaranteed (Optional<Int>) -> ()) -> ()
67+
// CHECK: [[MAIN_ACTOR_METATYPE:%.*]] = metatype $@thick MainActor.Type
68+
// CHECK: [[SHARED_FIELD_GETTER:%.*]] = function_ref @$sScM6sharedScMvgZ : $@convention(method) (@thick MainActor.Type) -> @owned MainActor
69+
// CHECK-NEXT: [[MAIN_ACTOR:%.*]] = apply [[SHARED_FIELD_GETTER]]([[MAIN_ACTOR_METATYPE]]) : $@convention(method) (@thick MainActor.Type) -> @owned MainActor
70+
// CHECK-NEXT: [[MAIN_ACTOR_ACCESS:%.*]] = begin_borrow [[MAIN_ACTOR]] : $MainActor
71+
// CHECK-NEXT: [[EXEC:%.*]] = extract_executor [[MAIN_ACTOR_ACCESS]] : $MainActor
72+
// CHECK: [[CHECK_EXEC_REF:%.*]] = function_ref @$ss22_checkExpectedExecutor14_filenameStart01_D6Length01_D7IsASCII5_line9_executoryBp_BwBi1_BwBetF
73+
// CHECK-NEXT: {{.*}} = apply [[CHECK_EXEC_REF]]({{.*}}, [[EXEC]])
74+
75+
76+
// CHECK-LABEL: sil hidden [ossa] @$s6Client17testComplexGlobalyyyxSgScMYcclF : $@convention(thin) <U> (@guaranteed @callee_guaranteed @substituted <τ_0_0> (@in_guaranteed Optional<τ_0_0>) -> () for <U>) -> ()
77+
func testComplexGlobal<U>(_ fn: @escaping @MainActor (U?) -> Void) {
78+
// CHECK: [[FN:%.*]] = copy_value %0 : $@callee_guaranteed @substituted <τ_0_0> (@in_guaranteed Optional<τ_0_0>) -> () for <U>
79+
// CHECK-NEXT: [[SUBST_FN:%.*]] = convert_function [[FN]] : $@callee_guaranteed @substituted <τ_0_0> (@in_guaranteed Optional<τ_0_0>) -> () for <U> to $@callee_guaranteed (@in_guaranteed Optional<U>) -> ()
80+
// CHECK: [[FN_THUNK:%.*]] = function_ref @$sxSgIegn_AAIegn_lTRScMTU : $@convention(thin) <τ_0_0> (@in_guaranteed Optional<τ_0_0>, @guaranteed @callee_guaranteed (@in_guaranteed Optional<τ_0_0>) -> ()) -> ()
81+
// CHECK-NEXT: [[THUNKED_FN:%.*]] = partial_apply [callee_guaranteed] [[FN_THUNK]]<U>([[SUBST_FN]]) : $@convention(thin) <τ_0_0> (@in_guaranteed Optional<τ_0_0>, @guaranteed @callee_guaranteed (@in_guaranteed Optional<τ_0_0>) -> ()) -> ()
82+
// CHECK-NEXT: [[SUBST_THUNKED_FN:%.*]] = convert_function [[THUNKED_FN]] : $@callee_guaranteed (@in_guaranteed Optional<U>) -> () to $@callee_guaranteed @substituted <τ_0_0> (@in_guaranteed Optional<τ_0_0>) -> () for <U>
83+
// CHECK-NEXT: {{.*}} = enum $Optional<@callee_guaranteed @substituted <τ_0_0> (@in_guaranteed Optional<τ_0_0>) -> () for <U>>, #Optional.some!enumelt, [[SUBST_THUNKED_FN]] : $@callee_guaranteed @substituted <τ_0_0> (@in_guaranteed Optional<τ_0_0>) -> () for <U>
84+
compute(fn)
85+
// expected-warning@-1 {{converting function value of type '@MainActor (U?) -> Void' to '(U?) -> Void' loses global actor 'MainActor'; this is an error in Swift 6}}
86+
87+
// CHECK: [[CLOSURE:%.*]] = function_ref @$s6Client17testComplexGlobalyyyxSgScMYcclFySiScMYccfU_ : $@convention(thin) (Int) -> ()
88+
// CHECK-NEXT: [[CLOSURE_REF:%.*]] = thin_to_thick_function [[CLOSURE]] : $@convention(thin) (Int) -> () to $@callee_guaranteed (Int) -> ()
89+
// CHECK: [[CLOSURE_THUNK:%.*]] = function_ref @$sSiIegy_SiIegy_TRScMTU : $@convention(thin) (Int, @guaranteed @callee_guaranteed (Int) -> ()) -> ()
90+
// CHECK-NEXT: {{.*}} = partial_apply [callee_guaranteed] [[CLOSURE_THUNK]]([[CLOSURE_REF]]) : $@convention(thin) (Int, @guaranteed @callee_guaranteed (Int) -> ()) -> ()
91+
compute { @MainActor (arg: Int) -> Void in
92+
// expected-warning@-1 {{converting function value of type '@MainActor (Int) -> Void' to '(Int) -> Void' loses global actor 'MainActor'; this is an error in Swift 6}}
93+
}
94+
}
95+
96+
// CHECK-LABEL: sil shared [transparent] [serialized] [reabstraction_thunk] [ossa] @$sxSgIegn_AAIegn_lTRScMTU : $@convention(thin) <U> (@in_guaranteed Optional<U>, @guaranteed @callee_guaranteed (@in_guaranteed Optional<U>) -> ()) -> ()
97+
// CHECK: [[MAIN_ACTOR_METATYPE:%.*]] = metatype $@thick MainActor.Type
98+
// CHECK: [[SHARED_FIELD_GETTER:%.*]] = function_ref @$sScM6sharedScMvgZ : $@convention(method) (@thick MainActor.Type) -> @owned MainActor
99+
// CHECK-NEXT: [[MAIN_ACTOR:%.*]] = apply [[SHARED_FIELD_GETTER]]([[MAIN_ACTOR_METATYPE]]) : $@convention(method) (@thick MainActor.Type) -> @owned MainActor
100+
// CHECK-NEXT: [[MAIN_ACTOR_ACCESS:%.*]] = begin_borrow [[MAIN_ACTOR]] : $MainActor
101+
// CHECK-NEXT: [[EXEC:%.*]] = extract_executor [[MAIN_ACTOR_ACCESS]] : $MainActor
102+
// CHECK: [[CHECK_EXEC_REF:%.*]] = function_ref @$ss22_checkExpectedExecutor14_filenameStart01_D6Length01_D7IsASCII5_line9_executoryBp_BwBi1_BwBetF
103+
// CHECK-NEXT: {{.*}} = apply [[CHECK_EXEC_REF]]({{.*}}, [[EXEC]])
104+
105+
// CHECK-LABEL: sil shared [transparent] [serialized] [reabstraction_thunk] [ossa] @$sSiIegy_SiIegy_TRScMTU : $@convention(thin) (Int, @guaranteed @callee_guaranteed (Int) -> ()) -> ()
106+
// CHECK: [[MAIN_ACTOR_METATYPE:%.*]] = metatype $@thick MainActor.Type
107+
// CHECK: [[SHARED_FIELD_GETTER:%.*]] = function_ref @$sScM6sharedScMvgZ : $@convention(method) (@thick MainActor.Type) -> @owned MainActor
108+
// CHECK-NEXT: [[MAIN_ACTOR:%.*]] = apply [[SHARED_FIELD_GETTER]]([[MAIN_ACTOR_METATYPE]]) : $@convention(method) (@thick MainActor.Type) -> @owned MainActor
109+
// CHECK-NEXT: [[MAIN_ACTOR_ACCESS:%.*]] = begin_borrow [[MAIN_ACTOR]] : $MainActor
110+
// CHECK-NEXT: [[EXEC:%.*]] = extract_executor [[MAIN_ACTOR_ACCESS]] : $MainActor
111+
// CHECK: [[CHECK_EXEC_REF:%.*]] = function_ref @$ss22_checkExpectedExecutor14_filenameStart01_D6Length01_D7IsASCII5_line9_executoryBp_BwBi1_BwBetF
112+
// CHECK-NEXT: {{.*}} = apply [[CHECK_EXEC_REF]]({{.*}}, [[EXEC]])
113+
114+
// CHECK-LABEL: sil hidden [ossa] @$s6Client11testMembers1v1s2fnyx_3API1SVyxGSixScMYcctlF : $@convention(thin) <X> (@in_guaranteed X, @in_guaranteed S<X>, @guaranteed @callee_guaranteed @substituted <τ_0_0> (@in_guaranteed τ_0_0) -> Int for <X>) -> ()
115+
@MainActor
116+
func testMembers<X>(v: X, s: S<X>, fn: @escaping @MainActor (X) -> Int) {
117+
// CHECK: [[FN_COPY:%.*]] = copy_value %2 : $@callee_guaranteed @substituted <τ_0_0> (@in_guaranteed τ_0_0) -> Int for <X>
118+
// CHECK-NEXT: [[FN:%.*]] = convert_function [[FN_COPY]] : $@callee_guaranteed @substituted <τ_0_0> (@in_guaranteed τ_0_0) -> Int for <X> to $@callee_guaranteed (@in_guaranteed X) -> Int
119+
// CHECK: [[FN_THUNK:%.*]] = function_ref @$sxSiIegnd_xSiIegnd_lTRScMTU : $@convention(thin) <τ_0_0> (@in_guaranteed τ_0_0, @guaranteed @callee_guaranteed (@in_guaranteed τ_0_0) -> Int) -> Int
120+
// CHECK-NEXT: [[THUNKED_FN:%.*]] = partial_apply [callee_guaranteed] [[FN_THUNK]]<X>([[FN]]) : $@convention(thin) <τ_0_0> (@in_guaranteed τ_0_0, @guaranteed @callee_guaranteed (@in_guaranteed τ_0_0) -> Int) -> Int
121+
// CHECK-NEXT: {{.*}} = convert_function [[THUNKED_FN]] : $@callee_guaranteed (@in_guaranteed X) -> Int to $@callee_guaranteed @substituted <τ_0_0> (@in_guaranteed τ_0_0) -> Int for <X>
122+
s.test(fn)
123+
124+
// CHECK: [[CLOSURE_REF:%.*]] = function_ref @$s6Client11testMembers1v1s2fnyx_3API1SVyxGSixScMYcctlFxyScMYcXEfU_ : $@convention(thin) <τ_0_0> (@in_guaranteed τ_0_0) -> @out τ_0_0
125+
// CHECK-NEXT: [[V:%.*]] = alloc_stack $X
126+
// CHECK-NEXT: copy_addr %0 to [init] [[V]] : $*X
127+
// CHECK-NEXT: [[CLOSURE:%.*]] = partial_apply [callee_guaranteed] [[CLOSURE_REF]]<X>([[V]]) : $@convention(thin) <τ_0_0> (@in_guaranteed τ_0_0) -> @out τ_0_0
128+
// CHECK-NEXT: [[SUBST_CLOSURE:%.*]] = convert_function [[CLOSURE]] : $@callee_guaranteed () -> @out X to $@callee_guaranteed @substituted <τ_0_0> () -> @out τ_0_0 for <X>
129+
// CHECK-NEXT: [[NOESCAPE_SUBST_CLOSURE:%.*]] = convert_escape_to_noescape [not_guaranteed] [[SUBST_CLOSURE]] : $@callee_guaranteed @substituted <τ_0_0> () -> @out τ_0_0 for <X> to $@noescape @callee_guaranteed @substituted <τ_0_0> () -> @out τ_0_0 for <X>
130+
// CHECK-NEXT: [[CLOSURE:%.*]] = convert_function [[NOESCAPE_SUBST_CLOSURE]] : $@noescape @callee_guaranteed @substituted <τ_0_0> () -> @out τ_0_0 for <X> to $@noescape @callee_guaranteed () -> @out X
131+
// CHECK: [[CLOSURE_THUNK_REF:%.*]] = function_ref @$sxIgr_xIgr_lTRScMTU : $@convention(thin) <τ_0_0> (@guaranteed @noescape @callee_guaranteed () -> @out τ_0_0) -> @out τ_0_0
132+
// CHECK-NEXT: [[THUNKED_CLOSURE:%.*]] = partial_apply [callee_guaranteed] [[CLOSURE_THUNK_REF]]<X>([[CLOSURE]]) : $@convention(thin) <τ_0_0> (@guaranteed @noescape @callee_guaranteed () -> @out τ_0_0) -> @out τ_0_0
133+
// CHECK-NEXT: [[SUBST_THUNKED_CLOSURE:%.*]] = convert_function [[THUNKED_CLOSURE]] : $@callee_guaranteed () -> @out X to $@callee_guaranteed @substituted <τ_0_0> () -> @out τ_0_0 for <X>
134+
// CHECK-NEXT: [[THUNKED_CLOSURE:%.*]] = convert_escape_to_noescape [not_guaranteed] [[SUBST_THUNKED_CLOSURE]] : $@callee_guaranteed @substituted <τ_0_0> () -> @out τ_0_0 for <X> to $@noescape @callee_guaranteed @substituted <τ_0_0> () -> @out τ_0_0 for <X>
135+
// CHECK: [[SETTER_REF:%.*]] = function_ref @$s3API1SVyxxyXEcig : $@convention(method) <τ_0_0> (@guaranteed @noescape @callee_guaranteed @substituted <τ_0_0> () -> @out τ_0_0 for <τ_0_0>, @in_guaranteed S<τ_0_0>) -> @out τ_0_0
136+
// CHECK-NEXT: %41 = apply [[SETTER_REF]]<X>({{.*}}, [[THUNKED_CLOSURE]], {{.*}}) : $@convention(method) <τ_0_0> (@guaranteed @noescape @callee_guaranteed @substituted <τ_0_0> () -> @out τ_0_0 for <τ_0_0>, @in_guaranteed S<τ_0_0>) -> @out τ_0_0
137+
_ = s[{ @MainActor in v }]
138+
139+
// CHECK: [[TEST_REF:%.*]] = function_ref @$s6Client4testyySiSgF : $@convention(thin) (Optional<Int>) -> ()
140+
// CHECK-NEXT: [[TEST:%.*]] = thin_to_thick_function [[TEST_REF]] : $@convention(thin) (Optional<Int>) -> () to $@callee_guaranteed (Optional<Int>) -> ()
141+
// CHECK: [[TEST_THUNK_REF:%.*]] = function_ref @$sSiSgIegy_AAIegy_TRScMTU : $@convention(thin) (Optional<Int>, @guaranteed @callee_guaranteed (Optional<Int>) -> ()) -> ()
142+
// CHECK-NEXT: {{.*}} = partial_apply [callee_guaranteed] [[TEST_THUNK_REF]]([[TEST]]) : $@convention(thin) (Optional<Int>, @guaranteed @callee_guaranteed (Optional<Int>) -> ()) -> ()
143+
S().test(test)
144+
}
145+
146+
// CHECK-LABEL: sil shared [transparent] [serialized] [reabstraction_thunk] [ossa] @$sxSiIegnd_xSiIegnd_lTRScMTU : $@convention(thin) <X> (@in_guaranteed X, @guaranteed @callee_guaranteed (@in_guaranteed X) -> Int) -> Int
147+
// CHECK: [[MAIN_ACTOR_METATYPE:%.*]] = metatype $@thick MainActor.Type
148+
// CHECK: [[SHARED_FIELD_GETTER:%.*]] = function_ref @$sScM6sharedScMvgZ : $@convention(method) (@thick MainActor.Type) -> @owned MainActor
149+
// CHECK-NEXT: [[MAIN_ACTOR:%.*]] = apply [[SHARED_FIELD_GETTER]]([[MAIN_ACTOR_METATYPE]]) : $@convention(method) (@thick MainActor.Type) -> @owned MainActor
150+
// CHECK-NEXT: [[MAIN_ACTOR_ACCESS:%.*]] = begin_borrow [[MAIN_ACTOR]] : $MainActor
151+
// CHECK-NEXT: [[EXEC:%.*]] = extract_executor [[MAIN_ACTOR_ACCESS]] : $MainActor
152+
// CHECK: [[CHECK_EXEC_REF:%.*]] = function_ref @$ss22_checkExpectedExecutor14_filenameStart01_D6Length01_D7IsASCII5_line9_executoryBp_BwBi1_BwBetF
153+
// CHECK-NEXT: {{.*}} = apply [[CHECK_EXEC_REF]]({{.*}}, [[EXEC]])
154+
155+
// CHECK-LABEL: sil shared [transparent] [serialized] [reabstraction_thunk] [ossa] @$sxIgr_xIgr_lTRScMTU : $@convention(thin) <X> (@guaranteed @noescape @callee_guaranteed () -> @out X) -> @out X
156+
// CHECK: [[MAIN_ACTOR_METATYPE:%.*]] = metatype $@thick MainActor.Type
157+
// CHECK: [[SHARED_FIELD_GETTER:%.*]] = function_ref @$sScM6sharedScMvgZ : $@convention(method) (@thick MainActor.Type) -> @owned MainActor
158+
// CHECK-NEXT: [[MAIN_ACTOR:%.*]] = apply [[SHARED_FIELD_GETTER]]([[MAIN_ACTOR_METATYPE]]) : $@convention(method) (@thick MainActor.Type) -> @owned MainActor
159+
// CHECK-NEXT: [[MAIN_ACTOR_ACCESS:%.*]] = begin_borrow [[MAIN_ACTOR]] : $MainActor
160+
// CHECK-NEXT: [[EXEC:%.*]] = extract_executor [[MAIN_ACTOR_ACCESS]] : $MainActor
161+
// CHECK: [[CHECK_EXEC_REF:%.*]] = function_ref @$ss22_checkExpectedExecutor14_filenameStart01_D6Length01_D7IsASCII5_line9_executoryBp_BwBi1_BwBetF
162+
// CHECK-NEXT: {{.*}} = apply [[CHECK_EXEC_REF]]({{.*}}, [[EXEC]])

0 commit comments

Comments
 (0)