File: inverse_generics.swift

package info (click to toggle)
swiftlang 6.0.3-2
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 2,519,992 kB
  • sloc: cpp: 9,107,863; ansic: 2,040,022; asm: 1,135,751; python: 296,500; objc: 82,456; f90: 60,502; lisp: 34,951; pascal: 19,946; sh: 18,133; perl: 7,482; ml: 4,937; javascript: 4,117; makefile: 3,840; awk: 3,535; xml: 914; fortran: 619; cs: 573; ruby: 573
file content (537 lines) | stat: -rw-r--r-- 24,153 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
// RUN: %target-typecheck-verify-swift \
// RUN: -enable-experimental-feature NonescapableTypes \
// RUN: -enable-experimental-feature SuppressedAssociatedTypes

// expected-note@+1 {{'T' has '~Copyable' constraint preventing implicit 'Copyable' conformance}}
struct AttemptImplicitConditionalConformance<T: ~Copyable>: ~Copyable {
  var t: T // expected-error {{stored property 't' of 'Copyable'-conforming generic struct 'AttemptImplicitConditionalConformance' has non-Copyable type 'T'}}
}
extension AttemptImplicitConditionalConformance: Copyable {}
// expected-error@-1 {{generic struct 'AttemptImplicitConditionalConformance' required to be 'Copyable' but is marked with '~Copyable'}}

enum Hello<T: ~Escapable & ~Copyable>: ~Escapable & ~Copyable {}
extension Hello: Escapable {} // expected-error {{generic enum 'Hello' required to be 'Escapable' but is marked with '~Escapable'}}
extension Hello: Copyable {} // expected-error {{generic enum 'Hello' required to be 'Copyable' but is marked with '~Copyable'}}

enum HelloExplicitlyFixed<T: ~Escapable & ~Copyable>: Escapable, Copyable {}

struct NoInverseBecauseNoDefault<T: ~Copyable & ~Escapable>: ~Copyable {}
extension NoInverseBecauseNoDefault: Copyable where T: Copyable, T: ~Escapable {}
// expected-error@-1 {{cannot suppress '~Escapable' on generic parameter 'T' defined in outer scope}}

// Check support for explicit conditional conformance
public struct ExplicitCond<T: ~Copyable>: ~Copyable {}
extension ExplicitCond: Copyable where T: Copyable {}
// expected-note@-1 {{requirement from conditional conformance}}
// expected-note@-2 {{requirement from conditional conformance of 'ExplicitCondAlias<NC>' (aka 'ExplicitCond<NC>') to 'Copyable'}}

public typealias ExplicitCondAlias<T> = ExplicitCond<T> where T: ~Copyable
public typealias AlwaysCopyable<T> = ExplicitCond<T>

func checkCopyable<T>(_ t: T) {} // expected-note {{'where T: Copyable' is implicit here}}

func test<C, NC: ~Copyable>(
  _ a1: ExplicitCond<C>, _ b1: borrowing ExplicitCond<NC>,
  _ a2: ExplicitCondAlias<C>, _ b2: borrowing ExplicitCondAlias<NC>
  ) {
  checkCopyable(a1)
  checkCopyable(b1) // expected-error {{global function 'checkCopyable' requires that 'NC' conform to 'Copyable'}}
  checkCopyable(a2)
  checkCopyable(b2) // expected-error {{global function 'checkCopyable' requires that 'NC' conform to 'Copyable'}}
}

func checkAliases<C, NC: ~Copyable>(_ a: AlwaysCopyable<C>, _ b: AlwaysCopyable<NC>) {
// expected-error@-1 {{'NC' required to be 'Copyable' but is marked with '~Copyable'}}
  checkCopyable(a)
  checkCopyable(b)
}

protocol NeedsCopyable {}
// expected-note@-1 {{type 'TryInferCopyable' does not conform to inherited protocol 'Copyable'}}

struct TryInferCopyable: ~Copyable, NeedsCopyable {}
// expected-error@-1 {{type 'TryInferCopyable' does not conform to protocol 'Copyable'}}

