@@ -14,44 +14,50 @@ class MoveOnlyKlass {
14
14
var value : Int = 0
15
15
}
16
16
17
- @_moveOnly
18
- struct KlassPair {
17
+ struct KlassPair : ~ Copyable {
19
18
var lhs : Klass
20
19
var rhs : MoveOnlyKlass
21
20
}
22
21
23
- @_moveOnly
24
- struct AggStruct {
22
+ struct AggStruct : ~ Copyable {
25
23
var pair : KlassPair
26
24
}
27
25
28
- @_moveOnly
29
- struct KlassPair2 {
26
+ struct KlassPair2 : ~ Copyable {
30
27
var lhs : MoveOnlyKlass
31
28
var rhs : MoveOnlyKlass
32
29
}
33
30
34
- @_moveOnly
35
- struct AggStruct2 {
31
+ struct AggStruct2 : ~ Copyable {
36
32
var lhs : MoveOnlyKlass
37
33
var pair : KlassPair2
38
34
var rhs : MoveOnlyKlass
39
35
}
40
36
41
- @_moveOnly
42
- struct SingleIntContainingStruct {
37
+ struct SingleIntContainingStruct : ~ Copyable {
43
38
var value : Int = 0
44
39
}
45
40
41
+ struct MoveOnlyPair : ~ Copyable {
42
+ var first = SingleIntContainingStruct ( )
43
+ var second = SingleIntContainingStruct ( )
44
+ }
45
+
46
+ protocol P {
47
+ static var value : Self { get }
48
+ }
49
+
50
+ func consume< T : P > ( _ x: consuming T ) { }
51
+ func consume( _ x: consuming SingleIntContainingStruct ) { }
46
52
func consume( _ x: consuming MoveOnlyKlass ) { }
53
+ func consume( _ x: consuming MoveOnlyPair ) { }
47
54
func consume( _ x: consuming Klass ) { }
48
55
49
56
////////////////////
50
- // Test Top Level //
57
+ // MARK: Loadable //
51
58
////////////////////
52
59
53
- @_moveOnly
54
- struct DeinitStruct {
60
+ struct DeinitStruct : ~ Copyable {
55
61
var first : Klass
56
62
var second : ( Klass , Klass )
57
63
var third : KlassPair
@@ -98,12 +104,12 @@ func testConsumeNonCopyable4(_ x: consuming DeinitStruct) {
98
104
consume ( x. fifth) // expected-note {{consuming use here}}
99
105
}
100
106
101
- /////////////////
102
- // Test Fields //
103
- /////////////////
104
107
105
- @_moveOnly
106
- struct StructContainDeinitStruct {
108
+ ///////////////////////////
109
+ // MARK: Loadable Fields //
110
+ ///////////////////////////
111
+
112
+ struct StructContainDeinitStruct : ~ Copyable {
107
113
var first : DeinitStruct
108
114
var second : ( DeinitStruct , DeinitStruct )
109
115
var third : Klass
@@ -153,3 +159,85 @@ func testStructContainStructContainDeinitStructConsumeNonCopyable4(_ x: consumin
153
159
// expected-error @-1 {{Cannot partially consume 'x' since it contains field 'x.first' whose type 'DeinitStruct' has a user defined deinit}}
154
160
consume ( x. first. fifth) // expected-note {{consuming use here}}
155
161
}
162
+
163
+ ////////////////////////
164
+ // MARK: Address Only //
165
+ ////////////////////////
166
+
167
+ struct AddressOnlyDeinitStruct < T : P > : ~ Copyable {
168
+ var copyable : T = T . value
169
+ var moveOnly = SingleIntContainingStruct ( )
170
+ var moveOnlyPair = MoveOnlyPair ( )
171
+
172
+ deinit { }
173
+ // expected-note @-1 {{deinit declared here}}
174
+ // expected-note @-2 {{deinit declared here}}
175
+ // expected-note @-3 {{deinit declared here}}
176
+ // expected-note @-4 {{deinit declared here}}
177
+ // expected-note @-5 {{deinit declared here}}
178
+ }
179
+
180
+ func consume< T : P > ( _ x: consuming AddressOnlyDeinitStruct < T > ) { }
181
+
182
+ func testAddressOnlyCanConsumeEntireType< T : P > ( _ x: consuming AddressOnlyDeinitStruct < T > ) {
183
+ // This is ok since we are consuming a copyable value.
184
+ consume ( x. copyable)
185
+ // This is ok since we are consuming the entire value.
186
+ consume ( x)
187
+ }
188
+
189
+ func testAddressOnlyCannotPartialConsume< T : P > ( _ x: consuming AddressOnlyDeinitStruct < T > ) {
190
+ // expected-error @-1 {{Cannot partially consume 'x' since it has a user defined deinit}}
191
+ // expected-error @-2 {{Cannot partially consume 'x' since it has a user defined deinit}}
192
+ consume ( x. moveOnly) // expected-note {{consuming use here}}
193
+ consume ( x. moveOnlyPair. first) // expected-note {{consuming use here}}
194
+ consume ( x. copyable)
195
+ }
196
+
197
+ struct AddressOnlyContainingDeinitStruct < T : P > : ~ Copyable {
198
+ var a = AddressOnlyDeinitStruct < T > ( )
199
+ }
200
+
201
+ func testAddressOnlyCannotPartialConsumeEvenIfSingleElt< T : P > ( _ x: consuming AddressOnlyContainingDeinitStruct < T > ) {
202
+ // expected-error @-1 {{Cannot partially consume 'x' since it contains field 'x.a' whose type 'AddressOnlyDeinitStruct' has a user defined deinit}}
203
+
204
+ // We do not error here since we can partially consume x, but not x.a
205
+ consume ( x. a)
206
+ consume ( x. a. moveOnlyPair) // expected-note {{consuming use here}}
207
+ }
208
+
209
+ struct AddressOnlyContainingDeinitSingleField < T : P > : ~ Copyable {
210
+ var moveOnly = SingleIntContainingStruct ( )
211
+ deinit { }
212
+ // expected-note @-1 {{deinit declared here}}
213
+ }
214
+
215
+ struct AddressOnlyContainingDeinitStruct3 < T : P > : ~ Copyable {
216
+ var a = AddressOnlyContainingDeinitSingleField < T > ( )
217
+ }
218
+
219
+ func consume< T : P > ( _ x: consuming AddressOnlyContainingDeinitSingleField < T > ) { }
220
+
221
+ func testAddressOnlyCannotPartialConsumeEvenIfSingleElt< T : P > ( _ x: consuming AddressOnlyContainingDeinitStruct3 < T > ) {
222
+ // expected-error @-1 {{Cannot partially consume 'x' since it contains field 'x.a' whose type 'AddressOnlyContainingDeinitSingleField' has a user defined deinit}}
223
+
224
+ // We do not error here since we can partially consume x, but not x.a
225
+ consume ( x. a)
226
+ consume ( x. a. moveOnly) // expected-note {{consuming use here}}
227
+ }
228
+
229
+
230
+ struct AddressOnlyContainingDeinitStructPair < T : P > : ~ Copyable {
231
+ var first = AddressOnlyDeinitStruct < T > ( )
232
+ var second = AddressOnlyDeinitStruct < T > ( )
233
+ }
234
+
235
+ // Make sure that if the deinit is in an intermediate element of the path that
236
+ // we still handle it appropriately.
237
+ func testAddressOnlyDeinitInMiddlePath< T : P > ( _ x: consuming AddressOnlyContainingDeinitStructPair < T > ) {
238
+ // expected-error @-1 {{Cannot partially consume 'x' since it contains field 'x.first' whose type 'AddressOnlyDeinitStruct' has a user defined deinit}}
239
+ // expected-error @-2 {{Cannot partially consume 'x' since it contains field 'x.first' whose type 'AddressOnlyDeinitStruct' has a user defined deinit}}
240
+ consume ( x. first. moveOnly) // expected-note {{consuming use here}}
241
+ consume ( x. first. moveOnlyPair. first) // expected-note {{consuming use here}}
242
+ consume ( x. first. copyable)
243
+ }
0 commit comments