Skip to content

Commit 16c5c36

Browse files
committed
test: for noncopyable through subscript using coroutine
1 parent 4964a66 commit 16c5c36

File tree

1 file changed

+124
-0
lines changed

1 file changed

+124
-0
lines changed
Lines changed: 124 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,124 @@
1+
// RUN: %target-swift-emit-silgen -DTRIVIAL %s | %FileCheck --check-prefix TRIVIAL %s
2+
// RUN: %target-swift-emit-sil -DTRIVIAL -sil-verify-all %s > /dev/null
3+
4+
// RUN: %target-swift-emit-silgen -DLOADABLE %s | %FileCheck --check-prefix LOADABLE %s
5+
// RUN: %target-swift-emit-sil -DLOADABLE -sil-verify-all %s > /dev/null
6+
7+
// RUN: %target-swift-emit-silgen -DADDRESS_ONLY %s | %FileCheck --check-prefix ADDRESS_ONLY %s
8+
// RUN: %target-swift-emit-sil -DADDRESS_ONLY -sil-verify-all %s > /dev/null
9+
10+
class X {
11+
let snc = SNC()
12+
}
13+
14+
struct NC: ~Copyable {
15+
#if TRIVIAL
16+
typealias T = Int
17+
var x: T = 0
18+
#elseif LOADABLE
19+
typealias T = X
20+
var x: T = X()
21+
#elseif ADDRESS_ONLY
22+
typealias T = Any
23+
var x: T = X()
24+
#else
25+
#error("pick a mode")
26+
#endif
27+
28+
var consumingGetter: T {
29+
consuming get { fatalError() }
30+
}
31+
var readCoroutine: T {
32+
_read { yield x }
33+
}
34+
consuming func consumingFunc() -> T { fatalError() }
35+
borrowing func borrowingFunc() -> T { fatalError() }
36+
37+
deinit { print("destroy") }
38+
}
39+
40+
struct SNC: ~Copyable {
41+
private var _data: NC = NC()
42+
43+
subscript(index: Int) -> NC {
44+
_read { yield _data }
45+
_modify { yield &_data }
46+
}
47+
}
48+
49+
func use(_ x: NC.T) {}
50+
51+
52+
// TRIVIAL-LABEL: sil hidden [ossa] @${{.*}}test_subscript_read3sncyAA3SNCV_tF : $@convention(thin) (@guaranteed SNC) -> () {
53+
// TRIVIAL: ([[YIELDED:%.*]], [[HANDLE:%.*]]) = begin_apply
54+
// TRIVIAL: [[COPY:%.*]] = copy_value [[YIELDED]]
55+
// TRIVIAL: [[MARK:%.*]] = mark_unresolved_non_copyable_value [no_consume_or_assign] [[COPY]]
56+
// TRIVIAL: [[BORROW_MARK:%.*]] = begin_borrow [[MARK]]
57+
// TRIVIAL: [[X:%.*]] = struct_extract [[BORROW_MARK]], #NC.x
58+
// TRIVIAL: end_borrow [[BORROW_MARK]]
59+
// TRIVIAL: destroy_value [[MARK]]
60+
// TRIVIAL: = end_apply [[HANDLE]] as $()
61+
// TRIVIAL: = apply {{%.*}}([[X]])
62+
63+
64+
// LOADABLE-LABEL: sil hidden [ossa] @${{.*}}test_subscript_read3sncyAA3SNCV_tF : $@convention(thin) (@guaranteed SNC) -> () {
65+
// LOADABLE: ([[YIELDED:%.*]], [[HANDLE:%.*]]) = begin_apply
66+
// LOADABLE: [[COPY:%.*]] = copy_value [[YIELDED]]
67+
// LOADABLE: [[MARK:%.*]] = mark_unresolved_non_copyable_value [no_consume_or_assign] [[COPY]]
68+
// LOADABLE: [[BORROW_MARK:%.*]] = begin_borrow [[MARK]]
69+
// LOADABLE: [[X:%.*]] = struct_extract [[BORROW_MARK]], #NC.x
70+
71+
// LOADABLE: [[X_COPY:%.*]] = copy_value [[X]]
72+
73+
// LOADABLE: end_borrow [[BORROW_MARK]]
74+
// LOADABLE: destroy_value [[MARK]]
75+
// LOADABLE: = end_apply [[HANDLE]] as $()
76+
77+
// LOADABLE: = apply {{%.*}}([[X_COPY]])
78+
79+
80+
81+
// ADDRESS_ONLY-LABEL: sil hidden [ossa] @${{.*}}test_subscript_read3sncyAA3SNCV_tF : $@convention(thin) (@in_guaranteed SNC) -> () {
82+
// ADDRESS_ONLY: ([[YIELDED:%.*]], [[HANDLE:%.*]]) = begin_apply
83+
84+
// ADDRESS_ONLY: [[MARK:%.*]] = mark_unresolved_non_copyable_value [no_consume_or_assign] [[YIELDED]]
85+
// ADDRESS_ONLY: [[X_FIELD_ADDR:%.*]] = struct_element_addr [[MARK]], #NC.x
86+
// ADDRESS_ONLY: [[X_LOCAL_ADDR:%.*]] = alloc_stack $Any
87+
// ADDRESS_ONLY: copy_addr [[X_FIELD_ADDR]] to [init] [[X_LOCAL_ADDR]]
88+
// ADDRESS_ONLY: = end_apply [[HANDLE]] as $()
89+
// ADDRESS_ONLY: = apply {{%.*}}([[X_LOCAL_ADDR]])
90+
// ADDRESS_ONLY: destroy_addr [[X_LOCAL_ADDR]]
91+
// ADDRESS_ONLY: dealloc_stack [[X_LOCAL_ADDR]]
92+
93+
func test_subscript_read(snc: borrowing SNC) {
94+
use(snc[0].x)
95+
}
96+
97+
98+
struct SNC_OPT: ~Copyable {
99+
private var _data: NC? = NC()
100+
101+
subscript(index: Int) -> NC? {
102+
_read { yield _data }
103+
_modify { yield &_data }
104+
}
105+
}
106+
107+
// LOADABLE-LABEL: sil hidden [ossa] @${{.*}}test_subscript_write3sncyAA7SNC_OPTVz_tF
108+
109+
// For the snc[0].take(), ensure the end_apply happens after the call to take.
110+
// LOADABLE: begin_access [modify]
111+
// LOADABLE: begin_apply
112+
// LOADABLE: apply
113+
// LOADABLE: end_apply
114+
// LOADABLE: end_access
115+
116+
// LOADABLE: begin_access [modify]
117+
// LOADABLE: begin_apply
118+
// LOADABLE: assign
119+
// LOADABLE: end_apply
120+
// LOADABLE: end_access
121+
func test_subscript_write(snc: inout SNC_OPT) {
122+
let x = snc[0].take()
123+
snc[0] = x
124+
}

0 commit comments

Comments
 (0)