protocol Removed: ~Copyable {
  func requiresCopyableSelf(_ t: AlwaysCopyable<Self>)
  // expected-error@-1 {{type 'Self' does not conform to protocol 'Copyable'}}
}
protocol Plain<T> {
  associatedtype T: ~Copyable
  func requiresCopyableSelf(_ t: AlwaysCopyable<Self>)
  func requiresCopyableT(_ t: AlwaysCopyable<T>)
  // expected-error@-1 {{type 'Self.T' does not conform to protocol 'Copyable'}}
}

protocol RemovedAgain where Self: ~Copyable {
    func requiresCopyableSelf(_ t: AlwaysCopyable<Self>) // expected-error {{type 'Self' does not conform to protocol 'Copyable'}}
}

struct StructContainment<T: ~Copyable> : Copyable {
    var storage: Maybe<T>
    // expected-error@-1 {{stored property 'storage' of 'Copyable'-conforming generic struct 'StructContainment' has non-Copyable type 'Maybe<T>'}}
}

enum EnumContainment<T: ~Copyable> : Copyable {
    // expected-note@-1 {{'T' has '~Copyable' constraint preventing implicit 'Copyable' conformance}}

    case some(T) // expected-error {{associated value 'some' of 'Copyable'-conforming generic enum 'EnumContainment' has non-Copyable type 'T'}}
    case other(Int)
    case none
}

class ClassContainment<T: ~Copyable> {
    var storage: T
    init(_ t: consuming T) {
        storage = t
        checkCopyable(t) // expected-error {{global function 'checkCopyable' requires that 'T' conform to 'Copyable'}}
    }

    deinit {}
}

struct ConditionalContainment<T: ~Copyable>: ~Copyable {
  var x: T
  var y: NC // expected-error {{stored property 'y' of 'Copyable'-conforming generic struct 'ConditionalContainment' has non-Copyable type 'NC'}}
}

extension ConditionalContainment: Copyable where T: Copyable {}

func chk(_ T: RequireCopyable<ConditionalContainment<Int>>) {}

func chk(_ t: ConditionalContainment<NC>) {}
// expected-error@-1 {{parameter of noncopyable type 'ConditionalContainment<NC>' must specify ownership}}
// expected-note@-2 3{{add}}

/// ----------------

// expected-note@+2 3{{add}}
// expected-error@+1 {{parameter of noncopyable type 'some Escapable & ~Copyable' must specify ownership}}
func dogDays(_ t: some Escapable & ~Copyable) {}

/// ----------------

struct AlwaysCopyableDeinit<T: ~Copyable> : Copyable {
  let nc: NC // expected-error {{stored property 'nc' of 'Copyable'-conforming generic struct 'AlwaysCopyableDeinit' has non-Copyable type 'NC'}}
  deinit {} // expected-error {{deinitializer cannot be declared in generic struct 'AlwaysCopyableDeinit' that conforms to 'Copyable'}}
}

struct SometimesCopyableDeinit<T: ~Copyable> : ~Copyable {
  deinit {} // expected-error {{deinitializer cannot be declared in generic struct 'SometimesCopyableDeinit' that conforms to 'Copyable'}}
}
extension SometimesCopyableDeinit: Copyable where T: Copyable {}

struct NeverCopyableDeinit<T: ~Copyable>: ~Copyable {
  deinit {}
}

protocol Test: ~Copyable {
  init?()
}

struct NoncopyableAndSendable: ~Copyable, Sendable {}

/// ---------------

// expected-note@+1 {{generic enum 'Maybe' has '~Copyable' constraint preventing 'Copyable' conformance}}
enum Maybe<Wrapped: ~Copyable>: ~Copyable {
  case just(Wrapped)
  case none

  deinit {} // expected-error {{deinitializer cannot be declared in generic enum 'Maybe' that conforms to 'Copyable'}}
}

extension Maybe: Copyable where Wrapped: Copyable {}

// expected-note@+4{{requirement specified as 'NC' : 'Copyable'}}
// expected-note@+3{{requirement from conditional conformance of 'Maybe<NC>' to 'Copyable'}}
// expected-note@+2{{requirement specified as 'Wrapped' : 'Copyable'}}
// expected-note@+1{{requirement from conditional conformance of 'Maybe<Wrapped>' to 'Copyable'}}
struct RequireCopyable<T> {
  // expected-note@-1 {{consider adding '~Copyable' to generic struct 'RequireCopyable'}}{{27-27=: ~Copyable}}
  deinit {} // expected-error {{deinitializer cannot be declared in generic struct 'RequireCopyable' that conforms to 'Copyable'}}
}

