Skip to content

Commit bcedcca

Browse files
committed
Docs: discuss @_preInverseGenerics
1 parent 545844c commit bcedcca

File tree

1 file changed

+40
-0
lines changed

1 file changed

+40
-0
lines changed

docs/ReferenceGuides/UnderscoredAttributes.md

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -917,6 +917,46 @@ More generally, multiple availabilities can be specified, like so:
917917
enum Toast { ... }
918918
```
919919

920+
## `@_preInverseGenerics`
921+
922+
By default when mangling a generic signature, the presence of a conformance
923+
requirement for an invertible protocol, like Copyable and Escapable, is not
924+
explicitly mangled. Only the _absence_ of those conformance requirements for
925+
each generic parameter appears in the mangled name.
926+
927+
This attribute changes the way generic signatures are mangled, by ignoring
928+
even the absences of those conformance requirements for invertible protocols.
929+
So, the following functions would have the same mangling because of the
930+
attribute:
931+
932+
```swift
933+
@_preInverseGenerics
934+
func foo<T: ~Copyable>(_ t: borrowing T) {}
935+
936+
// In 'bug.swift', the function above without the attribute would be:
937+
//
938+
// $s3bug3fooyyxRi_zlF ---> bug.foo<A where A: ~Swift.Copyable>(A) -> ()
939+
//
940+
// With the attribute, the above becomes:
941+
//
942+
// $s3bug3fooyyxlF ---> bug.foo<A>(A) -> ()
943+
//
944+
// which is exactly the same symbol for the function below.
945+
946+
func foo<T>(_ t: T) {}
947+
```
948+
949+
The purpose of this attribute is to aid in adopting noncopyable generics
950+
(SE-427) in existing libraries without breaking ABI; it is for advanced users
951+
only.
952+
953+
> **WARNING:** Before applying this attribute, you _must manually verify_ that
954+
> there never were any implementations of `foo` that contained a copy of `t`,
955+
> to ensure correctness. There is no way to prove this by simply inspecting the
956+
> Swift source code! You actually have to **check the assembly code** in all of
957+
> your existing libraries containing `foo`, because an older version of the
958+
> Swift compiler could have decided to insert a copy of `t` as an optimization!
959+
920960
## `@_private(sourceFile: "FileName.swift")`
921961

922962
Fully bypasses access control, allowing access to private declarations

0 commit comments

Comments
 (0)