11// RUN: %target-swift-frontend %s -emit-sil -verify \
2- // RUN: -enable-experimental-feature ManualOwnership \
3- // RUN: -enable-copy-propagation=always
2+ // RUN: -enable-experimental-feature ManualOwnership
43
54// REQUIRES: swift_feature_ManualOwnership
65
@@ -34,6 +33,14 @@ public class Triangle {
3433 borrowing func borrowing( ) { }
3534}
3635
36+ // MARK: utilities
37+
38+ func eat( _ t: consuming Triangle ) { }
39+ func use( _ t: borrowing Triangle ) { }
40+
41+ func consume_generic< T> ( _ t: consuming T ) { }
42+ func borrow_generic< T> ( _ t: borrowing T ) { }
43+
3744/// MARK: return statements
3845
3946@_manualOwnership
@@ -44,7 +51,7 @@ public func basic_return1() -> Triangle {
4451
4552@_manualOwnership
4653public func basic_return2( t: Triangle ) -> Triangle {
47- return t // expected-error {{explicit 'copy' required here }}
54+ return t // expected-error {{ownership of 't' is demanded }}
4855}
4956@_manualOwnership
5057public func basic_return2_fixed( t: Triangle ) -> Triangle {
@@ -68,8 +75,9 @@ func reassign_with_lets() -> Triangle {
6875func renamed_return( _ cond: Bool , _ a: Triangle ) -> Triangle {
6976 let b = a
7077 let c = b
71- if cond { return b } // expected-error {{explicit 'copy' required here}}
72- return c // expected-error {{explicit 'copy' required here}}
78+ // FIXME: we say 'c' instead of 'b', because of the propagation.
79+ if cond { return b } // expected-error {{ownership of 'c' is demanded}}
80+ return c // expected-error {{ownership of 'c' is demanded}}
7381}
7482
7583@_manualOwnership
@@ -101,26 +109,27 @@ func basic_methods_borrowing(_ t1: Triangle) {
101109@_manualOwnership
102110func basic_methods_consuming( _ t1: Triangle ) {
103111 let t2 = Triangle ( )
104- t1. consuming ( ) // expected-error {{explicit 'copy' required here }}
112+ t1. consuming ( ) // expected-error {{ownership of 't1' is demanded }}
105113 t2. consuming ( )
106114}
107115@_manualOwnership
108116func basic_methods_consuming_fixed( _ t1: Triangle ) {
109117 let t2 = Triangle ( )
110- var t3 = Triangle ( )
111- t3 = Triangle ( )
112118
113119 ( copy t1 ) . consuming ( )
114120 ( copy t2 ) . consuming ( ) // FIXME: why is this not propagated?
115- ( copy t3 ) . consuming ( )
116121}
117122
118- func consumingFunc( _ t0: consuming Triangle ) { }
123+ @_manualOwnership
124+ @discardableResult
125+ func consumingFunc( _ t0: consuming Triangle ) -> Bool { return false }
126+
127+ @_manualOwnership
119128func plainFunc( _ t0: Triangle ) { }
120129
121130@_manualOwnership
122131func basic_function_call( _ t1: Triangle ) {
123- consumingFunc ( t1) // expected-error {{explicit 'copy' required here }}
132+ consumingFunc ( t1) // expected-error {{ownership of 't1' is demanded }}
124133 consumingFunc ( copy t1 )
125134 plainFunc ( t1)
126135}
@@ -146,7 +155,7 @@ func basic_function_call(_ t1: Triangle) {
146155@_manualOwnership
147156public func basic_loop_trivial_values( _ t: Triangle , _ xs: [ Triangle ] ) {
148157 var p : Pair = t. a
149- for x in xs { // expected-error {{explicit 'copy' required here }}
158+ for x in xs { // expected-error {{ownership of 'xs' is demanded }}
150159 p = p. midpoint ( x. a)
151160 }
152161 t. a = p
@@ -169,33 +178,125 @@ public func basic_loop_trivial_values_fixed(_ t: Triangle, _ xs: [Triangle]) {
169178
170179@_manualOwnership
171180public func basic_loop_nontrivial_values( _ t: Triangle , _ xs: [ Triangle ] ) {
172- var p : Pair = t. nontrivial. a // expected-error {{explicit 'copy' required here }}
173- for x in xs { // expected-error {{explicit 'copy' required here }}
174- p = p. midpoint ( x. nontrivial. a) // expected-error {{explicit 'copy' required here }}
181+ var p : Pair = t. nontrivial. a // expected-error {{accessing 't.nontrivial' produces a copy of it }}
182+ for x in xs { // expected-error {{ownership of 'xs' is demanded }}
183+ p = p. midpoint ( x. nontrivial. a) // expected-error {{accessing 'x.nontrivial' produces a copy of it }}
175184 }
176- t. nontrivial. a = p // expected-error {{explicit 'copy' required here }}
185+ t. nontrivial. a = p // expected-error {{accessing 't.nontrivial' produces a copy of it }}
177186}
178187
179188// FIXME: there should be no copies required in the below, other than what's already written.
180189@_manualOwnership
181190public func basic_loop_nontrivial_values_fixed( _ t: Triangle , _ xs: [ Triangle ] ) {
182- var p : Pair = ( copy t. nontrivial) . a // expected-error {{explicit 'copy' required here }}
191+ var p : Pair = ( copy t. nontrivial) . a // expected-error {{accessing 't.nontrivial' produces a copy of it }}
183192 for x in copy xs {
184- p = p. midpoint ( ( copy x. nontrivial) . a) // expected-error {{explicit 'copy' required here }}
193+ p = p. midpoint ( ( copy x. nontrivial) . a) // expected-error {{accessing 'x.nontrivial' produces a copy of it }}
185194 }
186- ( copy t. nontrivial) . a = p // expected-error {{explicit 'copy' required here }}
195+ ( copy t. nontrivial) . a = p // expected-error {{accessing 't.nontrivial' produces a copy of it }}
187196}
188197
189198
190199/// MARK: Globals
191200let ref_result = [ 5 , 13 , 29 ]
192201
202+ // FIXME: if we had a borrow operator, we could allow people to elide these simple copies that
203+ // are present to avoid exclusivity issues. We'd need to start generating read coroutines.
193204@_manualOwnership
194205func access_global_1( ) -> Int {
195- return ref_result [ 2 ] // expected-error {{explicit 'copy' required here }}
206+ return ref_result [ 2 ] // expected-error {{accessing 'ref_result' produces a copy of it }}
196207}
197208@_manualOwnership
198209func access_global_1_fixed( ) -> Int {
199210return ( copy ref_result) [ 2 ]
200211}
201212
213+ /// MARK: closures
214+
215+ // FIXME: (1) Closure capture lists need to support the short-hand [copy t] and produce explicit copies.
216+ // We also need a better error message for when this is missed for closure captures.
217+ // (2) Escaping closures need to be recursively checked by the PerformanceDiagnostics.
218+ // We might just need to widen the propagation of [manual_ownership]?
219+ // (3) Autoclosures have no ability to annotate captures. Is that OK?
220+
221+ @_manualOwnership
222+ func closure_basic( _ t: Triangle ) -> ( ) -> Triangle {
223+ return { return t } // expected-error {{ownership of 't' is demanded by a closure}}
224+ }
225+ @_manualOwnership
226+ func closure_basic_fixed( _ t: Triangle ) -> ( ) -> Triangle {
227+ return { [ t = copy t] in return t }
228+ }
229+
230+ @_manualOwnership
231+ func closure_copies_in_body( _ t: Triangle ) -> ( ) -> Triangle {
232+ return { [ t = copy t] in
233+ eat ( t) // FIXME: missing required copies
234+ eat ( t)
235+ return t }
236+ }
237+
238+ @_manualOwnership
239+ func closure_copies_in_body_noescape( _ t: Triangle ) -> Triangle {
240+ let f = { [ t = copy t] in
241+ eat ( t) // FIXME: missing required copies
242+ eat ( t)
243+ return t
244+ }
245+ return f ( )
246+ }
247+
248+ @_manualOwnership
249+ func simple_assert( _ f: @autoclosure ( ) -> Bool ) {
250+ guard f ( ) else { fatalError ( ) }
251+ }
252+ @_manualOwnership
253+ func try_to_assert( _ n: Int , _ names: [ String ] ) {
254+ simple_assert ( names. count == n)
255+ }
256+
257+ @_manualOwnership
258+ func copy_in_autoclosure( _ t: Triangle ) {
259+ simple_assert ( consumingFunc ( t) ) // FIXME: missing required copies
260+ }
261+
262+ /// MARK: generics
263+
264+ @_manualOwnership
265+ func return_generic< T> ( _ t: T ) -> T {
266+ return t // expected-error {{explicit 'copy' required here}}
267+ }
268+ @_manualOwnership
269+ func return_generic_fixed< T> ( _ t: T ) -> T {
270+ return copy t
271+ }
272+
273+ @_manualOwnership
274+ func reassign_with_lets< T> ( _ t: T ) -> T {
275+ let x = t // expected-error {{explicit 'copy' required here}}
276+ let y = x // expected-error {{explicit 'copy' required here}}
277+ let z = y // expected-error {{explicit 'copy' required here}}
278+ return copy z
279+ }
280+
281+ // FIXME: there's copy propagation has no effect on address-only types.
282+ @_manualOwnership
283+ func reassign_with_lets_fixed< T> ( _ t: T ) -> T {
284+ let x = copy t
285+ let y = copy x
286+ let z = copy y
287+ return copy z
288+ }
289+
290+ @_manualOwnership
291+ func copy_generic< T> ( _ t: T ) {
292+ consume_generic ( t) // expected-error {{explicit 'copy' required here}}
293+ borrow_generic ( t)
294+ consume_generic ( t) // expected-error {{explicit 'copy' required here}}
295+ }
296+
297+ @_manualOwnership
298+ func copy_generic_fixed< T> ( _ t: T ) {
299+ consume_generic ( copy t)
300+ borrow_generic ( t)
301+ consume_generic ( copy t)
302+ }
0 commit comments