struct NC: ~Copyable {
// expected-note@-1 3{{struct 'NC' has '~Copyable' constraint preventing 'Copyable' conformance}}
  deinit {}
}

typealias ok1 = RequireCopyable<Int>
typealias ok2 = RequireCopyable<Maybe<Int>>

typealias err1 = RequireCopyable<Maybe<NC>>
// expected-error@-1{{type 'NC' does not conform to protocol 'Copyable'}}
// expected-error@-2{{'RequireCopyable' requires that 'NC' conform to 'Copyable'}}

typealias err2 = RequireCopyable<NC>
// expected-error@-1{{type 'NC' does not conform to protocol 'Copyable'}}

extension Maybe where Wrapped: ~Copyable {
  func check1(_ t: RequireCopyable<Self>) {}
  // expected-error@-1 {{type 'Wrapped' does not conform to protocol 'Copyable'}}
  // expected-error@-2 {{'RequireCopyable' requires that 'Wrapped' conform to 'Copyable'}}
}

extension Maybe {
  func check2(_ t: RequireCopyable<Self>) {}
}

/// MARK: tests that we diagnose ~Copyable that became invalid because it's required to be copyable

struct Silly: ~Copyable, Copyable {} // expected-error {{struct 'Silly' required to be 'Copyable' but is marked with '~Copyable'}}
enum Sally: Copyable, ~Copyable, NeedsCopyable {} // expected-error {{enum 'Sally' required to be 'Copyable' but is marked with '~Copyable'}}

class NiceTry: ~Copyable, Copyable {} // expected-error {{classes cannot be '~Copyable'}}

@_moveOnly class NiceTry2: Copyable {} // expected-error {{'@_moveOnly' attribute is only valid on structs or enums}}


struct Extendo: ~Copyable {}
extension Extendo: Copyable, ~Copyable {} // expected-error {{cannot suppress 'Copyable' in extension}}
// expected-error@-1 {{struct 'Extendo' required to be 'Copyable' but is marked with '~Copyable'}}

enum EnumExtendo {}
extension EnumExtendo: ~Copyable {} // expected-error {{cannot suppress 'Copyable' in extension}}

extension NeedsCopyable where Self: ~Copyable {}
// expected-error@-1 {{'Self' required to be 'Copyable' but is marked with '~Copyable'}}

protocol NoCopyP: ~Copyable {}

func needsCopyable<T>(_ t: T) {} // expected-note 2{{'where T: Copyable' is implicit here}}
func noCopyable(_ t: borrowing some ~Copyable) {}
func noCopyableAndP(_ t: borrowing some NoCopyP & ~Copyable) {}

func openingExistentials(_ a: borrowing any NoCopyP & ~Copyable,
                         _ b: any NoCopyP,
                         _ nc: borrowing any ~Copyable) {
  needsCopyable(a) // expected-error {{global function 'needsCopyable' requires that 'T' conform to 'Copyable'}}
  noCopyable(a)
  noCopyableAndP(a)

  needsCopyable(b)
  noCopyable(b)
  noCopyableAndP(b)

  needsCopyable(nc) // expected-error {{global function 'needsCopyable' requires that 'T' conform to 'Copyable'}}
  noCopyable(nc)
  noCopyableAndP(nc) // expected-error {{global function 'noCopyableAndP' requires that 'some NoCopyP & ~Copyable' conform to 'NoCopyP'}}
}

func project<CurValue>(_ base: CurValue) { }
func testSpecial(_ a: Any) {
  _openExistential(a, do: project)
}

/// MARK: non-Escapable types

func requireEscape<T: ~Copyable>(_ t: borrowing T) {} // expected-note {{generic parameters are always considered '@escaping'}}
// expected-note@-1 4{{'where T: Escapable' is implicit here}}

