@@ -467,8 +467,93 @@ An ``extension`` mangling is used whenever an entity's declaration context is
467
467
an extension *and * the entity being extended is in a different module. In this
468
468
case the extension's module is mangled first, followed by the entity being
469
469
extended. If the extension and the extended entity are in the same module, the
470
- plain ``entity `` mangling is preferred. If the extension is constrained, the
471
- constraints on the extension are mangled in its generic signature.
470
+ plain ``entity `` mangling is preferred, but not always used. An extension is
471
+ considered "constrained" if it:
472
+
473
+ - Has any requirements not already satisfied by the extended nominal,
474
+ excluding conformance requirements for invertible protocols.
475
+ - Has any generic parameters with an inverse requirement.
476
+
477
+ Those requirements included in any of the above are included in the extension's
478
+ generic signature. The reason for this additional complexity is that we do not
479
+ mangle conformance req's for invertible protocols, only their absence.
480
+
481
+ ::
482
+
483
+ struct S<A: ~Copyable, B: ~Copyable> {}
484
+
485
+ // An unconstrained extension.
486
+ extension S {}
487
+
488
+ // Also an unconstrained extension, because there are no inverses to mangle.
489
+ // This extension is exactly the same as the previous.
490
+ extension S where A: Copyable, B: Copyable {}
491
+
492
+ // A constrained extension, because of the added requirement `B: P` that is
493
+ // not already present in S.
494
+ extension S where B: P {}
495
+
496
+ // A constrained extension, because of the absence of `A: Copyable`.
497
+ // Despite also being absent in `S`, absences of invertible protocols
498
+ // are always mangled.
499
+ extension S where A: ~Copyable {}
500
+
501
+ As a consequence of the fact that some entities, like computed properties, rely
502
+
503
+ FIXME
504
+
505
+
506
+ these rules for extensions, if the outermost type
507
+ declaration (or extension) in the context has any inverses, then extension
508
+ mangling is used. This strategy is used to ensure that moving a declaration
509
+ between a nominal type and one of its extensions does not cause an ABI break if
510
+ the generic signature of the entity is equivalent in both circumstances.
511
+ For example:
512
+
513
+ ::
514
+
515
+ struct R<A: ~Copyable> {
516
+ func f1() {} // uses extension mangling, just like `f3`
517
+
518
+ func f2() where A: Copyable {}
519
+ }
520
+
521
+ extension R where A: ~Copyable {
522
+ func f3() {}
523
+
524
+ func f4() where A: Copyable {} // uses entity mangling, just like `f2`
525
+ }
526
+
527
+ extension R where A: Copyable {
528
+ // 'f5' is mangled equivalent to 'f2' and 'f4' modulo its identifier.
529
+ func f5() {}
530
+ }
531
+
532
+ For intermediate nested types, i.e., those between the top level and the entity,
533
+ any inverses that remain in at the signature of the entity are mangled into
534
+ that entity's generic signature:
535
+
536
+ ::
537
+
538
+ struct X<A: ~Copyable> {
539
+ struct Y<B: ~Copyable> {
540
+ // 'g1' uses 'entity' context mangling with and has no mangled signatures.
541
+ func g1() where A: Copyable, B: Copyable {}
542
+
543
+ // 'g2' uses 'entity' context mangling. The requirement `B: ~Copyable` is
544
+ //mangled into the generic signature for 'g2'.
545
+ func g2() where A: Copyable {}
546
+
547
+ // 'g3' uses extension mangling with generic signature 'A: ~Copyable'.
548
+ // The mangled generic signature of 'g3' is empty.
549
+ func g3() where B: Copyable {}
550
+
551
+ // 'g4' uses extension mangling with generic signature 'A: ~Copyable'.
552
+ // The mangled generic signature of 'g4' contains 'B: ~Copyable'.
553
+ func g4() {}
554
+ }
555
+ }
556
+
472
557
473
558
When mangling the context of a local entity within a constructor or
474
559
destructor, the non-allocating or non-deallocating variant is used.
@@ -680,12 +765,14 @@ Types
680
765
METATYPE-REPR ::= 'T' // Thick metatype representation
681
766
METATYPE-REPR ::= 'o' // ObjC metatype representation
682
767
768
+ existential-layout ::= protocol-list 'p' // existential layout
769
+ existential-layout ::= protocol-list superclass 'Xc' // existential layout with superclass
770
+ existential-layout ::= protocol-list 'Xl' // existential layout with AnyObject
771
+
683
772
type ::= associated-type
684
773
type ::= any-generic-type
685
- type ::= protocol-list 'p' // existential type
686
- type ::= protocol-list superclass 'Xc' // existential type with superclass
687
- type ::= protocol-list 'Xl' // existential type with AnyObject
688
- type ::= protocol-list requirement* '_' 'XP' // constrained existential type
774
+ type ::= existential-layout // existential type
775
+ type ::= existential-layout requirement '_' requirement* 'XP' // constrained existential type
689
776
type ::= type-list 't' // tuple
690
777
type ::= type generic-signature 'u' // generic type
691
778
type ::= 'x' // generic param, depth=0, idx=0
@@ -925,13 +1012,19 @@ now codified into the ABI; the index 0 is therefore reserved.
925
1012
926
1013
generic-param-pack-marker ::= 'Rv' GENERIC_PARAM-INDEX // generic parameter pack marker
927
1014
1015
+ INVERTIBLE-KIND ::= 'c' // Copyable
1016
+ INVERTIBLE-KIND ::= 'e' // Escapable
1017
+
928
1018
GENERIC-PARAM-COUNT ::= 'z' // zero parameters
929
1019
GENERIC-PARAM-COUNT ::= INDEX // N+1 parameters
930
1020
931
1021
requirement ::= protocol 'R' GENERIC-PARAM-INDEX // protocol requirement
932
1022
requirement ::= protocol assoc-type-name 'Rp' GENERIC-PARAM-INDEX // protocol requirement on associated type
933
1023
requirement ::= protocol assoc-type-list 'RP' GENERIC-PARAM-INDEX // protocol requirement on associated type at depth
934
1024
requirement ::= protocol substitution 'RQ' // protocol requirement with substitution
1025
+ #if SWIFT_RUNTIME_VERSION >= 6.0
1026
+ requirement ::= 'Ri' INVERTIBLE-KIND GENERIC-PARAM-INDEX // inverse requirement
1027
+ #endif
935
1028
requirement ::= type 'Rb' GENERIC-PARAM-INDEX // base class requirement
936
1029
requirement ::= type assoc-type-name 'Rc' GENERIC-PARAM-INDEX // base class requirement on associated type
937
1030
requirement ::= type assoc-type-list 'RC' GENERIC-PARAM-INDEX // base class requirement on associated type at depth
0 commit comments