@@ -14,44 +14,50 @@ class MoveOnlyKlass {
1414 var value : Int = 0
1515}
1616
17- @_moveOnly
18- struct KlassPair {
17+ struct KlassPair : ~ Copyable {
1918 var lhs : Klass
2019 var rhs : MoveOnlyKlass
2120}
2221
23- @_moveOnly
24- struct AggStruct {
22+ struct AggStruct : ~ Copyable {
2523 var pair : KlassPair
2624}
2725
28- @_moveOnly
29- struct KlassPair2 {
26+ struct KlassPair2 : ~ Copyable {
3027 var lhs : MoveOnlyKlass
3128 var rhs : MoveOnlyKlass
3229}
3330
34- @_moveOnly
35- struct AggStruct2 {
31+ struct AggStruct2 : ~ Copyable {
3632 var lhs : MoveOnlyKlass
3733 var pair : KlassPair2
3834 var rhs : MoveOnlyKlass
3935}
4036
41- @_moveOnly
42- struct SingleIntContainingStruct {
37+ struct SingleIntContainingStruct : ~ Copyable {
4338 var value : Int = 0
4439}
4540
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 ) { }
4652func consume( _ x: consuming MoveOnlyKlass ) { }
53+ func consume( _ x: consuming MoveOnlyPair ) { }
4754func consume( _ x: consuming Klass ) { }
4855
4956////////////////////
50- // Test Top Level //
57+ // MARK: Loadable //
5158////////////////////
5259
53- @_moveOnly
54- struct DeinitStruct {
60+ struct DeinitStruct : ~ Copyable {
5561 var first : Klass
5662 var second : ( Klass , Klass )
5763 var third : KlassPair
@@ -98,12 +104,12 @@ func testConsumeNonCopyable4(_ x: consuming DeinitStruct) {
98104 consume ( x. fifth) // expected-note {{consuming use here}}
99105}
100106
101- /////////////////
102- // Test Fields //
103- /////////////////
104107
105- @_moveOnly
106- struct StructContainDeinitStruct {
108+ ///////////////////////////
109+ // MARK: Loadable Fields //
110+ ///////////////////////////
111+
112+ struct StructContainDeinitStruct : ~ Copyable {
107113 var first : DeinitStruct
108114 var second : ( DeinitStruct , DeinitStruct )
109115 var third : Klass
@@ -153,3 +159,85 @@ func testStructContainStructContainDeinitStructConsumeNonCopyable4(_ x: consumin
153159 // expected-error @-1 {{Cannot partially consume 'x' since it contains field 'x.first' whose type 'DeinitStruct' has a user defined deinit}}
154160 consume ( x. first. fifth) // expected-note {{consuming use here}}
155161}
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