func genericNoEscape<T: ~Escapable>(_ t: borrowing T) {} // expected-note {{generic parameters are always considered '@escaping'}}
// expected-note@-1 2{{'where T: Copyable' is implicit here}}

func genericNoEscapeOrCopy<T: ~Escapable & ~Copyable>(_ t: borrowing T) {}

func checkFunctions(_ f: @autoclosure () -> Int) {
  requireEscape(f) // expected-error {{converting non-escaping parameter 'f' to generic parameter 'T' may allow it to escape}}

  // FIXME: rdar://119410346 (nonescaping function is not permitted as arg to ~Escapable generic function)
  genericNoEscape(f) // expected-error {{converting non-escaping parameter 'f' to generic parameter 'T' may allow it to escape}}
}

struct BuggerView<T: ~Copyable>: ~Escapable, Copyable {}

struct MutableBuggerView<T: ~Copyable>: ~Copyable, ~Escapable {}

func checkNominals(_ mutRef: inout MutableBuggerView<NC>,
                   _ ref: BuggerView<NC>,
                   _ intMutRef: borrowing MutableBuggerView<Int>,
                   _ intRef: BuggerView<Int>) {

  genericNoEscape(mutRef) // expected-error {{global function 'genericNoEscape' requires that 'MutableBuggerView<NC>' conform to 'Copyable'}}
  genericNoEscape(ref)
  genericNoEscape(intMutRef) // expected-error {{global function 'genericNoEscape' requires that 'MutableBuggerView<Int>' conform to 'Copyable'}}
  genericNoEscape(intRef)

  genericNoEscapeOrCopy(mutRef)
  genericNoEscapeOrCopy(ref)
  genericNoEscapeOrCopy(intMutRef)
  genericNoEscapeOrCopy(intRef)

  requireEscape(mutRef) // expected-error {{global function 'requireEscape' requires that 'MutableBuggerView<NC>' conform to 'Escapable'}}
  requireEscape(ref) // expected-error {{global function 'requireEscape' requires that 'BuggerView<NC>' conform to 'Escapable'}}
  requireEscape(intMutRef) // expected-error {{global function 'requireEscape' requires that 'MutableBuggerView<Int>' conform to 'Escapable'}}
  requireEscape(intRef) // expected-error {{global function 'requireEscape' requires that 'BuggerView<Int>' conform to 'Escapable'}}
}

struct NonescapingType: ~Escapable {}

struct NonescapeDoesNotAllowNoncopyable: ~Escapable { // expected-note {{consider adding '~Copyable' to struct 'NonescapeDoesNotAllowNoncopyable'}}
  let x: NC // expected-error {{stored property 'x' of 'Copyable'-conforming struct 'NonescapeDoesNotAllowNoncopyable' has non-Copyable type 'NC'}}
  init(_ x: borrowing NC) {
    self.x = x
  }
}

enum MaybeEscapes<T: ~Escapable>: ~Escapable { // expected-note {{generic enum 'MaybeEscapes' has '~Escapable' constraint preventing 'Escapable' conformance}}
  case just(T)
  case none
}

extension MaybeEscapes: Escapable where T: Escapable {}

struct Escapes { // expected-note {{consider adding '~Escapable' to struct 'Escapes'}}
  let t: MaybeEscapes<NonescapingType> // expected-error {{stored property 't' of 'Escapable'-conforming struct 'Escapes' has non-Escapable type 'MaybeEscapes<NonescapingType>'}}
}

enum Boring {
  case thing(MaybeEscapes<Int>)
}

struct NonEscapingHasNoDeinit: ~Escapable { // expected-note {{consider adding '~Copyable' to struct 'NonEscapingHasNoDeinit'}}
  deinit {} // expected-error {{deinitializer cannot be declared in struct 'NonEscapingHasNoDeinit' that conforms to 'Copyable'}}
}

/// MARK: requirement conflict tests

func conflict1<T>(_ t: T) where T: NeedsCopyable, T: ~Copyable {}
// expected-error@-1 {{'T' required to be 'Copyable' but is marked with '~Copyable'}}

func conflict2<T: ~Copyable>(_ t: AlwaysCopyable<T>) {}
// expected-error@-1 {{'T' required to be 'Copyable' but is marked with '~Copyable'}}

