@@ -384,11 +384,10 @@ protocol Derived: Base {
384
384
}
385
385
```
386
386
387
- ### Conformance to ` Copyable `
387
+ ### Conditional conformance to ` Copyable `
388
388
389
- Structs and enums conform to ` Copyable ` unconditionally by default, but a
390
- conditional conformance can also be defined. For example, take this
391
- noncopyable generic type:
389
+ Generic structs and enums can conditionally conform to ` Copyable ` .
390
+ For example, take this unconditionally noncopyable generic type:
392
391
``` swift
393
392
enum List <T : ~ Copyable >: ~ Copyable {
394
393
case empty
@@ -405,35 +404,93 @@ Note that no `where` clause needs to be written, because by the rules above,
405
404
the default conformances here will already range over all generic parameters
406
405
of the type.
407
406
408
- A conditional ` Copyable ` conformance is not permitted if the
409
- struct or enum declares a ` deinit ` . Deterministic destruction requires the
407
+ A conditional ` Copyable ` conformance cannot be declared if the
408
+ type has a ` deinit ` member . Deterministic destruction requires the
410
409
type to be unconditionally noncopyable.
411
410
412
- A conformance to ` Copyable ` is checked by verifying that every stored property
413
- (of a struct) or associated value (or an enum) itself conforms to ` Copyable ` .
414
- For a conditional ` Copyable ` conformance, the conditional requirements must be
415
- sufficient to ensure this is the case. For example, the following is rejected,
416
- because the struct cannot unconditionally conform to ` Copyable ` , having a
417
- stored property of the noncopyable type ` T ` :
411
+ Copyability is an inherent property of the type, unlike a general protocol
412
+ conformance, which is a logically distinct entity from the conforming type itself.
413
+ This imposes some restrictions on the form that a conditional ` Copyable `
414
+ conformance can take:
415
+ 1 . Conditional ` Copyable ` conformance must be declared in the same source
416
+ file as the conforming struct or enum declaration.
417
+ 2 . The conditional requirements must be of the form ` T: Copyable ` where ` T `
418
+ is a generic parameter of the conforming type. Other conditional
419
+ requirements are not permitted:
420
+ ``` swift
421
+ extension Pair : Copyable where T: Equatable {} // error
422
+ ```
423
+ In particular, general conformance requirements can be satisfied by
424
+ retroactive conformances, and it would break the semantic model if the
425
+ addition of a retroactive conformance to some other protocol could
426
+ influence the copyability of a type.
427
+ 3 . It is also not allowed for ` Copyable ` be conditional on the copyability of
428
+ an associated type:
429
+ ``` swift
430
+ protocol Manager { associatedtype Resource : ~ Copyable }
431
+ struct ManagerManager <T : Manager >: ~ Copyable {}
432
+ extension ManagerManager : Copyable where T.Resource: Copyable {} // error
433
+ ```
434
+ To check the conditional requirement ` T.Resource: Copyable ` , we would
435
+ need to resolve the ` Resource ` associated type from the conformance of ` T ` to ` Manager ` ,
436
+ which again could be retroactive.
437
+
438
+ As a consequence of existing language rules around synthesized conformances
439
+ together with the first restriction above, the default conformance on the type
440
+ declaration does not need to be suppressed. The below is an equivalent
441
+ declaration of the earlier ` List ` example, and the decision to write ` ~Copyable `
442
+ in the inheritance clause is a matter of style:
443
+
444
+ ``` swift
445
+ enum List <T : ~ Copyable > /* : ~Copyable */ {
446
+ case empty
447
+ indirect case element (T, List<T>)
448
+ }
449
+
450
+ extension List : Copyable /* where T: Copyable */ {}
451
+ ```
452
+
453
+ It is an error to declare an unconditional ` Copyable ` conformance with an extension.
454
+ This is always equivalent to _ not_ suppressing the default conformance,
455
+ and perhaps indicates a missing ` ~Copyable ` on the generic parameter ` T ` :
456
+
457
+ ``` swift
458
+ struct CopyableBox <T >: ~ Copyable {
459
+ let contents: T
460
+ }
461
+
462
+ extension CopyableBox : Copyable {} // pointless
463
+ ```
464
+ ### Checking the ` Copyable ` conformance
465
+
466
+ When a struct or enum conforms to ` Copyable ` , conditionally or unconditionally, we
467
+ check that every stored property (of a struct) or associated value (or an enum) is itself
468
+ ` Copyable ` , under the same assumptions as the type itself.
469
+
470
+ For example, the following is rejected; while the struct claims to unconditionally conform
471
+ to ` Copyable ` , it has a stored property of the noncopyable type ` T ` :
418
472
``` swift
419
473
struct Holder <T : ~ Copyable > /* : Copyable */ {
420
474
var value: T // error
421
475
}
422
476
```
423
477
424
- There are two situations when it is permissible for a copyable type to
425
- have a noncopyable generic parameter. The first is when the generic parameter
426
- is not stored inside the type itself :
478
+ On the other hand, a struct or enum with a noncopyable generic parameter may still conform
479
+ to ` Copyable ` unconditionally if its storage layout does not depend on this generic
480
+ parameter. For example :
427
481
``` swift
428
482
struct Factory <T : ~ Copyable > /* : Copyable */ {
429
483
let fn: () -> T // ok
430
484
}
431
485
```
432
- The above is permitted, because a _ function_ of type ` () -> T ` is still copyable,
433
- even if a _ value_ of type ` T ` is not copyable.
486
+ The above is permitted, because a _ function_ of type ` () -> T ` type is still
487
+ copyable, even if its result type ` T ` is noncopyable.
488
+
489
+ ### Classes
434
490
435
- The second case is when the type is a class. The contents of a class is never
436
- copied, so noncopyable types can appear in the stored properties of a class:
491
+ Class references are always ` Copyable ` , but the contents of a class instance
492
+ are never implicitly copied, so a class can have noncopyable stored properties
493
+ without restriction:
437
494
``` swift
438
495
class Box <T : ~ Copyable > {
439
496
let value: T // ok
@@ -442,31 +499,14 @@ class Box<T: ~Copyable> {
442
499
}
443
500
```
444
501
445
- For a conditional ` Copyable ` conformance, the conditional requirements must be
446
- of the form ` T: Copyable ` where ` T ` is a generic parameter of the type. It is
447
- not permitted to make ` Copyable ` conditional on any other kind of requirement:
448
- ``` swift
449
- extension Pair : Copyable where T == Array <Int > {} // error
450
- ```
451
- Nor can ` Copyable ` be conditional on the copyability of an associated type:
452
- ``` swift
453
- struct ManagerManager <T : Manager >: ~ Copyable {}
454
- extension ManagerManager : Copyable where T.Resource: Copyable {} // error
455
- ```
456
-
457
- Conditional ` Copyable ` conformance must be declared in the same source
458
- file as the struct or enum itself. Unlike conformance to other protocols,
459
- copyability is a deep, inherent property of the type itself.
460
-
461
- ### Classes
462
-
463
- This proposal supports classes with noncopyable generic parameters,
502
+ This proposal allows generic classes to declare noncopyable generic parameters,
464
503
but it does not permit classes to themselves be ` ~Copyable ` .
465
504
Similarly, an ` AnyObject ` or superclass requirement cannot be combined with
466
505
` ~Copyable ` :
467
506
``` swift
468
507
func f <T >(_ t : T) where T: AnyObject , T: ~Copyable { ... } // error
469
508
```
509
+ This is left as a future direction.
470
510
471
511
### Existential types
472
512
@@ -512,14 +552,20 @@ noncopyable structs and enums.
512
552
513
553
This proposal does not change the ABI of existing code.
514
554
515
- Adding ` ~Copyable ` to
516
- an existing generic parameter is generally an ABI-breaking change, even when
517
- source-compatible.
555
+ A key goal is that ABI-stable frameworks should be able to adopt ` ~Copyable ` in public APIs where it makes sense.
556
+ There are two scenarios to consider:
557
+
558
+ 1 . An older client, built before noncopyable types, is running with a newer version of the framework,
559
+ whose existing types have been generalized to allow for noncopyability.
560
+ 2 . A newer client, built against a newer framework ** and** making use of noncopyable types, is running
561
+ with an older version of the framework that predates noncopyable types.
562
+
563
+ A follow-up proposal for adoption of ` ~Copyable ` in the standard library will address both
564
+ scenarios:
518
565
519
- Targeted mechanisms are being developed to preserve ABI compatibility when
520
- adopting ` ~Copyable ` on previously-shipped generic code. This will enable adoption
521
- of this feature by standard library types such as ` Optional ` . Such mechanisms will
522
- require extreme care to use correctly.
566
+ 1 . The first will be handled by describing the overall rules under which ` ~Copyable ` can retrofitted safely,
567
+ together with a new attribute that will handle certain differences in mangling.
568
+ 2 . The second scenario is inherently more complex but it is rare except for the standard library itself.
523
569
524
570
## Alternatives Considered
525
571
0 commit comments