Skip to content

Commit 8db7dc3

Browse files
committed
Add test: lifetime_dependence/coroutine.swift
1 parent 82afc7c commit 8db7dc3

File tree

1 file changed

+107
-0
lines changed

1 file changed

+107
-0
lines changed
Lines changed: 107 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,107 @@
1+
// RUN: %target-swift-frontend %s -emit-sil \
2+
// RUN: -enable-experimental-feature LifetimeDependence \
3+
// RUN: -enable-experimental-feature LifetimeDependenceDiagnoseTrivial \
4+
// RUN: | %FileCheck %s
5+
6+
// REQUIRES: swift_in_compiler
7+
// REQUIRES: swift_feature_LifetimeDependence
8+
// REQUIRES: swift_feature_LifetimeDependenceDiagnoseTrivial
9+
10+
struct View : ~Escapable {
11+
let ptr: UnsafeRawBufferPointer
12+
let c: Int
13+
@lifetime(borrow ptr)
14+
init(_ ptr: UnsafeRawBufferPointer, _ c: Int) {
15+
self.ptr = ptr
16+
self.c = c
17+
}
18+
init(_ otherBV: borrowing View) {
19+
self.ptr = otherBV.ptr
20+
self.c = otherBV.c
21+
}
22+
init(_ k: borrowing NCContainer) {
23+
self.ptr = k.ptr
24+
self.c = k.c
25+
}
26+
// This overload requires a separate label because overloading
27+
// on borrowing/consuming attributes is not allowed
28+
init(consumingView k: consuming View) {
29+
self.ptr = k.ptr
30+
self.c = k.c
31+
}
32+
}
33+
34+
struct Wrapper : ~Escapable {
35+
var _view: View
36+
37+
// Nested coroutine access.
38+
var view: View {
39+
_read {
40+
yield _view
41+
}
42+
_modify {
43+
yield &_view
44+
}
45+
}
46+
init(_ view: consuming View) {
47+
self._view = view
48+
}
49+
}
50+
51+
struct NCContainer : ~Copyable {
52+
let ptr: UnsafeRawBufferPointer
53+
let c: Int
54+
55+
init(_ ptr: UnsafeRawBufferPointer, _ c: Int) {
56+
self.ptr = ptr
57+
self.c = c
58+
}
59+
60+
// Nested coroutine access.
61+
var view: View {
62+
_read {
63+
yield View(self)
64+
}
65+
}
66+
67+
// Doubly nested coroutine access.
68+
var wrapper: Wrapper {
69+
_read {
70+
yield Wrapper(view)
71+
}
72+
}
73+
}
74+
75+
func use(_ o : borrowing View) {}
76+
77+
// Extend access scopes across chained coroutines.
78+
//
79+
// CHECK-LABEL: sil hidden @$s9coroutine20testDoubleNestedRead2ncyAA11NCContainerVn_tF : $@convention(thin) (@owned NCContainer) -> () {
80+
// CHECK: bb0(%0 : $NCContainer):
81+
// CHECK: [[NC:%.*]] = alloc_stack [lexical] [var_decl] $NCContainer, var, name "nc", type $NCContainer
82+
// CHECK: store %0 to [[NC]]
83+
// let wrapper = nc.wrapper
84+
// CHECK: [[ACCESS:%.*]] = begin_access [read] [static] [[NC]]
85+
// CHECK: [[NCVAL:%.*]] = load [[ACCESS]]
86+
// CHECK: ([[YIELD1:%.*]], [[TOKEN1:%.*]]) = begin_apply %{{.*}}([[NCVAL]]) : $@yield_once @convention(method) (@guaranteed NCContainer) -> @lifetime(borrow 0) @yields @guaranteed Wrapper
87+
// CHECK: [[WRAPPER:%.*]] = mark_dependence [nonescaping] [[YIELD1]] on [[TOKEN1]]
88+
// CHECK: retain_value [[WRAPPER]]
89+
// CHECK: debug_value [[WRAPPER]], let, name "wrapper"
90+
// let view = wrapper.view
91+
// CHECK: ([[VIEW:%.*]], [[TOKEN2:%.*]]) = begin_apply %{{.*}}([[WRAPPER]]) : $@yield_once @convention(method) (@guaranteed Wrapper) -> @lifetime(copy 0) @yields @guaranteed View
92+
// CHECK: retain_value [[VIEW]]
93+
// CHECK: end_apply [[TOKEN2]] as $()
94+
// CHECK: debug_value [[VIEW]], let, name "view"
95+
// use(view)
96+
// CHECK: apply %{{.*}}([[VIEW]]) : $@convention(thin) (@guaranteed View) -> ()
97+
// CHECK: release_value [[VIEW]]
98+
// CHECK: release_value [[WRAPPER]]
99+
// CHECK: %24 = end_apply [[TOKEN1]] as $()
100+
// CHECK: end_access [[ACCESS]]
101+
// CHECK: destroy_addr [[NC]]
102+
// CHECK-LABEL: } // end sil function '$s9coroutine20testDoubleNestedRead2ncyAA11NCContainerVn_tF'
103+
func testDoubleNestedRead(nc: consuming NCContainer) {
104+
let wrapper = nc.wrapper
105+
let view = wrapper.view
106+
use(view)
107+
}

0 commit comments

Comments
 (0)