func conflict3a<T: NeedsCopyable & ~Copyable>(_ t: T) {}
// expected-error@-1 {{composition cannot contain '~Copyable' when another member requires 'Copyable'}}

func conflict3b<T>(_ t: T) where T: NeedsCopyable, T: ~Copyable {}
// expected-error@-1 {{'T' required to be 'Copyable' but is marked with '~Copyable'}}

func conflict4a(_ t: some NeedsCopyable & ~Copyable) {}
// expected-error@-1 {{composition cannot contain '~Copyable' when another member requires 'Copyable'}}

protocol Conflict5: ~Copyable {
  borrowing func whatever() -> AlwaysCopyable<Self> // expected-error {{type 'Self' does not conform to protocol 'Copyable'}}
}

// expected-warning@+1 {{same-type requirement makes generic parameters 'U' and 'T' equivalent}}
func conflict6<T: ~Copyable, U>(_ t: T, _ u: U) // expected-error {{'T' required to be 'Copyable' but is marked with '~Copyable'}}
 where U : NeedsCopyable, T == U {}

protocol Conflict7 {
  associatedtype Element
}

func conflict7<T, U>(_ t: T, _ u: U)
  where
    U: ~Copyable,  // expected-error {{'U' required to be 'Copyable' but is marked with '~Copyable'}}
    T: Conflict7,
    U == T.Element
  {}

protocol Conflict8: ~Copyable, NeedsCopyable {}
// expected-error@-1 {{'Self' required to be 'Copyable' but is marked with '~Copyable'}}

struct Conflict9<T: NeedsCopyable> {}
func conflict9<U: ~Copyable>(_ u: Conflict9<U>) {}
// expected-error@-1 {{'U' required to be 'Copyable' but is marked with '~Copyable'}}

func conflict10<T>(_ t: T, _ u: some ~Copyable & Copyable)
// expected-error@-1 {{composition cannot contain '~Copyable' when another member requires 'Copyable'}}
  where T: Copyable,
        T: ~Copyable {}
// expected-error@-1 {{'T' required to be 'Copyable' but is marked with '~Copyable'}}

protocol Conflict11: ~Copyable, Copyable {}
// expected-error@-1 {{'Self' required to be 'Copyable' but is marked with '~Copyable'}}

struct Conflict12: ~Copyable, Copyable {}
// expected-error@-1 {{struct 'Conflict12' required to be 'Copyable' but is marked with '~Copyable'}}

// FIXME: this is bogus (rdar://119346022)
protocol Conflict13 {
  associatedtype A
  associatedtype B: ~Copyable
}
func conflict13<T>(_ t: T)
  where T: Conflict13,
        T.A == T.B
        {}

// expected-warning@+1 {{same-type requirement makes generic parameters 'U' and 'T' equivalent}}
func conflict14<T, U>(_ t: T, _ u: U)
  where T: ~Copyable, // expected-error {{'T' required to be 'Copyable' but is marked with '~Copyable'}}
        U: ~Escapable, // expected-error {{'U' required to be 'Escapable' but is marked with '~Escapable'}}
        T == U {}

protocol Conflict15 {
  associatedtype HasE: ~Copyable
  associatedtype HasC: ~Escapable
}
func conflict15<T, C, E>(_ t: T, _ c: C, _ e: borrowing E)
  where
    T: Conflict15,
    E: ~Copyable,  // expected-error {{'E' required to be 'Copyable' but is marked with '~Copyable'}}
    E == T.HasC,
    C: ~Escapable,  // expected-error {{'C' required to be 'Escapable' but is marked with '~Escapable'}}
    C == T.HasE
  {}


// Class bounds and AnyObject

class Soup {}
func checkClassBound1<T>(_ t: T) where T: ~Copyable, T: Soup {}
// expected-error@-1 {{'T' required to be 'Copyable' but is marked with '~Copyable'}}

// expected-note@+2 3{{add}}
// expected-error@+1 {{parameter of noncopyable type 'T' must specify ownership}}
func checkClassBound2<T>(_ t: T) where T: ~Escapable, T: AnyObject, T: ~Copyable {}
// expected-error@-1 {{'T' required to be 'Escapable' but is marked with '~Escapable'}}
// expected-error@-2 {{'T' required to be 'Copyable' but is marked with '~Copyable'}}

func checkClassBound3<T>(_ t: T) where T: Soup & ~Copyable & ~Escapable {}
// expected-error@-1 {{composition involving class requirement 'Soup' cannot contain '~Copyable'}}

func checkClassBound4<T>(_ t: T) where T: Soup, T: ~Copyable & ~Escapable {}
// expected-error@-1 {{'T' required to be 'Copyable' but is marked with '~Copyable'}}
// expected-error@-2 {{'T' required to be 'Escapable' but is marked with '~Escapable'}}

public func checkAnyObjInv1<Result: AnyObject>(_ t: borrowing Result) where Result: ~Copyable {}
// expected-error@-1 {{'Result' required to be 'Copyable' but is marked with '~Copyable'}}

public func checkAnyObjInv2<Result: AnyObject>(_ t: borrowing Result) where Result: ~Escapable {}
// expected-error@-1 {{'Result' required to be 'Escapable' but is marked with '~Escapable'}}

public func checkAnyObject<Result>(_ t: Result) where Result: AnyObject {
    checkCopyable(t)
}

func checkExistentialAndClasses(
    _ a: any AnyObject & ~Copyable, // expected-error {{composition involving 'AnyObject' cannot contain '~Copyable'}}
    _ b: any Soup & Copyable & ~Escapable & ~Copyable,
    // expected-error@-1 {{composition involving class requirement 'Soup' cannot contain '~Copyable'}}
    _ c: some (~Escapable & Removed) & Soup // expected-error {{composition cannot contain '~Escapable' when another member requires 'Escapable'}}
    ) {}

protocol HasNCBuddy: ~Copyable {
  associatedtype NCBuddy: HasNCBuddy, ~Copyable

  associatedtype Buddy: HasMember
}

protocol HasMember : HasNCBuddy {
  associatedtype Member: HasMember

  associatedtype NCMember: ~Copyable
}

func checkOwnership<T: HasMember>(_ t: T,
                                  _ l: T.NCBuddy.Buddy.Member.Buddy,
                                  _ m: T.Member.Member,
                                  _ n: T.Member.NCMember,
// expected-error@-1 {{parameter of noncopyable type 'T.Member.NCMember' must specify ownership}} // expected-note@-1 3{{add}}

                                  _ o: T.Member.NCBuddy.NCBuddy
// expected-error@-1 {{parameter of noncopyable type 'T.Member.NCBuddy.NCBuddy' must specify ownership}} // expected-note@-1 3{{add}}
) {}

// Covers an issue when building Combine from its interface.
public struct Record<Output> {
  public init(recording: Record<Output>) {}
}
protocol P {}
extension Record : Decodable where Output : P {}

struct Blahaj<Value>: ~Copyable {
  deinit {} // this is OK
}
extension Blahaj: Q where Value: Q {}
// expected-error@-1 {{type 'Blahaj<Value>' does not conform to protocol 'Copyable'}}
protocol Q: Copyable {}
// expected-note@-1 {{type 'Blahaj<Value>' does not conform to inherited protocol 'Copyable'}}

// expected-note@+2 3{{add}}
// expected-error@+1 {{parameter of noncopyable type 'Blahaj<T>' must specify ownership}}
func testBlahaj<T, U: Q>(_ x: Blahaj<T>,
// expected-note@+2 3{{add}}
// expected-error@+1 {{parameter of noncopyable type 'Blahaj<U>' must specify ownership}}
                         _ y: Blahaj<U>) {}

extension Int: NeedsCopyable {}

func checkExistentials() {
    let _: any ~Escapable & (NeedsCopyable & ~Copyable) // expected-error {{composition cannot contain '~Copyable' when another member requires 'Copyable'}}
    let _: any NeedsCopyable & ~Copyable = 1 // expected-error {{composition cannot contain '~Copyable' when another member requires 'Copyable'}}
    let _: any NeedsCopyable & ~Escapable = 1 // expected-error {{composition cannot contain '~Escapable' when another member requires 'Escapable'}}
    let _: any Copyable & ~Copyable = 1 // expected-error {{composition cannot contain '~Copyable' when another member requires 'Copyable'}}
    let _: any Escapable & ~Escapable = 1 // expected-error {{composition cannot contain '~Escapable' when another member requires 'Escapable'}}
}

typealias NotCopyable = ~Copyable
typealias EmptyComposition = ~Copyable & ~Escapable
func test(_ t: borrowing NotCopyable) {} // expected-error {{use of 'NotCopyable' (aka '~Copyable') as a type must be written 'any NotCopyable'}}
func test(_ t: borrowing EmptyComposition) {} // expected-error {{use of 'EmptyComposition' (aka '~Copyable & ~Escapable') as a type must be written 'any EmptyComposition' (aka 'any ~Copyable & ~Escapable')}}

typealias Copy = Copyable
func test(_ z1: Copy, _ z2: Copyable) {}

// Conformances can be conditional on whether a generic parameter is Copyable
protocol Arbitrary {}
protocol AnotherOne {}
struct UnethicalPointer<Pointee: ~Copyable> {}
extension UnethicalPointer: Arbitrary {}
extension UnethicalPointer: AnotherOne where Pointee: Copyable {}

struct AlsoLegal1<Pointee: ~Escapable> {}
extension AlsoLegal1: Arbitrary {}
extension AlsoLegal1: AnotherOne where Pointee: Escapable {}

struct SillIllegal2<Pointee> {}
extension SillIllegal2: Arbitrary where Pointee: Sendable {}
// expected-error@-1 {{conditional conformance to non-marker protocol 'Arbitrary' cannot depend on conformance of 'Pointee' to marker protocol 'Sendable'}}

struct SSS: ~Copyable, PPP {}
protocol PPP: ~Copyable {}
let global__old__: any PPP = SSS() // expected-error {{value of type 'SSS' does not conform to specified type 'Copyable'}}
let global__new__: any PPP & ~Copyable = SSS()

struct Example<T> {}

struct TestResolution1 { // expected-note {{consider adding '~Copyable' to struct 'TestResolution1'}}
  var maybeNC: NC? = nil // expected-error {{stored property 'maybeNC' of 'Copyable'-conforming struct 'TestResolution1' has non-Copyable type 'NC?'}}
}

struct TestResolution2 { // expected-note {{consider adding '~Copyable' to struct 'TestResolution2'}}
  var maybeIOUNC: NC! = nil // expected-error {{stored property 'maybeIOUNC' of 'Copyable'-conforming struct 'TestResolution2' has non-Copyable type 'NC?'}}
}

struct TestResolution3 {
  var arrayNC: [NC] = [] // expected-error {{type 'NC' does not conform to protocol 'Copyable'}}
  var dictNC: [String: NC] = [:] // expected-error {{type 'NC' does not conform to protocol 'Copyable'}}
  var exampleNC: Example<NC> = Example() // expected-error {{type 'NC' does not conform to protocol 'Copyable'}}
}

public struct Box<Wrapped: ~Copyable>: ~Copyable {}
// Box is never copyable, so we can't support this conditional conformance.
public enum List<Element: ~Copyable>: ~Copyable {
  case cons(Element, Box<List<Element>>)   // expected-error {{associated value 'cons' of 'Copyable'-conforming generic enum 'List' has non-Copyable type '(Element, Box<List<Element>>)'}}
  case empty
}
extension List: Copyable where Element: Copyable {}


struct Yapping<T: ~Copyable> {}
extension Yapping { // expected-note {{'where T: Copyable' is implicit here}}
  func yap() {}
}
func testYap(_ y: Yapping<NC>) {
  y.yap() // expected-error {{referencing instance method 'yap()' on 'Yapping' requires that 'NC' conform to 'Copyable'}}
}

protocol Veggie: ~Copyable {}
func generalized(_ x: Any.Type) {}
func testMetatypes(_ t: (any Veggie & ~Copyable).Type) {
  generalized(t) // expected-error {{cannot convert value of type '(any Veggie & ~Copyable).Type' to expected argument type 'any Any.Type'}}
}